2015-04-08 7 views
5

Ich habe sehr unterschiedliche Trainingseffizienz mit dem folgende NetzwerkSimulieren Standard-Patternnet mit Feedforwardnet in Matlab?

net = patternnet(hiddenLayerSize); 

und dem folgenden

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

auf den gleichen Daten.

Ich dachte, Netzwerke sollten gleich sein.

Was habe ich vergessen?

UPDATE

Der folgende Code zeigt, ist, dass das Netzwerkverhalten hängt eindeutig auf Netzwerk-Erstellungsfunktion.

Jede Art von Netzwerk wurde zwei Mal ausgeführt. Dies schließt zufällige Generatorprobleme oder etwas anderes aus. Daten sind gleich.

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

Ausgang folgt:

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. 

Antwort

0

Da in der Regel verhält Netzwerk nicht jedes Training absolut die gleiche Weise. Es kann von drei (ich meine, ich kenne drei) Gründe:

  1. initial Initialisierung des neuronalen Netzes.
  2. Normalization Daten
  3. Skalierung der Daten
    Wenn über (1) das Netzwerk mit zufälligen Gewichten, in einem gewissen kleinen Bereich mit unterschiedlichen Vorzeichen wird anfänglich konfiguriert ist, um zu sprechen. Zum Beispiel Neuronen mit 6 Eingängen können Anfangsgewichte wie folgt erhalten: 0,1, -0,3, 0,16, -0,23, 0,015, -0,0005. Und das kann zu einem weiteren Trainingsergebnis führen. Wenn Sie über (2) sprechen, wenn Ihre Normalisierung schlecht durchgeführt wird, dann konvergiert der Lernalgorithmus zu lokalen Minima und kann nicht herausspringen. Dasselbe gilt für den Fall (3), wenn Ihre Daten skaliert werden müssen und Sie es nicht gemacht haben.
+0

Siehe mein Update bitte. 1-3 können keine Gründe sein, da sich die Ergebnisse auf mehreren Läufen reproduzieren: 'patternnet' führt systematisch besser aus als (scheinbar) das gleiche' feedforwardnet'. Der Grund ist (wahrscheinlich) ich initiiere 'feedforwardnet' anders, Die Frage ist: Was ist der Unterschied? –

+0

http://www.mathworks.com/help/nnet/ref/feedforwardnet.html und http://www.mathworks.com/help/nnet/ref/patternnet.html. feedforwardnet ist universeller und eher für Approximationsfunktionen gedacht, während patternnet eher für die Mustererkennung gedacht ist. –

+1

Wenn Ihre Aufgabendaten besser für patternnet passen, dann wird patternnet besser funktionieren, und wenn Ihre Aufgabendaten für feedforwardnet passender sind, wird feedforwardnet besser funktionieren. –

1

Sieht aus wie diese beiden sind nicht ganz das gleiche:

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

Die net.outputs{2}.processFcns{2} ist mapminmax so entnehme ich, dass eine davon ist neu skaliert es ausgegeben ist, den Ausgangsbereich Ihrer realen Daten übereinstimmen besser.

Für zukünftige Referenz können Sie böse schmutzige Dinge wie Vergleich der inneren Datenstrukturen durch Casting zu Struct. Also habe ich etwas wie

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 

zu helfen, um die Unterschiede zu lokalisieren.