2015-04-08 6 views
5

mi sono molto diverse l'efficienza di formazione con la seguente reteSimula il patternnet predefinito con feedforwardnet in Matlab?

net = patternnet(hiddenLayerSize); 

e il successivo

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

sugli stessi dati.

Stavo pensando che le reti dovrebbero essere le stesse.

Che cosa ho dimenticato?

UPDATE

Il seguente codice illustra, che il comportamento della rete è dipende unicamente sulla funzione di creazione di rete.

Ogni tipo di rete è stata eseguita due volte. Questo esclude problemi generatori casuali o qualcosa del genere. I dati sono gli stessi.

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

uscita segue:

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. 

risposta

0

Come al solito non si comportano di rete ogni formazione assolutamente allo stesso modo. Può dipendere da tre motivi (intendo lo so tre):

  1. Inizializzazione iniziale della rete neurale.
  2. Normalizzazione dei dati
  3. scaling dei dati
    Se a parlare di (1) la rete è inizialmente configurata con pesi casuali, in qualche piccola gamma con segni diversi. Ad esempio il neurone con 6 ingressi può ottenere pesi iniziali come questo: 0.1, -0.3, 0.16, -0.23, 0.015, -0.0005. E questo può portare ad un altro piccolo risultato di allenamento. Se parlare di (2) se la normalizzazione è eseguita male, allora l'algoritmo di apprendimento converge ai minimi locali, e non può saltare fuori da esso. Lo stesso vale per il caso (3) se i tuoi dati hanno bisogno di ridimensionamento e non ce l'hai fatta.
+0

Vedere il mio aggiornamento per favore. 1-3 non può essere un motivo, dal momento che i risultati si riproducono su più esecuzioni: 'patternnet' esegue sistematicamente meglio di (apparentemente) lo stesso' feedforwardnet'. Quindi la ragione è (probabilmente) che inizializzo 'feedforwardnet' in modo diverso, la domanda è: qual è la differenza. –

+0

http://www.mathworks.com/help/nnet/ref/feedforwardnet.html e http://www.mathworks.com/help/nnet/ref/patternnet.html. feedforwardnet è più universale e destinato di più alle funzioni di approssimazione, mentre patternnet è più utile per il riconoscimento dei pattern. –

+1

Se i dati delle attività sono più adatti per patternnet, Patternnet funzionerà meglio e se i dati dell'attività sono più adatti per feedforwardnet, feedforwardnet funzionerà meglio. –

1

Sembra che quei due non sono proprio la stessa cosa:

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

Il net.outputs{2}.processFcns{2} è mapminmax così ho capito che uno di questi è ri-scalare il suo output in base al campo di uscita dei dati reali meglio.

Per riferimento futuro, è possibile fare brutte cose sporche come confrontare le strutture di dati interne mediante il cast di struct. Così ho fatto qualcosa come

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 

per aiutare a individuare le differenze.