Matlab学习笔记之BP神经网络求逼近函数及示例------------锋锋的快乐小窝

  • BP:误差反向传播算法(Error Back Propagtion)
  • BP 神经网络一般是多层的,与之相关的另一个概念是多层感知器 (Multi-LayerPerceptron,MLP)
  • 多层感知器除了输入层和输出层以外,还具有若干个隐含层
  • 多层感知器强调神经网络在结构上由多层组成,BP 神经网络则强调网络采用误差反向传播的学习算法
  • 大部分情况下多层感知器采用误差反向传播的算法进行权值调整,因此两者一般指的是同一种网络
  • 如图 1 所示,BP神经网络的隐含层可以为一层或多层,一个包含两层隐含层的BP神经网络的拓扑结构

图1 BP神经网络的结构

  • BP神经网络有以下特点:
  • (1) 网络由多层构成,层与层之间全连接,同一层之间的神经元无连接。多层的网络设计,使 BP 网络能够从输入中挖掘更多的信息,完成更复杂的任务。
  • (2) BP 网络的传递函数必须可微。
    感知器的传递函数 —— 一二值函数在这里没有用武之地
  • BP 网络一般使用Sigmoid 函数或线性函数作为传递函数。根据输出值是否包含负值,Sigmoid 函数又可分为 Log-Sigmoid 函数和 Tan-Sigmoid 函数
  • 一个简单的Log-Sigmoid函数可由下式确定:bp神经网络matlab语音识别 matlab自带bp神经网络_神经网络
  • 其中 bp神经网络matlab语音识别 matlab自带bp神经网络_matlab_02
  • Log-Sigmoid函数和Tan-Sigmoid函数的曲线区别如图 2所示
  • Sigmoid 函数是光滑的、可微的,在分类时比线性函数跟准确,容错也较强
  • 它将输入从负无穷到正无穷的范围映射到(-1,1)或(0,1)区间内,具有非线性的放大功能
  • 以正半轴为例,在靠近原点处,转输入信号较小,此时曲线上凸,输出值大于输入值;随着信号增大,非线性放大的系数逐深斩减小
  • Sigmoid函数可微的特性使它可以利用梯度下降法
  • 在输出层,如果采用 Sigmoid 函数,将会把输出值限制在一个较小的范围,因此,BP神经网络的典型设计是隐含层采用 Sigmoid函数作为传递函数,而输出层则采用线性函数作为传递函数
  • 采用误差反向传播算法(Back-Propag ation Algorithm)进行学习在 BP 网络中,数据从输入层经隐含层逐层向后传播,训练网线各权值时,则沿着减少误差的方向,从输出层经过中间各层逐层向前修正网络的连接权值
  • 随着学习的不断进行,最终的误差越来越小
clear
clc

p=[-0.96 0.577 -0.0729 0.377 0.641 0.66 0.461 0.1336 -0.201 -0.434 -0.5 -0.393 -0.1647 0.0988 0.3072 0.396 0.3449 0.1816 -0.0312 -0.2183 -0.3201]; %神经网络输入值
t=-1:0.1:1 ; %神经网络目标值

rng('default')
rng(0)
nTrainNum = 21; %21个训练样本
%nSampDim = 2; %数据维度
M = 1000; %迭代次数
ita = 0.01;%学习率
alpha = 0.3;

%%构建网络
NH = 21; % 隐含层层数
net.w1 = rand(2,NH);
net.w2 = rand(NH+1,1);


%%归一化数据
a = min(p);
b = max(p);
p_S = (p-a)/(b-a);


%%训练
net2_plot=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
for y=1:1:21
    for x=1:M % 迭代
        %ind = randi(21);% 从1-21中随机取一个数
        in = [p_S(:,y),1];% 输入层输出
        net1_in = in*net.w1;% 隐含层输入
        net1_out = tansig(net1_in);% 隐含层输出
        net2_int = [net1_out,1];% 隐含层输入
        net2_in = net2_int*net.w2;% 隐含层输入
        net2_out = tansig(net2_in);% 隐含层输出
        
        net2_plot(1,y)=net2_out;
        err = t(y)-net2_out;
        errt(x)=1/2*sqrt(sum(err.^2));
        
        
        if errt(x)<=ita
            fprintf('第%d次循环,第%d个数据,误差%f\n',x,y,errt(x));
            break;
        end
        
        % 调整权值
        for i=1:length(net1_out)+1
            for j=1:1
                % 局部梯度
                ipu1(j)=err(j);
                % 输出层与隐含层之间的调整量
                delta1(i,j) = ita.*ipu1(j).*net2_int(i);
            end
        end
        
        for m=1:2
            for i=1:length(net1_out)
                % 局部梯度
                ipu2(i)=net1_out(i).*(1-net1_out(i)).*sum(ipu1.*net.w2);
                % 输出层与隐含层之间的调整量
                delta2(m,i) = ita.*in(m).*ipu2(i);
            end
        end
        
        if x==1
            net.w1 = net.w1 + delta2;
            net.w2 = net.w2 + delta1;
        else
            net.w1 = net.w1 + delta2*(1-alpha) + alpha *delta2;
            net.w2 = net.w2 + delta1*(1-alpha) + alpha *delta1;
        end
        
    end
    plot(p,t,'*')
    title('使用BP神经网络函数逼近');
    xlabel('输入值');
    ylabel('目标值/输出值');
    hold on;
end
plot(p,net2_plot,'-')