前言:神经网络常常给人一种十分高深的感觉,让人觉得这是数学家或是IT工程师们才能学习的理论,普通人是难以掌握的。但当我们解决实际问题时并不需要完全掌握理论的原理,只需要“会用”即可。再加上MATLAB中强大的集成命令函数,让我们直接跳过“刀耕火种”的时代,直接使用BP神经网络算法进行预测。
一、神经网络的数学描述
1、搭建基本模块——神经元
神经元是构成神经网络的的基本单位,它先获得输入,然后通过某些数学运算后产生一个输出。
在这个神经元中,总共进行了四步数学运算:
(1)加权
x1 →x1×w1 x1 →x1×w1
(2)求和
(x1×w1) +(x1×w1)
(3)偏置(阈值)
(x1×w1) +(x1×w1)- b
(4)激活函数(将无限制的输入转化为可预测形式的输入)
f((x1×w1)+(x1×w1)-b)
一种常用的激活函数是sigmoid函数,作用是使输出介于0到1之间.
若以X表示输入向量,Y表示输出向量,W表示权重向量,B表示偏置向量,即:
(1)
(2)
神经元的输出就可以表示为:
(3)
如果我们在X向量第一个前面加上一个X0 = b, 在W向量的第一个前面加上W0 = -1,上式就可以改为:
(4)
好了,我们已经得到了单个的神经元,当我们把多个神经元组合在一起时我们就可以得到一个完整的神经网络
2、搭建神经网络
以上图搭建的神经网络为例,神经网络包含了输入层、隐含层、输出层三部分。
我们设网络的输入向量为X,输入向量为Y,三个隐含层前权重矩阵分别为W1,W2,W3,三个隐含层的输出向量为O1,O2,O3
以第一个隐含层为例:输入的元素个为n个,输出的元素个数为i个,权重矩阵为大小为i*n,即:
(5)
(6)
(7)
第一个隐含层就可以表示为:
(8)
注:这里的F1为一个激活函数矩阵:
(9)
以此类推我们就可以得到神经网络完整的数学表达式:
(10)
如上(3)(4)式,我们每个X向量第一个前面加上一个X0 = -1, 在W向量的第一个前面加上W0 = b,上式就可以改为:
(11)
二、BP神经网络
在正式介绍BP神经网络之前,我们先来回顾一下我们学习过程。
以识别一个人的性别为例:
我们以身高、体重、头发三个变量作为识别的一个判断依据:
假如第一组样本中:男女身高、体重都差不多,但女性的头发明显长于男性,由此作为我们判断下一组的经验:头发长的是女性(即权重为:0 0 1),但在第二组样本中,男性的头发比女性的要长,这样我们根据第一组得到的经验就会导致错误。但我们发现第二组的男性身高高于女性,由此我们就有开始改变我们刚才到的经验:头发长的、身高矮的是女性,(即权重变为:0.2 0 0.8)·······
当我们学习足够多的样本时,就可以得到一个较为合理的权重矩阵,由此作为我们判断的标准。
BP神经网络的原理与上面的学习过程有一些类似。BP是误差反向后传(Back Propagation)的英文缩写,它的原理是利用输出后的误差来估计输出层的直接前导层,在利用这个误差估计更前一层的误差,如此一层层地反传下去,就可以获得所有其他各层的误差估计。
具体流程图
我们设每个输入层与输出层之间的误差为:ε
下面的步骤就是想办法调整权值,使 ε 值达到最小。由于负梯度方向是函数值减小最快的方向,因此可以设定一个步长η,每次沿负方向调整η个单位,即每次权值调整为:
(12)
注:η在神经网络中称为学习率
三、BP神经网络的MATLAB实现函数
1、数据的预处理
由于神经网络有些输入数据的范围可能特别大,导致神经网络收敛缓慢,训练时间长,所以一般需要对数据进行预处理。
2、神经网络实现函数
newff : 前馈网络创建函数
train :训练网络函数
sim :使用网络进行仿真
(1)newff函数语法:
net = newff(I,O,[C],{D},'trainFun','BLF','PF')
I: 输入层,O: 输出层,[C]:维数表示隐含层数,其元素为每一个隐含层的节点数。如[2,5,4]表示有3个隐含层,第一个隐含层有2个节点,第二个隐含层有5个节点,第四个隐含层有4个节点,{D}:每一分量对应层的激活函数,默认为’tangsig'
常用的激活函数:
线性:f(x) = x 'purelin'
对数S形:
‘logsig'
trainFun: 为学习规则采用的训练算法
常见的训练函数:
trainIm——Levenberg-Marquardt的BP算法训练函数
trainfg——BFGS拟牛顿BP算法函数
traingda——梯度下降自适应Ir的BP算法训练函数
BLF:BP权值学习函数,默认为‘learngdam'
PF:性能函数,默认为’mse'
(2)train函数
语法:[net,tr,YI,E] = train(net,X,Y)
X:网络实际输入,Y:网络应有输出,tr:训练跟踪信息,YI:网络实际输出
E:误差矩阵
(3)sim函数
Y = sim(net,X)
net:网络,X:输入给网络的K*N矩阵,其中K为网络输入个数,N为数据样本数,Y:输出矩阵Q*N,其中Q为网络输出个数.
(4)配置参数
net.trainparam.gaol——神经网络训练的目标误差
net.trainparam.show——显示中间结果的周期
net.trainparam.epochs——最大迭代次数
net.trainparam.Ir——学习率
四、BP神经网络训练实例
蠓虫分类问题:
生物学家试图对两种蠓虫(Af 与 Apf)进行鉴别, 依据的资料是触角和翅膀的长度,已经测得了 9 支 Af 和 6 支 Apf 的数据如下:Af: (1.24,1.27),(1.36,1.74),(1.38,1.64),(1.38,1.82),(1.38,1.90),(1.40,1.70), (1.48,1.82),(1.54,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).
现在的问题是:
制定一种方法,正确地区分两类蠓虫。 并对触角和翼长分别为(1.24,1.80),(1.28,1.84)与(1.40,2.04)的 3 个标本,用所得到的方法加以识别。
解决思路:
(1)用数字‘1’表示Af, 数字‘0’表示Apf,建立3层BP神经网络(含有两个隐含层),输入层节点数为2,输出层节点数为1。隐含层节点数分别为:3,2,激活层函数均为:logsig
(2)采用默认训练函数‘trainlm'训练神经网络,目标差gaoal为:10^(-10),学习率lr为:0.05,最大迭代次数epochs为:100,显示中间结果的周期show为:10
BP神经网络预测源代码
clc,clear
p1=[1.24,1.27;1.36,1.74;1.38,1.64;1.38,1.82;1.38,1.90;
1.40,1.70;1.48,1.82;1.54,1.82;1.56,2.08];
p2=[1.14,1.82;1.18,1.96;1.20,1.86;1.26,2.00
1.28,2.00;1.30,1.96];
p=[p1;p2]';
goal=[ones(1,9),zeros(1,6)];
net2=newff(p,goal,[3,2],{'logsig','logsig'});
net2.trainParam.show = 10;
net2.trainParam.lr = 0.05;
net2.trainParam.goal = 1e-10;
net2.trainParam.epochs =100 ;
%在新的newff语法体系中,需要清除net2.divideFcn等属性再训练,否则结果误差较大
net2.divideFcn ='';
net2 = train(net2,p,goal);
x=[1.24 1.80;1.28 1.84;1.40 2.04]';
y0=sim(net2,p) %输入样本的预测
y=sim(net2,x)%对三组数据的预测
结果显示:我们可以看到当迭代次数为18次时,目标差(Performance)就达到了期望值,训练的效果较好。
参考资料:
[1] 司守奎《数学建模算法与程序》
[2] 姜启源,谢金星,叶俊《数学建模》
[3] 包子阳,余继周《智能优化算法及其MATLAB实例》
图片来源:由 Colin Behrens 在Pixabay上发布