2015-05-27 7 views
9

Ho scritto la seguente routine di backpropagation per una rete neurale, usando come esempio il codice here. Il problema che sto affrontando mi confonde e ha spinto al limite le mie capacità di debug.Perché questa implementazione di backpropagation non riesce a formare correttamente i pesi?

Il problema che sto affrontando è piuttosto semplice: mentre la rete neurale si allena, i suoi pesi vengono addestrati a zero senza alcun guadagno in precisione.

ho cercato di risolvere il problema molte volte, verificando che:

  • i set di allenamento sono corretti
  • i vettori di destinazione siano corretti
  • il passo in avanti è la registrazione informazioni in modo corretto
  • all'indietro i delta step stanno registrando correttamente
  • i segni sui delta sono corretti
  • i pesi sono ind eed essere regolato
  • delta dello strato di input sono tutti a zero
  • non ci sono altri errori o avvisi di overflow

Alcuni dati:

  • Gli input di formazione sono una griglia 8x8 di [ 0,16) valori che rappresentano un'intensità; questa griglia rappresenta una cifra numerica (convertito in un vettore colonna)
  • Il vettore obiettivo è un'uscita che è 1 nella posizione corrispondente al numero corretto
  • I pesi e pregiudizi originali vengono assegnati dalla distribuzione gaussiana
  • Le attivazioni sono un sigmoide standard

Non so da dove andare. Ho verificato che tutto ciò che so controllare funzioni correttamente e non funziona ancora, quindi ti sto chiedendo qui. Quello che segue è il codice che sto usando per backpropagate:

def backprop(train_set, wts, bias, eta): 
    learning_coef = eta/len(train_set[0]) 

    for next_set in train_set: 
     # These record the sum of the cost gradients in the batch 
     sum_del_w = [np.zeros(w.shape) for w in wts] 
     sum_del_b = [np.zeros(b.shape) for b in bias] 

     for test, sol in next_set: 
      del_w = [np.zeros(wt.shape) for wt in wts] 
      del_b = [np.zeros(bt.shape) for bt in bias] 
      # These two helper functions take training set data and make them useful 
      next_input = conv_to_col(test) 
      outp = create_tgt_vec(sol) 

      # Feedforward step 
      pre_sig = []; post_sig = [] 
      for w, b in zip(wts, bias): 
       next_input = np.dot(w, next_input) + b 
       pre_sig.append(next_input) 
       post_sig.append(sigmoid(next_input)) 
       next_input = sigmoid(next_input) 

      # Backpropagation gradient 
      delta = cost_deriv(post_sig[-1], outp) * sigmoid_deriv(pre_sig[-1]) 
      del_b[-1] = delta 
      del_w[-1] = np.dot(delta, post_sig[-2].transpose()) 

      for i in range(2, len(wts)): 
       pre_sig_vec = pre_sig[-i] 
       sig_deriv = sigmoid_deriv(pre_sig_vec) 
       delta = np.dot(wts[-i+1].transpose(), delta) * sig_deriv 
       del_b[-i] = delta 
       del_w[-i] = np.dot(delta, post_sig[-i-1].transpose()) 

      sum_del_w = [dw + sdw for dw, sdw in zip(del_w, sum_del_w)] 
      sum_del_b = [db + sdb for db, sdb in zip(del_b, sum_del_b)] 

     # Modify weights based on current batch    
     wts = [wt - learning_coef * dw for wt, dw in zip(wts, sum_del_w)] 
     bias = [bt - learning_coef * db for bt, db in zip(bias, sum_del_b)] 

    return wts, bias 

Con il suggerimento di Shep, ho controllato quello che succede quando la formazione di una rete di forma [2, 1, 1] per sempre l'uscita 1, e in effetti, i treni della rete correttamente questo caso. La mia ipotesi migliore a questo punto è che il gradiente si sta regolando troppo forte per gli 0 e debolmente sugli 1, risultando in una diminuzione netta nonostante un aumento ad ogni passo, ma non ne sono sicuro.

+3

poiché non hai codificato la topologia della rete, ecco un suggerimento: prova ad allenarti con zero o uno nascosto (ognuno con un nodo), un input e un output, per vedere se fa quello che aspettarsi. – Shep

+0

@Shep In modo interessante, quando si esegue su una rete nnet con forma '[2, 1, 1]', i pesi vengono effettivamente addestrati correttamente. Addestrandolo all'uscita 1, i pesi effettivamente aumentano, e l'uscita converge a 1. Test interessante. – Zyerah

+0

1) Con "i pesi vengono addestrati a zero", si intende che i pesi iniziano come numeri casuali, ma sembrano convergere a zero? 2) Quanto è grande la tua rete attuale? 3) Prova a ridimensionare gli input nell'intervallo [0, 1]. – cfh

risposta

1

Suppongo che il problema sia nella scelta dei pesi iniziali e nella scelta dell'inizializzazione dell'algoritmo dei pesi. Jeff Heaton autore di Encog afferma che come di solito si comporta peggio di altri metodi di inizializzazione. Here è un altro risultato della perfomance dell'algoritmo di inizializzazione dei pesi. Inoltre, dalla mia esperienza personale, ti consiglio di iniziare i tuoi pesi con diversi valori di segni. Anche nei casi in cui ho avuto tutte le uscite positive pesi con segni diversi perfomed meglio allora con lo stesso segno.

Problemi correlati