如何在 Matlab 中增量训练神经网络?并迭代组合它们



我有非常大的火车设置,以便 Matlab。我需要做大规模的培训。

是否可以将训练集分成几部分并迭代训练网络,并在每次迭代时更新"网络"而不是覆盖它?

下面的代码显示了这个想法,它不起作用。在每次迭代中,它仅根据训练的数据集更新网络。

TF1 = 'tansig';TF2 = 'tansig'; TF3 = 'tansig';% layers of the transfer function , TF3 transfer function for the output layers
net = newff(trainSamples.P,trainSamples.T,[NodeNum1,NodeNum2,NodeOutput],{TF1 TF2 TF3},'traingdx');% Network created
net.trainfcn = 'traingdm' ; %'traingdm';
net.trainParam.epochs   = 1000;
net.trainParam.min_grad = 0;
net.trainParam.max_fail = 2000; %large value for infinity
while(1) // iteratively takes 10 data point at a time.
p %=> get updated with following 10 new data points
t %=> get updated with following 10 new data points
[net,tr]             = train(net, p, t,[], []);
end

我还没有机会看看adapt函数,但我怀疑它正在更新而不是覆盖。若要验证此语句,可能需要选择第一个数据区块的子集作为训练中的第二个区块。如果它正在覆盖,当您使用带有子集的训练网络来测试您的第一个数据块时,它应该无法预测那些不属于该子集的数据。

我用一个非常简单的程序对其进行了测试:y=x^2训练曲线。在第一次训练过程中,我[1,3,5,7,9]学习了数据集:

m=6;
P=[1 3 5 7 9];
T=P.^2;
[Pn,minP,maxP,Tn,minT,maxT] = premnmx(P,T);
clear net
net.IW{1,1}=zeros(m,1);
net.LW{2,1}=zeros(1,m);
net.b{1,1}=zeros(m,1);
net.b{2,1}=zeros(1,1);
net=newff(minmax(Pn),[m,1],{'logsig','purelin'},'trainlm');
net.trainParam.show =100;
net.trainParam.lr = 0.09;
net.trainParam.epochs =1000;
net.trainParam.goal = 1e-3; 
[net,tr]=train(net,Pn,Tn);
Tn_predicted= sim(net,Pn)
Tn

结果(请注意,输出使用相同的引用进行缩放。如果您正在执行标准归一化,请确保始终将第一个训练集中的平均值和 std 值应用于所有其他值):

Tn_predicted =
-1.0000   -0.8000   -0.4000    0.1995    1.0000

Tn =
-1.0000   -0.8000   -0.4000    0.2000    1.0000

现在我们正在实现第二个训练过程,训练数据[1,9]

Pt=[1 9];
Tt=Pt.^2;
n=length(Pt);
Ptn = tramnmx(Pt,minP,maxP);
Ttn = tramnmx(Tt,minT,maxT);

[net,tr]=train(net,Ptn,Ttn);
Tn_predicted= sim(net,Pn)
Tn

结果:

Tn_predicted =
-1.0000   -0.8000   -0.4000    0.1995    1.0000

Tn =
-1.0000   -0.8000   -0.4000    0.2000    1.0000

请注意,具有x=[3,5,7];的数据仍可精确预测。

但是,如果我们从一开始就只训练x=[1,9];

clear net
net.IW{1,1}=zeros(m,1);
net.LW{2,1}=zeros(1,m);
net.b{1,1}=zeros(m,1);
net.b{2,1}=zeros(1,1);
net=newff(minmax(Ptn),[m,1],{'logsig','purelin'},'trainlm');
net.trainParam.show =100;
net.trainParam.lr = 0.09;
net.trainParam.epochs =1000;
net.trainParam.goal = 1e-3; 
[net,tr]=train(net,Ptn,Ttn);
Tn_predicted= sim(net,Pn)
Tn

观看结果:

Tn_predicted =
-1.0071   -0.6413    0.5281    0.6467    0.9922

Tn =
-1.0000   -0.8000   -0.4000    0.2000    1.0000

请注意,经过训练的网络在x=[3,5,7];上表现不佳

上面的测试表明训练是基于以前的网络而不是重新启动的。性能较差的原因是每个数据块只实现一次(随机梯度下降而不是批量梯度下降),因此总误差曲线可能尚未收敛。假设您只有两个数据块,您可能需要在完成训练块 2 后重新训练块 1,然后重新训练块 2,然后是块 1,依此类推,直到满足某些条件。如果你有更多的块,你可能不需要担心第二个与第一个训练效果的比较。在线学习只是删除以前的数据集,无论更新的权重是否会影响它们的性能。

这里有一个如何在 matlab 中迭代训练 NN 的示例(迷你批处理):

只需创建一个玩具数据集

[ x,t] = building_dataset;

小批量大小和数量

M = 420 
imax = 10;

让我们检查直接训练与小批量训练

net = feedforwardnet(70,'trainscg');
dnet = feedforwardnet(70,'trainscg');

这里的标准训练:1次包含整个数据的单次调用

dnet.trainParam.epochs=100;
[ dnet tr y ] = train( dnet, x, t ,'useGPU','only','showResources','no');

误差度量:MEA,易于测量MSE或任何其他您想要的

dperf = mean(mean(abs(t-dnet(x))))

这是迭代部分:每次调用 1 个纪元

net.trainParam.epochs=1;
e=1;

直到我们到达上一个方法错误,用于纪元比较

while perf(end)>dperf

随机化每个时期的数据非常重要!

idx = randperm(size(x,2));

使用所有数据块迭代训练

for i=1:imax
k = idx(1+M*(i-1) : M*i);
[ net tr ] = train( net, x( : , k ), t( : , k ) );
end

计算每个时期的性能

perf(e) = mean(mean(abs(t-net(x))))
e=e+1;
end

检查性能,我们想要一个漂亮的准平滑和类似 exp(-x) 的曲线

plot(perf)

最新更新