Ho scritto del codice per implementare il backpropagation in una rete neurale profonda con la funzione di attivazione logistica e l'output di softmax.Backpropagation con unità lineari rettificate
def backprop_deep(node_values, targets, weight_matrices):
delta_nodes = node_values[-1] - targets
delta_weights = delta_nodes.T.dot(node_values[-2])
weight_updates = [delta_weights]
for i in xrange(-2, -len(weight_matrices)- 1, -1):
delta_nodes = dsigmoid(node_values[i][:,:-1]) * delta_nodes.dot(weight_matrices[i+1])[:,:-1]
delta_weights = delta_nodes.T.dot(node_values[i-1])
weight_updates.insert(0, delta_weights)
return weight_updates
Il codice funziona bene, ma quando sono passato a Relu come la funzione di attivazione ha smesso di funzionare. Nella routine backprop cambio solo la derivata della funzione di attivazione:
def backprop_relu(node_values, targets, weight_matrices):
delta_nodes = node_values[-1] - targets
delta_weights = delta_nodes.T.dot(node_values[-2])
weight_updates = [delta_weights]
for i in xrange(-2, -len(weight_matrices)- 1, -1):
delta_nodes = (node_values[i]>0)[:,:-1] * delta_nodes.dot(weight_matrices[i+1])[:,:-1]
delta_weights = delta_nodes.T.dot(node_values[i-1])
weight_updates.insert(0, delta_weights)
return weight_updates
Tuttavia, la rete non è più impara, ed i pesi andare rapidamente a zero e rimanere lì. Sono totalmente perplesso.
sei sicuro di avere la giusta rappresentazione della derivata? – Ashalynd
Sono ragionevolmente certo di farlo. La derivata deve essere 0 quando l'input è negativo, 1 quando l'input è positivo. ReLU non è differenziabile a zero, quindi qui presumo che la derivata sia solo zero a zero. – GuillaumeDufay
Se i valori di matrici di peso sono <1, impostare la derivata su 0 o 1 significherebbe che si stanno riducendo in modo sistematico delta_nodes/delta_weights in ogni passaggio successivo. Potresti doverli rinormalizzare? – Ashalynd