2015-04-08 3 views
5

я получил очень различную эффективность обучения с помощью следующей сетиМоделирование шаблона по умолчанию с помощью feedforwardnet в Matlab?

net = patternnet(hiddenLayerSize); 

и следующего

net = feedforwardnet(hiddenLayerSize, 'trainscg'); 
net.layers{1}.transferFcn = 'tansig'; 
net.layers{2}.transferFcn = 'softmax'; 
net.performFcn = 'crossentropy'; 

на один и те же данные.

Я думал, что сети должны быть одинаковыми.

Что я забыл?

UPDATE

Приведенный ниже код показывает, что поведение сети однозначно зависит от функции создания сети.

Каждый тип сети запускался два раза. Это исключает случайные проблемы с генератором или что-то еще. Данные одинаковы.

hiddenLayerSize = 10; 

% pass 1, with patternnet 
net = patternnet(hiddenLayerSize); 

net.divideParam.trainRatio = 70/100; 
net.divideParam.valRatio = 15/100; 
net.divideParam.testRatio = 15/100; 

[net,tr] = train(net,x,t); 

y = net(x); 
performance = perform(net,t,y); 

fprintf('pass 1, patternnet, performance: %f\n', performance); 
fprintf('num_epochs: %d, stop: %s\n', tr.num_epochs, tr.stop); 

% pass 2, with feedforwardnet 
net = feedforwardnet(hiddenLayerSize, 'trainscg'); 
net.layers{1}.transferFcn = 'tansig'; 
net.layers{2}.transferFcn = 'softmax'; 
net.performFcn = 'crossentropy'; 

net.divideParam.trainRatio = 70/100; 
net.divideParam.valRatio = 15/100; 
net.divideParam.testRatio = 15/100; 

[net,tr] = train(net,x,t); 

y = net(x); 
performance = perform(net,t,y); 

fprintf('pass 2, feedforwardnet, performance: %f\n', performance); 
fprintf('num_epochs: %d, stop: %s\n', tr.num_epochs, tr.stop); 

% pass 1, with patternnet 
net = patternnet(hiddenLayerSize); 

net.divideParam.trainRatio = 70/100; 
net.divideParam.valRatio = 15/100; 
net.divideParam.testRatio = 15/100; 

[net,tr] = train(net,x,t); 

y = net(x); 
performance = perform(net,t,y); 

fprintf('pass 3, patternnet, performance: %f\n', performance); 
fprintf('num_epochs: %d, stop: %s\n', tr.num_epochs, tr.stop); 

% pass 2, with feedforwardnet 
net = feedforwardnet(hiddenLayerSize, 'trainscg'); 
net.layers{1}.transferFcn = 'tansig'; 
net.layers{2}.transferFcn = 'softmax'; 
net.performFcn = 'crossentropy'; 

net.divideParam.trainRatio = 70/100; 
net.divideParam.valRatio = 15/100; 
net.divideParam.testRatio = 15/100; 

[net,tr] = train(net,x,t); 

y = net(x); 
performance = perform(net,t,y); 

fprintf('pass 4, feedforwardnet, performance: %f\n', performance); 
fprintf('num_epochs: %d, stop: %s\n', tr.num_epochs, tr.stop); 

Выход следующим образом:

pass 1, patternnet, performance: 0.116445 
num_epochs: 353, stop: Validation stop. 
pass 2, feedforwardnet, performance: 0.693561 
num_epochs: 260, stop: Validation stop. 
pass 3, patternnet, performance: 0.116445 
num_epochs: 353, stop: Validation stop. 
pass 4, feedforwardnet, performance: 0.693561 
num_epochs: 260, stop: Validation stop. 

ответ

0

Как правило, сети не ведут себя каждый тренинг абсолютно таким же образом. Это может зависеть от трех (я имею в виду, что знаю три) причины:

  1. Начальная инициализация нейронной сети.
  2. Нормализация данных
  3. Масштабирование данных
    Если говорить о (1) сеть изначально настроена со случайными весами, в некотором небольшом диапазоне с различными знаками. Например, нейрон с 6 входами может получить начальные веса, такие как: 0,1, -0,3, 0,16, -0,23, 0,015, -0,0005. И это может привести к немногому другому результату обучения. Если говорить о (2), если ваша нормализация выполняется плохо, алгоритм обучения сходится к локальным минимумам и не может выпрыгнуть из него. То же самое относится к случаю (3), если ваши данные нуждаются в масштабировании, и вы этого не сделали.
+0

См. Мое обновление, пожалуйста. 1-3 не может быть причин, так как результаты воспроизводятся на нескольких прогонах: 'patternnet' систематически выполняет лучше, чем (по-видимому) ту же самую' feedforwardnet'. Итак, причина в том, что (возможно) я инициализирую 'feedforwardnet' по-другому. Вопрос в том, в чем разница. –

+0

http://www.mathworks.com/help/nnet/ref/feedforwardnet.html и http://www.mathworks.com/help/nnet/ref/patternnet.html. feedforwardnet является более универсальным и больше предназначен для функций аппроксимации, а patternnet - для распознавания образов. –

+1

Если ваши данные задачи более подходят для шаблона, то patternnet будет работать лучше, и если ваши данные задачи более подходят для feedforwardnet, то функция feedforwardnet будет работать лучше. –

1

Похоже, эти двое не совсем то же самое:

>> net = patternnet(hiddenLayerSize); 
>> net2 = feedforwardnet(hiddenLayerSize,'trainscg'); 
>> net.outputs{2}.processParams{2} 

ans = 

    ymin: 0 
    ymax: 1 

>> net2.outputs{2}.processParams{2} 

ans = 

    ymin: -1 
    ymax: 1 

net.outputs{2}.processFcns{2} является mapminmax так я понимаю, что один из них повторно масштабирования это выход, чтобы соответствовать выходному диапазону ваших реальных данных лучше.

Для справок в будущем вы можете делать неприятные грязные вещи, такие как сравнение внутренних структур данных путем кастинга в struct. Поэтому я сделал что-то вроде

n = struct(net); n2 = struct(net2); 
for fn=fieldnames(n)'; 
    if(~isequaln(n.(fn{1}),n2.(fn{1}))) 
    fprintf('fields %s differ\n', fn{1}); 
    end 
end 

, чтобы помочь выявить различия.

Смежные вопросы