Ich habe Code geschrieben, um Backpropagation in einem tiefen neuronalen Netzwerk mit der logistischen Aktivierungsfunktion und dem Softmax-Ausgang zu implementieren.Backpropagation mit korrigierten Lineareinheiten
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
Der Code funktioniert gut, aber wenn ich zu relu als Aktivierungsfunktion eingeschaltet arbeitet er gestoppt. In der Backprop Routine wechsle ich nur die Ableitung der Aktivierungsfunktion:
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
jedoch das Netzwerk nicht mehr lernt, und die Gewichte gehen schnell auf Null und dort bleiben. Ich bin total ratlos.
Sind Sie sicher, dass Sie die richtige Darstellung des Derivats haben? – Ashalynd
Ich bin mir ziemlich sicher, dass ich das tue. Die Ableitung sollte 0 sein, wenn der Eingang negativ ist, 1, wenn der Eingang positiv ist. ReLU ist bei Null nicht differenzierbar, daher nehme ich hier an, dass die Ableitung bei null null ist. – GuillaumeDufay
Wenn Weight_Matrices-Werte <1 sind, würde das Setzen der Ableitung auf 0 oder 1 bedeuten, dass Sie delta_nodes/delta_weights bei jedem folgenden Schritt systematisch verringern. Vielleicht sollten Sie sie wieder normalisieren? – Ashalynd