1

Ich möchte mit Keras ein neuronales Netzwerk kodieren, das sowohl als Auto-Encoder als auch als Klassifikator für semi-überwachtes Lernen fungiert. Nehmen Sie zum Beispiel diesen Datensatz, wo es ein paar beschriftete Bilder und viele unmarkierte Bilder gibt: https://cs.stanford.edu/~acoates/stl10/Keras: Modell mit einem Eingang und zwei Ausgängen, gemeinsam trainiert auf verschiedenen Daten (semi-überwachtes Lernen)

Einige Papiere aufgeführt here erreicht, dass oder sehr ähnliche Dinge, erfolgreich.

Zusammenfassend: Wenn das Modell die gleiche Eingabedatenform und die gleichen "kodierenden" Faltungsschichten hätte, aber sich in zwei Köpfe teilen würde (Gabel-Stil), so gibt es einen Klassifizierungskopf und einen Dekodierkopf, in einer Weise, dass der unbeaufsichtigte Autoencoder zu einem guten Lernen für den Klassifikationskopf beiträgt.

Mit TensorFlow wäre das kein Problem, da wir die volle Kontrolle über den Computergraph haben.

Aber mit Keras, Dinge sind mehr High-Level und ich fühle, dass alle Anrufe zu ".fit" müssen immer alle Daten auf einmal (so würde es mich zwingen, zusammen den Klassifikations-Kopf und die Autoencodierungs-Kopf in einen Zeitschritt).

Eine Möglichkeit, in keras fast, dass mit etwas wäre zu tun, das so geht:

input = Input(shape=(32, 32, 3)) 
cnn_feature_map = sequential_cnn_trunk(input) 

classification_predictions = Dense(10, activation='sigmoid')(cnn_feature_map) 

autoencoded_predictions = decode_cnn_head_sequential(cnn_feature_map) 

model = Model(inputs=[input], outputs=[classification_predictions, ]) 

model.compile(optimizer='rmsprop', 
       loss='binary_crossentropy', 
       metrics=['accuracy']) 
model.fit([images], [labels, images], epochs=10) 

Aber ich denke, und ich fürchte, wenn ich will nur Dinge passen auf diese Weise wird es scheitern und frage nach dem fehlenden Kopf:

for epoch in range(10): 
    # classifications step 
    model.fit([images], [labels, None], epochs=1) 
    # "semi-unsupervised" autoencoding step 
    model.fit([images], [None, images], epochs=1) 
    # note: ".train_on_batch" could probably be used rather than ".fit" to avoid doing a whole epoch each time. 

Wie soll man dieses Verhalten mit Keras umsetzen? Und könnte das Training gemeinsam durchgeführt werden, ohne die beiden Anrufe auf die Funktion ".fit" aufteilen zu müssen?

Antwort

0

Sie können gemeinsam trainieren, müssen Sie ein Array statt Single-Label übergeben.

Ich verwendete fit_generator, z.B.

+0

Das Problem, das ich ist Sie haben nicht gleichzeitig Zugriff auf die beiden Labels. Zum Beispiel habe ich mit einem X nur Y_1 und für ein anderes X habe ich sowohl Y_1 als auch Y_2. Aber die Sache ist, ich kann nicht immer die beiden Ausgänge auf einmal geben. Jedenfalls, wenn ich das vorhabe, wird es am Ende mit einer anderen Bibliothek sein. –

+0

jetzt sehe ich yout Problem, dont worry Ich habe auch eine (eigene) Lösung für diese :) Sie benötigen eine benutzerdefinierte to_categorical und eine benutzerdefinierte Genauigkeitsfunktion. Morgen poste ich eine ausführliche Antwort, die Hauptidee ist, dass, wenn Sie nicht Aufkleber haben, Sie Nullvektor von einem heißen Vektor übergeben sollten. In diesem Fall haben Sie kein Fehlersignal, und das ist es. –

1

Manchmal, wenn Sie keine Beschriftung haben, können Sie Null-Vektor anstelle von einem heiß codierten Vektor übergeben. Es sollte Ihr Ergebnis nicht ändern, weil Nullvektor kein Fehlersignal mit kategorischem Kreuzentropieverlust hat.

Meine benutzerdefinierte to_categorical Funktion sieht wie folgt aus:

def tricky_to_categorical(y, translator_dict): 
    encoded = np.zeros((y.shape[0], len(translator_dict))) 
    for i in range(y.shape[0]): 
     if y[i] in translator_dict: 
      encoded[i][translator_dict[y[i]]] = 1 
    return encoded 

Wenn y Etiketten enthält, und translator_dict ist ein Python-Wörterbuch Hexe enthält Etiketten und seiner einzigartigen Schlüssel wie folgt aus:

{'unisex':2, 'female': 1, 'male': 0}

Wenn ein UNK-Etikett kann in diesem Diktat nicht gefunden werden, dann ist sein codiertes Etikett ein Nullvektor

Wenn Mit diesem Trick müssen Sie auch Ihre Genauigkeitsfunktion ändern, um echte Genauigkeitszahlen zu sehen. Sie müssen alle Nullvektoren aus unseren Metriken herausfiltern

def tricky_accuracy(y_true, y_pred): 
    mask = K.not_equal(K.sum(y_true, axis=-1), K.constant(0)) # zero vector mask 
    y_true = tf.boolean_mask(y_true, mask) 
    y_pred = tf.boolean_mask(y_pred, mask) 
    return K.cast(K.equal(K.argmax(y_true, axis=-1), K.argmax(y_pred, axis=-1)), K.floatx()) 

Hinweis: Sie müssen größere Chargen (z.32), um Nullmatrix Update zu verhindern, weil es Ihre Genauigkeit Metriken verrückt machen kann, ich weiß nicht, warum

Alternative Lösung

Verwenden Pseudo Kennzeichnung :)

+0

Ich verstehe nicht, was du unten meinst (etwa Chargen). Wollen Sie damit sagen, dass in einem bestimmten Batch jeder Artikel unmarkiert sein muss (0 Maske) oder alle Artikel im Batch mit einem Label versehen sein müssen? –

+0

Einige "einheiß" codierte Labels können Nullvektoren sein (weil wir das richtige Label nicht kennen). Wir wollen kein Update, bei dem alle Labels Nullvektoren in einem Batch (0 Matrix) sind, weil ich nicht weiß, warum es in Keras zu einigen Metrikenproblemen kommen kann. Mindestens eines der Labels muss Informationen enthalten, es sollte kein Nullvektor sein –

Verwandte Themen