Как постепенно обучать нейронную сеть в 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

2 ответа

Решение

Вот пример того, как обучить NN итеративно (мини-пакет) в Matlab:

просто создайте набор игрушечных данных

[ 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)

У меня нет возможности взглянуть на 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=[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];

Тест выше показывает, что обучение основано на предыдущей сети, а не на перезапуске. Причина, по которой производительность ухудшается, заключается в том, что вы реализуете только один раз для каждого блока данных (случайный градиентный спуск, а не пакетный градиентный спуск), поэтому кривая общей ошибки может еще не сходиться. Предположим, что у вас есть только два блока данных, вам может потребоваться повторно обучить блок 1 после выполненного обучения блока 2, затем повторно обучить блок 2, затем блок 1 и т. Д. До тех пор, пока не будут выполнены некоторые условия. Если у вас гораздо больше кусков, вам не нужно беспокоиться о втором по сравнению с первым эффектом тренировки. Онлайновое обучение просто отбрасывает предыдущий набор данных, независимо от того, влияют ли обновленные веса на их производительность.

Другие вопросы по тегам