2015-04-04 10 views
5

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.

+0

Sind Sie sicher, dass Sie die richtige Darstellung des Derivats haben? – Ashalynd

+0

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

+0

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

Antwort

4

Obwohl ich die Ursache des Problems festgestellt habe, werde ich das hier lassen, falls es für jemand anderen von Vorteil sein könnte.

Das Problem war, dass ich die Skala der Anfangsgewichte nicht angepasst habe, wenn ich die Aktivierungsfunktionen änderte. Während logistische Netzwerke sehr gut lernen, wenn Knoteneingänge nahe Null sind und die logistische Funktion annähernd linear ist, lernen ReLU-Netzwerke gut für mäßig große Eingaben in Knoten. Die in Logistiknetzwerken verwendete kleine Gewichtsinitialisierung ist daher nicht notwendig und in der Tat schädlich. Das Verhalten, das ich sah, war das ReLU-Netzwerk, das die Eigenschaften ignorierte und versuchte, die Voreingenommenheit des Trainingssatzes ausschließlich zu erlernen.

Ich verwende derzeit Anfangsgewichtungen gleichmäßig verteilt von -5 bis .5 auf dem MNIST-Datensatz, und es lernt sehr schnell.

Verwandte Themen