Modell einfrieren und trainieren
Ich benutze Keras Tensorflow in Colab. Ich passe ein Modell an und speichere es. Dann lade ich es und überprüfe die Leistung und natürlich sollte es das gleiche sein. Dann friere ich es ein und passe es wieder an. Ich würde erwarten, dass das Modell danach die gleiche Leistung hat. Natürlich kann es während des "Trainings" aufgrund von Unterschieden in der Chargengröße zu Unterschieden in der Genauigkeit kommen. Aber später, wenn ich es mit model.evaluate überprüfe, würde ich keine Unterschiede erwarten, da die Gewichte nicht geändert werden können, da das Modell eingefroren wurde. Es stellt sich jedoch heraus, dass dies nicht der Fall ist.
Mein Code:
import csv
import tensorflow as tf
import tensorflow_datasets as tfds
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
(train_x, train_labels), (test_x, test_labels) = tf.keras.datasets.imdb.load_data(num_words=10000)
x_train_padded = pad_sequences(train_x, maxlen=500)
x_test_padded = pad_sequences(test_x, maxlen=500)
model = tf.keras.Sequential([
tf.keras.layers.Embedding(10000, 128, input_length=500),
tf.keras.layers.Conv1D(128, 5, activation='relu'),
tf.keras.layers.GlobalAveragePooling1D(),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1)
])
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),optimizer='adam', metrics=[tf.metrics.BinaryAccuracy(threshold=0.0, name='accuracy')])
history = model.fit(x=x_train_padded,
y=train_labels,
validation_data=(x_test_padded , test_labels),
epochs=4, batch_size=128)
gibt die Ausgabe:
Ich speichere das Modell:
model.save('test.h5')
und lade es zurück:
modelloaded=tf.keras.models.load_model('test.h5')
und überprüfen Sie die Leistung:
modelloaded.evaluate(x_test_padded , test_labels)
natürlich immer noch das gleiche:
Jetzt habe ich das Modell auf nicht trainierbar gesetzt:
modelloaded.trainable=False
und in der Tat:
modelloaded.summary()
zeigt, dass alle Parameter nicht trainierbar sind:
Jetzt passe ich es wieder mit nur einer Epoche an:
history = modelloaded.fit(x=x_train_padded,
y=train_labels,
validation_data=(x_test_padded , test_labels),
epochs=1, batch_size=128)
Ich verstehe, dass sich die Genauigkeit ändert, obwohl die Gewichte nicht trainierbar sind, da dies von der Chargengröße abhängt.
Wenn ich das Modell danach jedoch überprüfe mit:
modelloaded.evaluate(x_test_padded , test_labels)
Kann ich sehen, dass das Modell geändert wurde? Der Verlust und die Genauigkeit sind unterschiedlich. Ich verstehe nicht warum, ich hätte die gleichen Zahlen erwartet. Da das Modell nicht trainiert werden kann. Es spielt keine Rolle, ob ich es mit verschiedenen Chargengrößen nenne:
modelloaded.evaluate(x_test_padded , test_labels, batch_size=16)
Die Nummern sind immer gleich, unterscheiden sich jedoch von denen vor der Modellanpassung.
Bearbeiten:
Ich habe folgendes versucht:
modelloaded=tf.keras.models.load_model('test.h5')
modelloaded.trainable=False
for layer in modelloaded.layers:
layer.trainable=False
history = modelloaded.fit(x=x_train_padded,
y=train_labels,
validation_data=(x_test_padded , test_labels),
epochs=1, batch_size=128)
modelloaded.evaluate(x_test_padded, test_labels)
Trotzdem werden die Gewichte angepasst (ich habe dies mit Vergleichen print(modelloaded.trainable_variables)vor und nach dem Vergleichen überprüft ) und die Ausgabe von modelloaded.evaluate liefert leicht unterschiedliche Ergebnisse, bei denen ich keine Änderungen erwarten würde. Da sollten sich die Modellgewichte nicht geändert haben. Aber sie haben es getan, wie ich bei der Überprüfung sehen kann print(modelloaded.trainable_variables).
Antworten
Dies scheint ein größeres Problem zu sein , das diskutiert wird hier . Das explizite Festlegen aller Ebenen, die nicht trainierbar sind, sollte funktionieren:
for layer in modelloaded.layers:
layer.trainable = False
Mein Fehler war, dass ich das Modell nicht erneut kompiliert habe, nachdem ich es auf nicht trainierbar gesetzt hatte.
Sie müssen das Modell kompilieren, bevor Sie es erneut anpassen können. Andernfalls übernimmt die Funktionsanpassung Ihre neueste Kompilierungskonfiguration ...