2017-03-24 3 views
2

Ich versuche, eine Lambda-Schicht zu implementieren, die eine benutzerdefinierte Verlustfunktion erzeugt. In der Schicht muss ich in der Lage sein, jedes Element in einer Charge mit jedem anderen Element in der Charge zu vergleichen, um die Kosten zu berechnen. Idealerweise mag ich Code, der etwa wie folgt aussieht:Keras Lambda Layer für benutzerdefinierten Verlust

for el_1 in zip(y_pred, y_true): 
    for el_2 in zip(y_pred, y_true): 
     if el_1[1] == el_2[1]: 
      # Perform a calculation 
     else: 
      # Perform a different calculation 

Als ich dies wahr ist, erhalte ich:

TypeError: TensorType does not support iteration. 

I Keras Version 2.0.2 mit einem Theano Version 0.9.0 Backend verwenden. Ich verstehe, dass ich Keras-Tensor-Funktionen verwenden muss, um dies zu tun, aber ich kann keine Tensorfunktionen herausfinden, die tun, was ich will.

Auch habe ich Schwierigkeiten zu verstehen, genau was meine Lambda-Funktion zurückgeben sollte. Ist es ein Tensor der Gesamtkosten für jede Probe oder sind es nur Gesamtkosten für die Charge?

Ich habe seit Tagen meinen Kopf dagegen geschlagen. Jede Hilfe wird sehr geschätzt.

+0

Okay, mit Keras Callbacks, ich bestimmte, was der Lambda zurückgeben soll - ein Skalar pro Batch. Ich kann jedoch immer noch nicht herausfinden, wie man während des Trainings über Tensoren iteriert. Ich denke, es könnte mit dem Schneiden zu tun haben ... – gaw89

+0

Haben Sie meine Antwort gelesen? – nemo

+0

Sorry, über das Wochenende gegangen. Nur akzeptiert. Danke vielmals! – gaw89

Antwort

2

Ein Tensor in Keras hat üblicherweise mindestens 2 Dimensionen, die Charge und die Neuron/Einheit/Knoten/... Dimension. Eine dichte Schicht mit 128 Einheiten, die mit einer Chargengröße von 64 trainiert wurde, würde daher einen Tensor mit der Form (64,128) ergeben.

Ihre LambdaLayer Prozessoren Tensoren wie jede andere Schicht tut, stecken Sie es nach Ihrer dichten Schicht von zuvor wird Ihnen einen Tensor mit Form (64,128) zu verarbeiten. Die Verarbeitung eines Tensors funktioniert ähnlich wie bei Berechnungen mit numpy Arrays (oder einer anderen Vektorverarbeitungsbibliothek): Sie geben eine Operation an, die über alle Elemente in der Datenstruktur gesendet wird.

Zum Beispiel Ihre individuelle Kosten ist die Differenz für jeden Wert in der Charge, würden Sie es wie so implementieren:

cost_layer = LambdaLayer(lambda a,b: a - b) 

Der - Betrieb wird über a und b ausgestrahlt und ein geeignetes Ergebnis bereitgestellt Rück die Dimensionen stimmen überein. Der Vorteil ist, dass Sie wirklich nur eine Operation für jeden Wert angeben können. Wenn Sie komplexere Aufgaben ausführen möchten, z. B. Berechnungen basierend auf dem Wert, benötigen Sie Einzeloperationen, die zwei Operationen ausführen, und wenden die richtige entsprechend an, d. H. Die Operation switch.

Die Syntax für K.switch ist

K.switch(condition, then_expression, else_expression) 

Zum Beispiel, wenn Sie beide Werte, wenn a != b subtrahieren wollen, aber sie addieren, wenn sie gleich sind, würden Sie schreiben:

import keras.backend as K 
cost_layer = LambdaLayer(lambda a,b: K.switch(a != b, a - b, a + b)) 
Verwandte Themen