Как постепенно обучать нейронную сеть в 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 и т. Д. До тех пор, пока не будут выполнены некоторые условия. Если у вас гораздо больше кусков, вам не нужно беспокоиться о втором по сравнению с первым эффектом тренировки. Онлайновое обучение просто отбрасывает предыдущий набор данных, независимо от того, влияют ли обновленные веса на их производительность.