2017-04-11 2 views
2

Ich möchte ein neues Netzwerk aus zwei bestehenden Netzwerken (Modelle) A und B mit Keras mit Tensorflow erstellen. Architektur des neuen Netzwerks ist wie dieserKann die Lambda-Ebene verwendet werden, um die Daten und die Form der Eingabe zu manipulieren?

Eingang -> A -> B -> Ausgabe

Der Ausgang von A hat Form (15, 500) und die B-Eingang hat eine Form (1000). Ich habe eine Konvertierungsmethode, die die Eingabe von Shape (15, 100) und Call-Vorhersage eines völlig anderen Netzwerks (C) nimmt und die Ausgabe mit der Form von (1000) zurückgibt.

Ich gehe davon aus, dass ich eine Lambda-Schicht einzuführen, die meine Konvertierungsmethode verwenden, um die Ausgabe von A in ein Format für B. erforderlich, aber zu konvertieren, als ich versuchte, dass ich Fehler

„Typeerror : nicht unterstützte Operandentypen für /: 'Dimension' und 'float'_ "beim Aufrufen der Vorhersage in der Konvertierungsmethode.

Dies ist die Umwandlungsmethode

def convert(x): 
    C = load_model("path/to/the/network/C.h5") 
    return C.predict(x) 

Ich bin nicht sicher, ob dies der richtige Weg zu tun ist, wenn es ist, dann, warum dieser Fehler ist. Wenn es nicht der richtige Weg ist, was sollte mein Ansatz sein?

Keras Version: 2.0.1 Tensorflow Version: 1.0.1

Danke,

+0

Nein, Diese "Konvertierungs" -Methode wird nicht funktionieren, wenn C ein trainierbares Netzwerk sein wird. Wir brauchen mehr Details, wie ist die Architektur von C? – putonspectacles

+0

@putonspectacles Ich habe einen Auto-Encoder mit RNN-Schichten. Es ist Architektur ist (Input -> Dropout -> LSTM -> Dichte -> Dichte -> RepeatVector -> LSTM). C hat die ersten 5 Schichten, um die Ausgabe von der Codiererschicht zu erhalten. Das heißt, C = Model (Eingabe, model.get_layer ('dichte_2'). Ausgabe) – paachi

+0

ok, so haben Sie 3 Netzwerke A, B, C, Ihr Ziel ist es, ein Netzwerk zu trainieren D: Input -> A -> B -> Ausgabe. Aber während des Trainings D möchten Sie auch die Vorhersagen (auf Input) von C als Teil der Transformation im Netzwerk nehmen. Habe ich das richtig verstanden? – putonspectacles

Antwort

1

Ich gehe davon aus, dass Sie nicht das C in als Teil des neuen Netzes zu trainieren versuchen (lass es D nennen). Das, was ich Ihnen vorstellen möchte

A 
| 
(C) # transform step. a non-trainable keras model 
| 
B 
| 
out 

Beachten Sie die Variablennamen aus den Beispielen sind in der ursprünglichen Antwort Abschnitt.

aktualisieren, Ja der Code in ORGINAL beantworten nur die von model_1dense_2 Schicht verwendet.

Das ist nicht was du willst, also ging ich graben. Und schön, die Antwort ist einfach.

  • Last C und seine Gewichte,
  • Aktualisierung der Ausgänge des Modells, so dass wir eine beliebige Schicht, wie der Ausgang gesetzt.
  • setzen Sie die Schichten von C nicht trainierbar mit layer.trainable = False.
  • Schließlich fordern die verwandeln Modell wie ein Schicht model_1(inp2)

Hier wird das Beispiel in der ursprünglichen Antwort aktualisiert, um zu beweisen, dass Gewichte in C nicht trainierbar sind wir model_1.summary() drucken

# let `model_1` be C in the diagram above. 
from keras.models import Model 
from keras.layers import (Lambda, Dense, Input) 

inp = Input(shape=(5,)) 
lam = Lambda(lambda x: x + 2, name='lamb')(inp) 
den = Dense(1, name='dense')(lam) # this is the `model_1` output 
model_1 = Model(inp, den) 

# suppose we want an intermediate output from model_1 
# (the `lam` layer for instance) 
# we update the outputs and use that output in model2 

model.outputs = [model.output, model.get_layer(name='lamb').output] 
print(model.outputs) 

# [<tf.Tensor 'dense_11/BiasAdd:0' shape=(?, 1) dtype=float32>, 
# <tf.Tensor 'lamb_9/add:0' shape=(?, 5) dtype=float32>] 

# now build D, since we can treat a model like a layer(awesome!) 
# we can just let models A, B in the diagram above be layers 
# (for this exmple) - nothing changes. 

# But first set the layers of `model_1` to not be trainable: 

print(model_1.summary()) # Trainable params: 6.0 - before 
for l in model_1.layers: 
    l.trainable = False 
print(model_1.summary()) # Trainable params: 0.0 - after 

# ...then D is: 

inp2 = Input(shape=(5,))  # imagine that this layer is model A 
transform = model_1(inp2)[1] # this is (C) the transform step. 
           # Notice that we pulled out the lambda 
           # output by using the index into the 
           # `model_1's` outputs. 

# carry on as normal 
den2 = Dense(1)(transform) # imagine that this is B 
model_2 = Model(inp2, den2) 
model_2.compile(loss='mse', optimizer='adam') 
model_2.summary() 

# simulate data 
X = np.random.randn(10, 5) 
y = np.random.randn(10, 1) 

# fit D 
model_2.fit(X, y) # ... it trains! 

Ein paar Anmerkungen:

  • werden wir nicht sein Aufruf kompilieren, da wir das Modell für das Training nicht konfigurieren müssen. Siehe doc Reihe von compile() oder äquivalent die keras docs

  • Wenn wir jedoch das Modell mit keras.models.load_model laden. Dieses Modell ist kompiliert, aber es sollte keinen Einfluss haben, da wir layer.trainable = False verwenden werden. doc-String für save()

Original-Antwort

Statt mit einer die Vorhersage der Rücksendung ein Array ist, greifen die Ausgabe die letzte Schicht von C.

def convert(x): 
    # there is not need to load C in the lambda layer. 
    # load it somewhere outside of the training op. 
    # assuming you have C loaded... 
    return C.get_layer('dense_2')(x) 

hier ein See ist schnelles Beispiel für diesen Ansatz: Beachten Sie, dass Sie sicherstellen müssen, dass die Layer-Shape kompatibel sind.

können Sie sich vorstellen, dass dieser Modus C

from keras.models import Model 
from keras.layers import (Lambda, Dense, Input) 

inp = Input(shape=(5,)) 
lam = Lambda(lambda x: x + 2, name='lamb')(inp) 
den = Dense(1, name='dense')(lam) # this is the `model_` output 
model_1 = Model(inp, den) 
model_1.compile(loss='mse', optimizer='adam') 

ist die Ausgabe der Schicht lam wir gehen greifen und verwenden, die als Transformationsschritt in D unter:

inp2 = Input(shape=(5,)) 
# grab the 'dense' layer from `model_1` 
sums = Lambda(lambda x: model_1.get_layer(name='dense')(x))(inp2) 
den2 = Dense(1)(sums) 
model_2 = Model(inp2, sums) 
model_2.compile(loss='mse', optimizer='adam') 
model_2.summary() 
+0

Im Transformationsschritt möchte ich die Ausgabe der Untermenge des Modells C (die ersten paar Schichten), nicht nur die n-te Schicht. Das heißt, wenn das trainierte Netzwerk C die Schichten C1 -> C2 -> C3 -> C4 -> C5 -> C6 -> C7 hat, würde ich gerne die Ausgabe des Untermodells (C1 -> C2 -> C3 - > C4 - C5) in meinem D. Ihr Beispiel oben, in D-Netzwerk, nehmen Sie nur die "dichte" Schicht, wo ich denke, dass wir alle Schichten vor dem Netzwerk berücksichtigen müssen. – paachi

+0

Ich korrigiere nur den letzten Satz in meinem vorherigen Empfehlungsschreiben. "Ihr Beispiel oben, in D-Netzwerk, nehmen Sie nur die 'dichte' Schicht, wo ich denke, dass wir alle Schichten vor der 'dichten' Schicht betrachten müssen" – paachi

+0

@ Fasil, du hast Recht! Siehe mein Update für eine Reparatur. – putonspectacles

Verwandte Themen