2015-05-27 14 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.