从曲线拟合的角度看待神经网络,就是寻找一个曲线/曲面尽量逼近历史数据点。但是,若果由于过度追求逼近精度,有时会引起拟合曲线/曲面过度跌宕起伏,这样当输入有微小变化时,输出就有剧烈变化,这样的系统非常不稳定,预测能力也不好。
为了避免过拟合,增加网络的泛化能力,一般会预留一部分数据用于检验训练好的网络是否过拟合。
例如有100个样本,只用80个去训练网络,剩下的在训练完后,用来检验未训练数据的拟合(从中也可以看出是否过拟合)。
代码如下:
x1 = linspace(-3,3,100); %在[-3,3]之间线性生成100个数据 x2 = linspace(-2,1.5,100); %在[-2,1.5]之间线性生成100个数据 y = sin(x1)+0.2*x2.*x2; %生成y
inputData = [x1;x2]; %将x1,x2作为输入数据 outputData = y; %将y作为输出数据
randIndex = randperm(100); trainIndex = sort(randIndex(1:80)); %随机选出80个数据作为训练数据(这里先选出数据的序号) testIndex = sort(randIndex(81:100)); %将剩下的20个数据作为检验数据(这里先选出数据的序号)
inputData_train = inputData(:,trainIndex); %根据序号选出80个用于训练的输入 inputData_test = inputData(:,testIndex); %根据序号选出20个用于检验的输入 outputData_train = outputData(:,trainIndex); %根据序号选出80个用于训练的输出 outputData_test = outputData(:,testIndex); %根据序号选出20个用于检验的输出
%使用用输入输出数据(inputData_train、outputData_train)建立网络,隐节点个数设为3.其中输入层到隐层、隐层到输出层的节点分别为tansig和purelin,使用trainlm方法训练。 net = newff(inputData_train,outputData_train,3,{'tansig','purelin'},'trainlm');
%设置一些常用参数 net.trainparam.goal = 0.0001; %训练目标:均方误差低于0.0001 net.trainparam.show = 400; %每训练400次展示一次结果 net.trainparam.epochs = 15000; %最大训练次数:15000.
[net,tr] = train(net,inputData_train,outputData_train);%调用matlab神经网络工具箱自带的train函数训练网络
figure; %训练数据的拟合效果 simout_train = sim(net,inputData_train); subplot(2,1,1); title('训练数据的拟合效果') hold on t=1:length(simout_train); plot(t,outputData_train,t,simout_train,'r')%画图,对比原来的y和网络预测的y
%未训练数据的拟合效果 simout_test = sim(net,inputData_test); subplot(2,1,2); title('未训练数据的拟合效果') hold on t=1:length(simout_test); plot(t,outputData_test,t,simout_test,'r')%画图,对比原来的y和网络预测的y
w12 = net.iw{1,1}; %第1层(输入层)到第2层(隐层)的权值 b2 = net.b{1}; %第2层(隐层)的神经元阈值
w23 = net.lw{2,1}; %第2层(输入层)到第3层(输出层)的权值 b3 = net.b{2}; %第3层(输出层)的神经元阈值 |
运行后得到图《训练数据的拟合效果》和《未训练数据的拟合效果》
图中,红色为网络的拟合值,蓝色为原始值。
可以看到,经过训练的数据的拟合效果很好,未经过训练的数据的拟合效果也很好,说明网络泛化能力好,没出现过拟合的现象。
若果训练数据的拟合效果好,并且未训练过的数据的拟合效果也好,那说明网络是成功的。可以投入使用。否则,需要再作调整。
注:训练数据拟合好,未经过训练的数据的拟合效果不好,引起这种情况是有多种原因的,并不一定是过拟合引起。