6

Sto cercando di implementare backpropagation con ricorsione a fini accademici, ma sembra che io abbia sbagliato qualcosa da qualche parte. Sono stati armeggiare con esso per un po 'ora, ma non ottengono alcun apprendimento o nessun apprendimento sul secondo schema.ANN: backpropagation ricorsivo

Per favore fatemi sapere dove ho sbagliato. (Questa è la sintassi javascript) Nota: gli errori vengono reimpostati su null prima di ogni ciclo di apprendimento.

this.backpropagate = function(oAnn, aTargetOutput, nLearningRate) { 
    nLearningRate = nLearningRate || 1; 

    var oNode, 
     n = 0; 

    for (sNodeId in oAnn.getOutputGroup().getNodes()) { 
     oNode = oAnn.getOutputGroup().getNodes()[sNodeId]; 
     oNode.setError(aTargetOutput[n] - oNode.getOutputValue()); 
     n ++; 
    } 

    for (sNodeId in oAnn.getInputGroup().getNodes()) { 
     this.backpropagateNode(oAnn.getInputGroup().getNodes()[sNodeId], nLearningRate); 
    } 
} 

this.backpropagateNode = function(oNode, nLearningRate) { 
    var nError = oNode.getError(), 
     oOutputNodes, 
     oConn, 
     nWeight, 
     nOutputError, 
     nDerivative = oNode.getOutputValue() * (1 - oNode.getOutputValue()), // Derivative for sigmoid activation funciton 
     nInputValue = oNode.getInputValue(), 
     n; 

    if (nError === null /* Dont do the same node twice */ && oNode.hasOutputs()) { 

     nDerivative = nDerivative || 0.000000000000001; 
     nInputValue = nInputValue || 0.000000000000001; 

     oOutputNodes = oNode.getOutputNodes(); 

     for (n=0; n<oOutputNodes.length; n++) { 
      nOutputError = this.backpropagateNode(oOutputNodes[n], nLearningRate); 

      oConn = oAnn.getConnection(oNode, oOutputNodes[n]); 
      nWeight = oConn.getWeight(); 
      oConn.setWeight(nWeight + nLearningRate * nOutputError * nDerivative * nInputValue); 
      nError += nOutputError * nWeight; 
     } 
     oNode.setError(nError); 
    } 

    return oNode.getError(); 
} 
+0

Come appare la struttura della rete neurale? C'è una ragione per cui stai usando la ricorsione? Dovresti essere in grado di scorrere i singoli livelli iniziando dal livello di output e risalendo. –

+0

Vivin, il punto accademico di questo esercizio è usare la ricorsione per BP. (No, questo non è il mio compito, sto solo cercando di capire questo :) La rete a questo punto è molto semplice: 2-2-1 rete a 3 strati con funzioni di attivazione sigmoide, che sto cercando di addestrare con campioni di allenamento [1, 0] -> [0,2] e [0, 1] -> [0,9]. –

+0

Gli algoritmi tipici che ho visto lo fanno in modo iterativo; Mi stavo chiedendo perché hai scelto la ricorsione. :) –

risposta

2

Risolto. Le reti apparentemente di bassa dimensione hanno maggiori probabilità di rimanere bloccate in un minimo locale. Questo è facile da capire sapendo che le reti di dimensione superiore hanno meno probabilità di raggiungere qualsiasi minimo, anche globale.

Il momento di attuazione che aumenta a ogni iterazione mi consente di superare la maggior parte dei minimi. Quindi, reinizializzare i valori in valori casuali (da -0,5 a 0,5) e condurre sessioni di allenamento multiple, alla fine mi fa attraversare tutti loro.

Sono lieto di annunciare che la mia rete ora riceve la formazione nel 100% dei casi se i dati sono classificabili.