繁体   English   中英

如何在Matlab中逐步训练神经网络? 并迭代地组合它们

[英]How to train neural network incrementally in Matlab? and iteratively combine them

我有非常大的火车设置,所以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

结果(请注意,输出使用相同的参考进行缩放。 如果您正在进行标准规范化,请确保始终将第1次训练集中的均值和标准值应用于所有其余值 ):

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=[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];上表现不佳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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM