%用经典的BP网络逼近多输入多输出非线性函数y=exp(x1)+x2
%三层神经网络(1输入层,1隐含层,1输出层)
%输入层有两个输入节点x1和x2
%隐含层的节点个数为s个,具体选择根据近似精度确定
%输出层有一个节点
clear;
%=====================================网络参数初始化====================================
s=8; %隐层神经元的个数
maxEpoch=100000; %最大训练次数
errGoal=0.01; %期望误差最小值
alpha=0.2; %学习效率
V=0.01*rand(3,s) %输入层到隐含层的权值矩阵(包括阈值)
W=0.01*rand(s+1,1) %隐含层到输出层的权值矩阵(包括阈值)
x1=-2:0.1:2;
x2=-2:0.1:2;
d=exp(x1)+x2; %计算期望输出向量d
[m,n]=size(x1); %其中n表示神经网络的训练样本数量
%===================================网络训练===================================
for count=1:maxEpoch %count为训练次数计数器
sse=0;
for p=1:n %p为训练样本计数器
X=[-1;x1(:,p);x2(:,p)]; %输入向量(第一个变量对应隐含层阈值)
Y=logsig(V'*X); %隐含层的输出
Y=[-1;Y]; %隐含层的第一个变量对应输出层的阈值,取值恒为-1
O=W'*Y; %输出层的输出
out(p)=O; %用来记录网络的输出
%计算网络输出误差e及总的误差平方和sse
e=d(p)-O;
sse=sse+(e^2)/2;
%反向传播,计算各层误差信号
delta_o=e; %输出层的误差信号
w=W(2:s+1,:);
w=diag(w);
y=Y(2:s+1,:);
y=diag(y);
In=diag(ones(s,1));
delta_y=diag( delta_o*w*y*(In-y) ); %得到隐含层的误差信号
%调整各层权值矩阵及阈值
W=W+alpha*delta_o*Y; %调整输出层的权值
V=V+alpha*X*(delta_y)';
end
Epoch(count)=count; %记录网络的训练步长
Error(count)=sse; %记录网络的训练的误差平方和
if (sse<errGoal)
break;
end
end
%================================BP网络训练后的有关图表输出============================
subplot(2,2,1);
plot(x1,d,'b-',x1,out,'r.');title('训练完后的实际输出与期望输出');grid on;
subplot(2,2,2);
plot(Epoch,Error);title('训练误差输出');xlabel('训练步长Epoch');ylabel('误差平方和SSE');grid on;
%========================================网络测试=======================================
x1=4*rand(1,10)-2; %取[-2,2]之间的10个随机数作为测试样本
x2=x1;
%x2=4*rand(1,10)-2;
d=exp(x1)+x2; %测试样本的标准输出
[m,n]=size(x1);
for i=1:1:n
X=[-1;x1(i);x2(i)];
Y=logsig(V'*X);
Y=[-1;Y];
O=W'*Y;
out_test(i)=O; %记录测试样本的网络输出
E(i)=d(i)-O; %记录网络的测试误差
end
%=================================BP网络测试结果的有关图形输出==============================
subplot(2,2,3);
plot(x1,d,'bo',x1,out_test,'r.');legend('期望输出','实际输出');title('测试时的实际输出与期望输出');grid on;
subplot(2,2,4);
plot(x1,E,'ro');title('测试误差输出');xlabel('测试样本'),ylabel('误差E');grid on;