【问题标题】:How to train neural network incrementally in Matlab? and iteratively combine them如何在 Matlab 中逐步训练神经网络?并迭代地组合它们
【发布时间】:2014-02-06 01:08:36
【问题描述】:

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

【问题讨论】:

  • 你怎么知道它是覆盖而不是更新?您能否展示一些数据示例,因为我不太明白“在每次迭代中,它会根据唯一经过训练的数据集更新网络”是什么意思?谢谢
  • 我在时间序列中使用神经网络来预测多个点(90)。如果我使用 train(),在每次迭代中它都会覆盖到已经训练过的部分。我通过比较我的预测值和实际值来观察它。随着时间的推移,没有任何改善,我的预测仅基于经过训练的一小部分数据。我认为迭代训练它比训练 1,000,000 个数据点更有效。目前我正在尝试 adapt() 函数,但我的预测没有任何改进。那是我的问题//adapter() 是否可能。谢谢。
  • 预测仅基于训练数据。在我的每次迭代训练中,我都无法看到之前训练过的数据的模式或行为。

标签: matlab machine-learning neural-network large-scale training-data


【解决方案1】:

我还没有机会查看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

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

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,依此类推,直到满足某些条件。如果你有更多的块,你可能不需要担心第二个和第一个训练效果相比。在线学习只是丢弃了之前的数据集,无论更新的权重是否会影响它们的性能。

【讨论】:

  • 感谢您的回复。就我而言,我有一个非常大的数据集,我的目标是预测 90 个点。在那种情况下,我有输入值和输出点。例如,当我训练前 1000 个数据时,直到它达到具有 > 95% 准确度的最小误差。在它被训练之后,当我对数据的第二个 1000 部分做了同样的事情时;它会覆盖权重,并且预测器主要表现为数据的最新训练部分。我无法想出解决这个问题的办法。在迭代训练中,我应该保持学习率小,#ofepochs 小。谢谢。
  • 对于数据的每个迭代训练部分,我总是尝试保留它,直到训练数据达到 >90% 的准确度。
  • 我没有进行第一次培训,而是进行了 adapt()。我尝试了您的建议,但不幸的是,我看不到任何改进。作为第一次训练的证明,训练数据完全适合,但是当我训练下一个 1000 部分数据时,以前适合的数据突然不再适合预测的行为仍然集中在迭代中数据的最后训练部分,它完全忽略数据中已经训练过的部分。 adapt() 函数的最佳 alpha(学习率)应该是多少/在 trainSamples.P 下,trainSamples.T 应该只是训练样本块?
【解决方案2】:

这里有一个如何在 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 个 epoch

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)

【讨论】:

  • 欢迎来到 Stack Overflow,感谢您的提交!为了帮助我们为最多的程序员提供良好的资源,您能否更新您的答案,解释为什么这是一个很好的问题解决方案?
猜你喜欢
  • 2013-07-11
  • 2010-11-20
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 2012-12-04
  • 2017-08-18
相关资源
最近更新 更多