2017-10-04 3 views
1

Sagen wir ein Faltungs neuronales Netz M. habe ich Eigenschaften von Bildern unter VerwendungExtrahieren letzten Schichten keras Modell als submodel

extractor = Model(M.inputs, M.get_layer('last_conv').output) 
features = extractor.predict(X) 

extrahieren Wie kann ich das Modell zu bekommen, die Klassen mit features vorhersagen ?

Ich kann die folgenden Zeilen nicht verwenden, da die Eingabe des Modells ein Platzhalter sein muss.

predictor = Model([M.get_layer('next_layer').input], M.outputs) 
pred = predictor.predict(features) 

Ich kann auch K.function nicht verwenden, weil später ich es als Teil eines anderen Modells verwenden möchten, so werde ich appliyng Prädiktor tf.tensor, nicht np.array sein.

+0

Was das Problem ist, einen Platzhalter mit der Verwendung oder eine Eingabeschicht? Das ist der richtige Weg. –

+1

@MatiasValdenegro Wie staple ich ** trainierte ** Schichten des Prädiktors auf neue Input-Ebene? – eclique

+0

Mit der funktionalen API, verwenden Sie einfach Ihr Modell als eine Ebene: in = Eingabe (...) inter = yourModel (in) final = Dichte (10) (inter) –

Antwort

2

Dies ist nicht die schönste Lösung, aber es funktioniert:

from keras.models import Sequential 
from keras.layers import Conv2D, MaxPooling2D 
from keras.layers import Dense, Dropout, Flatten 

def cnn(): 
    model = Sequential() 
    model.add(Conv2D(32, kernel_size=(3, 3), 
        activation='relu', 
        input_shape=(28, 28, 1), name='l_01')) 
    model.add(Conv2D(64, (3, 3), activation='relu', name='l_02')) 
    model.add(MaxPooling2D(pool_size=(2, 2), name='l_03')) 
    model.add(Dropout(0.25, name='l_04')) 
    model.add(Flatten(name='l_05')) 
    model.add(Dense(128, activation='relu', name='l_06')) 
    model.add(Dropout(0.5, name='l_07')) 
    model.add(Dense(10, activation='softmax', name='l_08')) 
    return model 

def predictor(input_shape): 
    model = Sequential() 
    model.add(Flatten(name='l_05', input_shape=(12, 12, 64))) 
    model.add(Dense(128, activation='relu', name='l_06')) 
    model.add(Dropout(0.5, name='l_07')) 
    model.add(Dense(10, activation='softmax', name='l_08')) 
    return model 

cnn_model = cnn() 
cnn_model.save('/tmp/cnn_model.h5') 

predictor_model = predictor(cnn_model.output.shape) 
predictor_model.load_weights('/tmp/cnn_model.h5', by_name=True) 
+0

Ja .... Bisher ist dies die einzige Lösung, die ich für diesen Fall gefunden habe, nämlich den relevanten Teil des Modells genau zu rekonstruieren. –

+0

Ja, ich habe auch den Prädiktor neu erstellt und Gewichte geladen. 'by_name' ist nützlich. Aber ich denke, es muss ein sauberer sein Lösung: Ich akzeptiere die Antwort, wenn wir nicht bald die bessere finden. – eclique

0

Es hängt davon ab, was Sie tun möchten.

  • Wenn Sie sich danach Merkmalsausleser wegzuwerfen
  • Wenn Sie auf die Ausbildung der Feature-Extraktor später

planen Wenn Sie die extrahierten Merkmale verwenden wollen, aber sie haben nicht die Absicht das Modell auf die Ausbildung verwendet, um sie zu erzeugen, könnte man die Methode vorherzusagen, verwenden Sie die Funktion nutzen zu können, wie Sie tat:

features = extractor.predict(X) 

dann seine Ausgabe in eine Datei (np.save speichern oder cPickle oder was auch immer). Danach können Sie dieses neue Dataset als Eingabe für ein neues Modell verwenden.

Wenn Sie auf die Ausbildung der Feature-Extraktor erst später müssen Sie die beiden Netzwerke stapeln, wie mit vgg als Feature-Extraktor hier gesehen https://github.com/fchollet/keras/issues/4576:

img_width, img_height = 150, 150 
vgg16_model = VGG16(include_top=False, weights='imagenet') 

input = Input(batch_shape=vgg16_model.output_shape) 
x = GlobalAveragePooling2D()(input) 
x = Dense(256, activation='relu')(x) 
x = Dropout(0.5)(x) 
predict = Dense(1, activation='sigmoid')(x) 
top_model = Model(input, predict) 

top_model.load_weights(os.path.join(data_path, 'VGG16Classifier.hdf5')) 

input = Input(shape=(3, img_width, img_height)) 
x = vgg16_model(input) 
predict = top_model(x) 
model = Model(input, predict) 

PS: In diesem Beispiel wird Kanäle erste Bestellung. Wenn Sie verwenden tensorflow Sie die Form ändern sollte formen = (img_width, img_height, 3)

+0

Ich denke, ich kann die Lösung in dem Code sehen, den Sie zur Verfügung gestellt haben. Ich werde es später testen können. Aber das Hauptproblem ist im Prädiktor, nicht Extraktor. Meintest du Prädiktor? Ich werde den Extraktor wegwerfen und nur feste Gewichte in Prädiktor verwenden (ohne es zu trainieren). – eclique

+0

Wenn Sie den Extraktor wegwerfen, ist es einfach, holen Sie sich einfach die Ausgabedaten aus dem Modell. Wenn ich "vorhersagen" sage, benutze ich den extractor.predict, um seine Ausgabe zu erhalten. Nach dieser Ausgabe sind Sie grundsätzlich mit einem neuen Datensatz wie jeder andere.Erstellen Sie Ihr symbolisches Modell mit keras/Tensorflow und übergeben Sie die Daten in der Fit-Methode des Modells, als wäre es irgendein anderer Datensatz mit einem Map-Vektor-> label – maz

+1

Ich lade die Features von extractor.predict (X) wie alle anderen Daten. Das Problem besteht darin, das ** symbolische Modell des Prädiktors ** mit den trainierten Gewichten zu erhalten. Leider löst Ihre Antwort dieses Problem nicht. :( – eclique

Verwandte Themen