Matlab实现BP神经网络

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SmartDazhi/article/details/78073937

最近在看数学建模相关资料时,有看到神经网络在分类问题中的应用,虽然在比赛中直接调用函数或工具箱就可以了,但是动手实践能更透彻的理解其原理。

1.相关资料整理

1.从多层感知器到卷积网络(一):http://blog.csdn.net/aws3217150/article/details/46316007
 这位博主大哥写的东西深入浅出,实为初学者的宝藏。
2. 数学建模算法与程序大全 司守奎:第十九章神经网络模型
3. 神经网络回顾-Relu激活函数:http://www.cnblogs.com/qw12/p/6294430.html
4. 深度学习与计算机视觉系列(5)_反向传播与它的直观理解:
http://m.blog.csdn.net/longxinchen_ml/article/details/50323183
博主的图不错,直观理解 

2.本文实现内容

本文的背景问题如下(数学建模算法与程序大全,第十九章)

蠓虫分类问题

蠓虫分类问题可概括叙述如下:生物学家试图对两种蠓虫(Af与Apf)进行鉴别,依据的资料时触角和翅膀的长度,已经测得了9支Af和6支Apf的数据如下:
Af:(1.24,1.27),(1.36,1.74),(1.38,1.64),(1.38,1.64),(1.38,1.82)
 (1.38,1.90),(1.40,1.70)(1.48,1.82),(1.56,2.08).
Apf:(1.14,1.82),(1.18,1.96),(1.20,1.86),(1.26,2.00),(1.28,2.00),(1.30,1.96).
现在的问题是:
   (i) 根据如上资料,如何制定一种方法,正确地区分两类蠓虫
   (ii)对触角和翼长分别为(1.24,1.80),(1.28,1.84)与(1.40,2.04)的3个标本,用所得到的方法加以识别。

2.1BP神经模型实现

本文构建的神经网络结构为:2×6×1

        这里写图片描述

2.1.1Back-Propagation推导

神经网络的反向传播有一点复杂,故在这里推导一下
因为训练数据数较小(15对)故mini-batch=1,记输出层为 di ,实际值为 yi ,其中 i=1,2,...,15 ,输入层到隐层的输入记为 x1i,x1i=w(i,1)x1+w(i,2)x2,i=1,2...6 。令 ai=sigmoid(x1i) ,隐层到输出层的输入记为 x2,x2=wka
   代价函数:
        
         cost=12(diyi)2
        
   step1:
   
    costwk=costdidix2x2wk =12(diyi)2didix2x2wk =(diyi)yi(1yi)a

   step2:
    costw=costaax1x1w =costdidaax1x1w =(diyi)yi(1yi)wk.a.(1a).x

注: . 为矩阵中点乘

2.2matlab实现

上代码

tic
X=load('data.txt');
x1=X(1,:);
x2=X(2,:);
d=X(3,:);
n=length(x1);%样本个数  
p=6; %隐层个数  
w=rand(p,2);  
wk=rand(1,p+1);  
max_epoch=500000;%最大训练次数  
error_goal=0.00002;%均方误差  
q=0.2;%学习速率  
a(p+1)=-1;

%training  
%此训练网络采取2-6-1的形式,即两个输入,6个隐层,1个输出  
for epoch=1:max_epoch  
    e=0;  
    for i=1:n %样本个数  
        x=[x1(i);x2(i)];   
        neto=0;  
        for j=1:p   
            neti(j)=w(j,1)*x(1)+w(j,2)*x(2);  
            a(j)=1/(1+exp(-neti(j)));  
%隐层的激活函数采取s函数,f(x)=1/(1+exp(-x))  
            neto=neto+wk(j)*a(j);  
        end            
        neto=neto+wk(p+1)*(-1);
        y(i)=1/(1+exp(-neto));  %输出层的激活函数采取sigmoid函数  
        de=(1/2)*(d(i)-y(i))*(d(i)-y(i));  
        e=de+e;       
        dwk=q*(d(i)-y(i))*y(i)*(1-y(i))*a;   
        for k=1:p  
            dw(k,1:2)=q*(d(i)-y(i))*y(i)*(1-y(i))*wk(k)*a(k)*(1-a(k))*x;         
        end     
        wk=wk+dwk; %从隐层到输出层权值的更新  
        w=w+dw; %从输入层到隐层的权值的更新      
    end   
    error(epoch)=e;  
    m(epoch)=epoch;      
    if(e<error_goal)              
       break;  
    elseif(epoch==max_epoch)  
        disp('在目前的迭代次数内不能逼近所给函数,请加大迭代次数')          
    end   
end

%test data  
x1_te=[1.24,1.28,1.4];
x2_te=[1.8,1.84,2.04];

for i=1:3 %样本个数  
    x=[x1_te(i);x2_te(i);-1];    
    neto=0;  
    for j=1:p  
        neti(j)=w(j,1)*x(1)+w(j,2)*x(2);  
        a(j)=1/(1+exp(-neti(j)));  
        neto=neto+wk(j)*a(j);  
    end    
    neto=neto+wk(p+1)*(-1);  
    y1(i)=1/(1+exp(-neto));  %输出层的激活函数采取sigmoid函数
end   
y1(1:3)
toc

上训练集结果
训练集结果还可行

     这里写图片描述

(⊙o⊙)…测试集有点打脸

      这里写图片描述

结果分析:由于训练集太少,以及网络结构不算太好,导致训练出神经网络过拟合,不能很好的用于测试集上。

数据和程序放在GitHub上 https://github.com/Wangxingzhi/BPNetworkdemo

猜你喜欢

转载自blog.csdn.net/SmartDazhi/article/details/78073937