2016-12-08 10 views
3

Ich versuche this keras blog über Feinabstimmung Bildklassifizierer nachzuahmen. Ich möchte den Inceptionv3 gefunden on a fchollet repo verwenden.Kombinieren zu Keras Funktionsmodelle

Inception ist eine Model (funktionale API), so kann ich nicht einfach tun , die für Sequential reserviert ist.

Wie kann ich kombinieren zwei funktionale Model s hinzufügen? Sagen wir, ich

inputs = Input(shape=input_shape) 
x = Flatten()(inputs) 
predictions = Dense(4, name='final1')(x) 

model1 = Model(input=inputs, output=predictions) 

für das erste Modell und

inputs_2 = Input(shape=(4,)) 
y = Dense(5)(l_inputs) 
y = Dense(2, name='final2')(y) 
predictions_2 = Dense(29)(y) 
model2 = Model(input=inputs2, output=predictions2) 

für die zweite haben. Ich möchte jetzt ein Ende-zu-Ende, das von inputs zu predicions_2 und Links predictions zu inputs_2 geht.

Ich versuchte mit model1.get_layer('final1').output, aber ich hatte eine Diskrepanz mit Typen und ich konnte es nicht funktionieren.

Antwort

4

Ich denke, es gibt zwei Möglichkeiten, je nachdem, was Sie brauchen:

(a) predictions_1 und predictions_2 Angelegenheit für Sie. In diesem Fall können Sie ein Netzwerk mit 2 Ausgängen trainieren. Hier ein Beispiel aus Ihrem Beitrag abgeleitet:

input_shape = [3, 20] 
inputs = Input(shape=input_shape) 
x = Flatten()(inputs) 
predictions_1 = Dense(4, name='predictions_1')(x) 

# here the predictions_1 just corresponds to your next layer's input 
y = Dense(5)(predictions_1) 
y = Dense(2)(y) 
predictions_2 = Dense(29, name='predictions_2')(y) 

# you specify here that you have 2 outputs 
model = Model(input=inputs, output=[predictions_1, predictions_2]) 

Für die .fit und .predict, können Sie eine Menge von Details in https://keras.io/getting-started/functional-api-guide/ Abschnitt finden: Multi-Input und Multi-Output-Modelle.

(b) Sie sind nur an Vorhersagen_2 interessiert. In diesem Fall können Sie einfach tun:

input_shape = [3, 20] 
inputs = Input(shape=input_shape) 
x = Flatten()(inputs) 
predictions_1 = Dense(4, name='predictions_1')(x) 

# here the predictions_1 just corresponds to your next layer's input 
y = Dense(5)(predictions_1) 
y = Dense(2)(y) 
predictions_2 = Dense(29, name='predictions_2')(y) 

# you specify here that your only output is predictions_2 
model = Model(input=inputs, output=predictions_2) 

nun in Bezug auf inception_v3. Sie können selbst die Architektur definieren und die tiefen Schichten nach Ihren Bedürfnissen modifizieren (indem Sie diesen Layern spezifische Namen geben, um zu vermeiden, dass sie automatisch benannt werden).

Danach kompilieren Sie Ihr Modell und Lasten Gewichte (wie in https://keras.io/models/about-keras-models/ siehe Funktion load_weights (..., by_name = True))

# you can load weights for only the part that corresponds to the true 
# inception_v3 architecture. The other part will be initialized 
# randomly 
model.load_weights("inception_v3.hdf5", by_name=True) 

Dieses Ihr Problem lösen sollte. Übrigens können Sie zusätzliche Informationen hier finden: https://www.gradientzoo.com. Der Arzt.erklärt mehrere Speichern/Laden/Feinabstimmung Routinen;)

aktualisieren: Wenn Sie von Grund auf Ihr Modell nicht neu definieren möchten Sie Folgendes tun können:

input_shape = [3, 20] 

# define model1 and model2 as you want 
inputs1 = Input(shape=input_shape) 
x = Flatten()(inputs1) 
predictions_1 = Dense(4, name='predictions_1')(x) 
model1 = Model(input=inputs1, output=predictions_1) 

inputs2 = Input(shape=(4,)) 
y = Dense(5)(inputs2) 
y = Dense(2)(y) 
predictions_2 = Dense(29, name='predictions_2')(y) 
model2 = Model(input=inputs2, output=predictions_2) 

# then define functions returning the image of an input through model1 or model2 
def give_model1(): 
    def f(x): 
     return model1(x) 
    return f 

def give_model2(): 
    def g(x): 
     return model2(x) 
    return g 

# now you can create a global model as follows: 
inputs = Input(shape=input_shape) 
x = model1(inputs) 
predictions = model2(x) 
model = Model(input=inputs, output=predictions) 
+0

vielen Dank. diese Arbeit, wenn ich das ganze Anfangsmodell neu definieren will. Was aber, wenn ich bereits ein Model-Objekt habe? Ich habe mich gefragt, ob es eine Möglichkeit gibt, es direkt an das neue Modell anzuhängen, ohne es von Grund auf neu definieren zu müssen (wenn man bedenkt, dass es sich um ein sehr großes Modell handelt). Danke auch für den Link – meto

+0

@meto ok ich bekomme es. Ich habe gerade meine Antwort basierend auf Ihrem Kommentar und Omids Vorschlag aktualisiert. Funktioniert es für Sie? – bn2nkm

7

ich nicht versucht haben, sondern nach den documentation Funktionsmodelle sind aufrufbar, so dass Sie so etwas tun:

y = model2(model1(x)) 

wo x die Daten, die an die Eingänge und y geht, ist die Ergebnis von predictions_2

2

Ich lief in dieses Problem auch während der Feinabstimmung VGG16. Hier ist, was für mich funktioniert hat und ich denke, dass ein ähnlicher Ansatz für Inception V3 verwendet werden kann. Getestet auf Keras 2.0.5 mit Tensorflow 1.2 Backend.

# NOTE: define the following variables 
#  top_model_weights_path 
#  num_classes 
#  dense_layer_1 = 4096 
#  dense_layer_2 = 4096 

vgg16 = applications.VGG16(
    include_top=False, 
    weights='imagenet', 
    input_shape=(224, 224, 3)) 

# Inspect the model 
vgg16.summary() 

# This shape has to match the last layer in VGG16 (without top) 
dense_input = Input(shape=(7, 7, 512)) 
dense_output = Flatten(name='flatten')(dense_input) 
dense_output = Dense(dense_layer_1, activation='relu', name='fc1')(dense_output) 
dense_output = Dense(dense_layer_2, activation='relu', name='fc2')(dense_output) 
dense_output = Dense(num_classes, activation='softmax', name='predictions')(dense_output) 

top_model = Model(inputs=dense_input, outputs=dense_output, name='top_model') 

# from: https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html 
# note that it is necessary to start with a fully-trained 
# classifier, including the top classifier, 
# in order to successfully do fine-tuning 
top_model.load_weights(top_model_weights_path) 

block5_pool = vgg16.get_layer('block5_pool').output 

# Now combine the two models 
full_output = top_model(block5_pool) 
full_model = Model(inputs=vgg16.input, outputs=full_output) 

# set the first 15 layers (up to the last conv block) 
# to non-trainable (weights will not be updated) 
# WARNING: this may not be applicable for Inception V3 
for layer in full_model.layers[:15]: 
    layer.trainable = False 

# Verify things look as expected 
full_model.summary() 

# compile the model with a SGD/momentum optimizer 
# and a very slow learning rate. 
full_model.compile(
    loss='binary_crossentropy', 
    optimizer=optimizers.SGD(lr=5e-5, momentum=0.9), 
    metrics=['accuracy']) 

# Train the model...