实验二 基于BP神经网络算法的正余弦函数逼近
1. 实验目的
(1) 掌握MATLAB子函数编写与调用。
(2) 理解BP神经元网络算法的原理,并利用程序实现通过BP算法逼近任意非线性函数。
2. 实验
与实验要求
(1) 掌握BP神经网络算法的原理。
(2) 掌握MATLAB子函数的编写方法及调用方法。
(3) 根据BP神经网络算法的原理,编写MATLAB程序,逼近非线性函数。
3. 实验原理
q
一个2×3×1的神经网络即输入层有两个节点,隐层含三个节点,输出层有一个节点,神经网络如图示。
e
X1
X2
图1 神经网络结构图
图中
为输入层与隐层的权值,
为隐层与输出层的权值,
、
是神经网络的输入值,
是网络的输出值,
为教师信号,
为神经网络的实际输出与期望输出的误差。在这个神经网络中,节点1,2是输入层,
节点3,4,5是隐层,节点6是输出层;输入层和隐层之间的权值依次
,隐层和输出层间的权值为
,下角标为节点的编号;隐层和输出层节点的阈值依次为
,
,
,
。
①前馈计算
设隐层的第
个节点的输入和输出分别为:
其中
为激励函数
由于隐层的输出就是输出层的输入,则输出层第
个节点的总输入和输出分别为:
若网络输出与实际输出存在误差,则将误差信号反向传播,并不断地修正权值,直至误差达到要求为止。
②权值调整
设误差函数定义为:
为了简便,以下计算都是针对每个节点而言,误差函数
记作
。
● 输出层权值的调整
权值修正公式为:
定义反传误差信号
为:
式中
所以
又
由此可得输出层的任意神经元权值的修正公式:
或
(
● 隐层权值的调整
式中
由于误差函数
与隐层输入
不存在直接的函数关系,因此不能直接求得,所以
隐层的反传误差信号为
由此可得,隐层权值的修正公式为;
或
4. 实验设备
(1) 计算机
(2) MATLAB软件
5. 实验流程
(1) 初始化
(2) 循环1开始,计算三角函数y=sin(4*3.14*k1*s/360)的值
(3) 循环2开始,进行前馈的计算,x(k+1)=x(k)+q(k),out1(k+1)=(1-exp(-x(k+1))) / (1+exp(-x(k+1)));out2(k+1)=1/(1-exp(-x(k+1)));
n1(k+1)=
y1(k+1)=1/(1+exp(-n2(k+1))),y2(k+1)=(1-exp(-n2(k+1)))/(1+exp(-n2(k+1)))
(4) 计算偏差
e2(k+1)=(y(k+1)-y2(k+1))^2/2;
修正项xj1(k+1)=e2(k+1)-e2(k);
xj2(k+1)=e2(k+1)-2*e2(k)+e1(k);
反传信号的偏差为δ(k+1)=y1(k+1)*(1-y2(k+1))*(y(k+1)-y2(k+1))
(5) 调整隐层权值
Δ
Δq=q1-q0;q2(k+1)=q1(k)+0.8*Δ
+0.4*Δq;
Δ
Δ
q0(k+1)=q1(k);q1(k+1)=q2(k+1).
(6) 调整输出层权值
Δh=
;
w20(k+1)=w21(k);w21(k+1)=
Δp=p(k+1)-p(k);
p(k+1)=p(k)+0.9*
Δp
p1(k+1)=p1(k);p1(k+1)=p(k+1).
(7) 判断偏差e,若小于0.0000001,则循环2结束;否则,跳转执行步骤(2)直到循环1结束。
(8) 得出实验结果为三角函数y=sin(4*3.14*k1*s/360)与逼近曲线的图形。
6. 实验结果
7. 实验结果分析
利用BP神经网络算法基本能实现非线性函数的逼近,但只能对正余弦进行逼近。在函数y取得最大值时,误差比其他区域要大,说明在峰值时刻的点越难逼近。而且逼近的程度与权值的加权系数有很大关系。
8. 实验代码
%BP Algorithms Program
%Giving initial value;
%初始化
w10=[0 0;0 0;0 0];
w11=[0 0;0 0;0 0];
w20=[0;0;0];
w21=[0;0;0];
q0=[0 0 0];
q1=[0 0 0];
p0=0;p1=0;
xj=[0;0];
e0=0;e1=0;e2=0;
k1=5;k2=100;
for s=1:72
yp1=sin(4*3.14*k1*s/360);
for k=1:k2;
%前馈计算
%得到m1,o1两个数组(3 * 1 )
for i=1:3
x=w11(i,1)*xj(1,:)+w11(i,2)*xj(2,:); %xj(1,:)表示取行 q1(:,i)表示取列
z=x+q1(:,i); %相当于加一个初始化时的值
o=(1-exp(-z))./(1+exp(-z)); % 算的是Oi 激励函数1为f1(z)=(1-e^(-z))/(1+e^(-z))
m=1./(1+exp(-z)); % 算的是Oi1 激励函数2为f2(z)=1./(1+e^(-z))
m1(i,:)=m; %把m的值赋给m1数组相对应的行
o1(i,:)=o; %把o的值赋给o1数组相对应的行
end
yb=0;
for i=1:3
yb=yb+w21(i,:)*o1(i,:); % yb=Ik
end
yi=yb+p1; % yi为修正后的值
n=1./(1+exp(-yi)); % 在函数2下的输出函数值n->Ok
y=(1-exp(-yi))./(1+exp(-yi)); % 在函数1下的输出函数值y->y
%calculation error between aim and practice output;
e0=e1;
e1=e2;
e2=((yp1-y).^2)./2; % y的权值误差函数的计算,放入e2
xj1=e2-e1; % 对修正项的修正,放入xj1
xj2=e2-2*e1+e0;
xj=[xj1;xj2]; %总的修正数组xj( 2 * 1 )
d2=n*(1-y)*(yp1-y); %d2:输出的反传误差信号
%隐层的权值调整
%revising weighted value and threshold value in hidden layer;
for i=1:3
u=w21(i,:)*d2; % u->dartak*wjk
d1=(1-o1(i,:)).*u; %d1->(1-oj)*u
d0=m1(i,:)*d1; % d0->m1*d1; d0=Λwij
qw=q1(:,i)-q0(:,i);
q2=q1(:,i)+0.8*d0+0.4*qw; %设定的阈值与计算出的阈值之间的偏差
q3(:,i)=q2;
for j=1:2
dw=w11(i,j)-w10(i,j);