Generate200data,100pointsfortrainingandtheother100formodelvalidation.
1、样本确定
为了使选择的样本具有:
完备性、一致性和简洁性,所以自变量x1和x2从[15]均匀取200个点(x1=1:
4/199:
5;x2=1:
4/199:
5;),将x1、x2代入函数得到y,即得到原函数三维图形如图1.1所示。
其中,奇数位置作为训练样本偶数位置的数据作为测试样本。
图1.1原函数三维图形
2、神经网络结构构造
由于输入变量有两个分别是x1、x2,则输入层的节点数
为2,输出变量只有y即输出层节点数
为1。
隐含层节点数的多少直接决定了建立的BP神经网络的训练性能,如果节点数太少,网络可能无法训练,或者建立的网络容错性差,鲁棒性差,抗噪音能力差;反之,如果节点数太多,使网络复杂性和训练时间急剧增加,甚至可能使网络难以收敛或无法收敛。
建立的结构图如图2.1所示。
图2.1BP神经网络结构图
2.1隐含层节点数确定
由经验公式(2.1)可以初步确定隐含层节点数
范围是[312]且为整数。
(2.1)
式中,
为隐含层神经元个数,
为输入向量的维数,
为输出向量的维数,
为修正系数取值为1-10之间的整数。
2.2结构参数确定
终止条件:
训练最大迭代数5000(net.trainParam.epochs=5000;),目标误差
(net.trainParam.goal=1.0e-5;)。
学习率
不同BP神经网络参数和训练时间也会不同,学习率过大时可能导致系统的不稳定,学习速率较小导致较长的训练时间,可能导致收敛很慢。
通过选取不同
来做试验,根据得到训练结果来确定适合于本文的值。
隐藏层和输出层的传递函数分别为正切S型函数tansig()和线性函数purelin(),设置BP神经网络的训练函数为trainlm函数,trainlm即采用Levenberg-Marquardt学习算法,该算法的优点在于其训练过程收敛速度快,且网络的训练误差也比较小。
3、试验法确定隐含层节点数和学习率
取初始学习率
初始隐含层节点数4,来确定输入样本数据处理的必要性,如图3.1所示。
(a)进行归一化后的训练图(b)未进行归一化后的训练图
图3.1BP训练结果图
从图3.1可以看出进行归一化后的数据在430步时满足设定误差
,而未进行数据归一化处理时陷入局部极小值情况。
为了使建立的神经网络具有更好的性能须对输入样本先进行归一化处理,本文是将输入变量的值折算到[01]内。
归一化公式(2.2),反归一化公式(2.3)所示。
(2.2)
(2.3)
取学习率一定时
,来确定隐含层节点数如表3.1所示,其训练图如图3.2所示。
表3.1不同隐含层节点数下训练参数
隐含层节点数
训练时间(s)
迭代步数
最终误差
3
3.60673483665618
316
0.0018277
4
2.64159338228844
218
9.9693e-6
5
1.158********288
56
9.7816e-6
6
0.813596597786995
13
9.6824e-6
7
1.08232746707435
49
9.9351e-6
8
0.999822929537224
38
9.1637e-6
9
0.670040069673312
7
2.1694e-6
10
0.704761424042305
6
1.333e-6
11
0.748786770842471
8
3.3659e-6
12
0.720462520519793
7
1.9426e-7
13
0.727898566434005
4
1.1704e-6
(a)隐含层节点数为3的训练图(b)隐含层节点数为4的训练图
(c)隐含层节点数为5的训练图(d)隐含层节点数为6的训练图
(e)隐含层节点数为7的训练图(f)隐含层节点数为8的训练图
(g)隐含层节点数为9的训练图(h)隐含层节点数为10的训练图
(i)隐含层节点数为11的训练图(j)隐含层节点数为12的训练图
(k)隐含层节点数为13的训练图
图3.2训练结果图
通过综合考虑建立网络结构的复杂性和训练速度等因素,本文选择隐含层节点数为5个。
取隐含层节点数为5,来通过试验确定学习率如表3.2所示(初始值0.0001)。
表3.2不同学习率下训练参数
学习率
训练时间(s)
迭代步数
最终误差
0.0001
1.46098811293092
87
9.8425e-6
0.001
1.139********076
47
6.5235e-6
0.01
1.87807208556284
128
9.5296e-6
0.1
6.88265068357539
20
9.9342e-6
0.2
8.14062061502989
787
9.9404e-6
0.3
0.898170530444481
32
9.7323e-6
0.4
0.916901141589704
32
9.5595e-6
0.5
17.4710095838398
58
9.3009e-6
0.8
19.2591395446172
64
9.2436e-6
通过表3.2本文选择学习率
。
4、模型建立及其验证
根据上述参数可以建立输入层的节点数
为2,输出层节点数
为1,隐含层节点数
为5。
隐藏层和输出层的传递函数分别为正切S型函数tansig()和线性函数purelin(),BP神经网络的训练函数为trainlm函数,学习率
,训练最大迭代数5000,目标误差
,如下BP神经网络模型如图4.1所示。
net=newff(minmax(test3),[5,1],{'tansig','purelin'},'trainlm');
net.trainParam.epochs=5000;
net.trainParam.goal=1.0e-5;
net.trainParam.lr=0.3;
图4.1BP结构图
4.1拟合结果
通过对测试样本进行测试得到数据拟合结果如图4.2和4.3所示。
图4.2三维拟合图
图4.3三维拟合平面投影图
建立的BP神经网络参数和均方误差如下:
===========================================
均方误差
error=
1.85526833137586
===========================================
输入层权值和阈值
iw1=
-0.546028740196925-6.21024296440124
4.857063771833032.22644798149902
5.7657413061143-0.346903793080004
-0.999603508933502-6.19013871925716
-5.53874753897862-2.30936270485844
b1=
7.24997618704325
-4.17131885618426
-4.26576958646016
1.66847014287027
0.695978069970298
===========================================
输出层权值和阈值
iw2=
Columns1through3
-1.019267749859280.594426257012008-0.413148818236868
Columns4through5
0.177********2276-0.221876626904716
b2=
1.16948399996256
===========================================
通过图4.2和4.3可以得到本文选择的参数和建立BP神经网络结构的有效性,以及该模型的正确性。
4.2模型验证
使用randperm函数随机打乱1-100以获得一个数字序列(randperm(100,100)),并使用该序列将100个测试样本分成10组做交叉验证,即依次取该序列10个数据,将得到的数据作为选取测试样本(test2)相应的位置的值,验证结果如表4.2.1和图4.2.1所示。
表4.2.1验证结果
组数
均方误差
样本均值
方差
1
3.23909004537446
2.47070983722483
15.84925918298
2
7.70129817866876
-6.5104042920062
162.7566226780
3
12.1460665007187
7.45128160660714
175.3681347983
4
13.5717700743609
-11.6542077065476
171.3132759782
5
7.96583989731501
.021*********
144.6756831503
6
6.84817635318185
1.40633791581642
99.75469344734
7
2.72773068520192
-0.97663574745271
26.38392328494
8
10.266741007833
3.88689562424727
150.7979753225
9
1.70576752713886
1.70576752713886
9.046902584251
10
8.75091104881352
8.75091104881352
153.9822171932
图4.2.1均方误差曲线
综上所述,通过确定BP神经网络的结构以及参数试验选择,建立了适合本文的神经网络,并通过10次的模型交叉验证来验证模型准确性,从表中可以看出模型基本上准确的,但是泛化性能不是非常好。
5、附件
%输入样本
clc
clearall
formatlongg
%y
(1)=0;
x1=1:
4/199:
5;
x2=1:
4/199:
5;
x3=[x1;x2];
fori=1:
length(x1)
forj=1:
length(x2)
y1(i,j)=(2+x1(i)^1.5-1.5*sin(3*x2(j)))^2;
end
end;
%[X10,X20]=meshgrid(x10,x20);
mesh(x1,x2,y1)
holdon
fori=1:
length(x1)
y(i)=(2+x1(i)^1.5-1.5*sin(3*x2(i)))^2;
end;
test1=[];
test2=[];
y1=[];
y2=[];
%确定训练样本和交叉验证样本
fori=1:
2:
length(x1)
test1=[test1,x3(:
i)];
y1=[y1,y(:
i)];
end
fori=2:
2:
length(x1)
test2=[test2,x3(:
i)];
y2=[y2,y(:
i)];
end
%去随机数
number=randperm(100,100);
%数据处理归一化
test3(1,:
)=(test1(1,:
)-min(test1(1,:
)))./(max(test1(1,:
))-min(test1(1,:
)));
test3(2,:
)=(test1(2,:
)-min(test1(2,:
)))./(max(test1(2,:
))-min(test1(2,:
)));
y3=(y1-min(y1))./(max(y1)-min(y1));
net=newff(minmax(test3),[5,1],{'tansig','purelin'},'trainlm');%正切S型传递函数
%设置训练参数
net.trainParam.show=10;
net.trainParam.epochs=5000;
net.trainParam.goal=1.0e-5;
net.trainParam.lr=0.3;
%网络训练
[net,tr]=train(net,test3,y3);
%仿真测试
test5(1,:
)=(test2(1,:
)-min(test2(1,:
)))./(max(test2(1,:
))-min(test2(1,:
)));
test5(2,:
)=(test2(2,:
)-min(test2(2,:
)))./(max(test2(2,:
))-min(test2(2,:
)));
s_bp1=sim(net,test5);%BP神经网络的仿真结果
%反归一化
s_bp1=(max(y1)-min(y1))*s_bp1+min(y-1);
%plot3(test1(1,:
),test1(2,:
),y1,'+');
%holdon
plot3(test2(1,:
),test2(2,:
),s_bp1,'g*');
holdon
plot3(x3(1,:
),x3(2,:
),y,'r');
xlabel('x1');
ylabel('x2');
zlabel('y');
title('神经网络拟合y=(2+x1^1.5-1.5*sin(3*x2))^2')
legend('y=(2+x1^1.5-1.5*sin(3*x2))^2','实际输出值','期望输出值')
gridon;
%画投影
figure
subplot(131);
plot3(test2(1,:
),test2(2,:
),s_bp1,'g*');
holdon
plot3(x3(1,:
),x3(2,:
),y,'r');
xlabel('x1');
ylabel('x2');
zlabel('y');
view(0,180);
gridon;
title('x1-y平面');
subplot(132);
plot3(test2(1,:
),test2(2,:
),s_bp1,'g*');
holdon
plot3(x3(1,:
),x3(2,:
),y,'r');
xlabel('x1');
ylabel('x2');
zlabel('y');
view(180,270);
gridon;
title('x1-x2平面');
subplot(133);
plot3(test2(1,:
),test2(2,:
),s_bp1,'g*');
holdon
plot3(x3(1,:
),x3(2,:
),y,'r');
xlabel('x1');
ylabel('x2');
zlabel('y');
gridon;
title('x2-y平面');
view(270,360);
%legend('期望输出值','实际输出值','y=(2+x1^1.5-1.5*sin(3*x2))^2')
%view(90,180);
error=0;
fori=1:
length(y2)
error=error+sqrt((s_bp1(i)-y2(i))^2);
end;
disp('===========================================')
disp('均方误差')
error=error/length(y2)
savenet;
loadnet;
disp('===========================================')
disp('输入层权值和阈值')
iw1=net.iw{1,1}
b1=net.b{1}
disp('===========================================')
disp('输出层权值和阈值')
iw2=net.Lw{2,1}
b2=net.b{2}
disp('===========================================')
disp('模型交叉验证')
Error=[0000000000];%均方误差
ave=[0000000000];%均值
D=[0000000000];%方差
forj=1:
1:
10
test4=[];
y4=[];
fori=1:
1:
10
test4=[test4,test2(:
number((j-1)*10+i))];
y4=[y4,y2(number((j-1)*10+i))];
end;
%归一化
test4(1,:
)=(test4(1,:
)-min(test4(1,:
)))./(max(test4(1,:
))-min(test4(1,:
)));
test4(2,:
)=(test4(2,:
)-min(test4(2,:
)))./(max(test4(2,:
))-min(test4(2,:
)));
Y=sim(net,test4);
%反一化
Y=(max(y1)-min(y1))*Y+min(y1);
fork=1:
length(test4)
Error(j)=Error(j)+sqrt((Y(k)-y4(k))^2);
end
ave(j)=mean(y4-Y);
D(j)=var(y4-Y,1);
end;
Error=Error/length(test4)
i=1:
10;
figure;
plot(i,Error,'p');
holdon
plot(i,Error,'r-','LineWidth',2);
gridon
xlabel('number');
ylabel('error');
title('交叉验证的均方误差');