Il salvataggio e il caricamento del modello Tensorflow genera l'errore di Keras

Aug 20 2020

Per un progetto su cui sto lavorando, ho creato un semplice modello in TensorFlow che consiste in uno strato di elementi densi seguito da tre strati densi.

def build_model(arguments):
    model = tf.keras.Sequential([
        tf.keras.layers.DenseFeatures(arguments),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dense(5, activation='sigmoid')
    ])
    
    return model

Non sono in grado di entrare più in dettaglio sul parametro arguments, ma la funzione del modello sopra funziona perfettamente e può addestrare e salvare un .h5file perfettamente bene usando il codice qui sotto.

    # Create a path for the saving location of the model
    model_dir = log_dir + "\model.h5"

    # Save the model
    model.save(model_dir)

Tuttavia, quando provo a caricare nuovamente il modello dal .h5file,

model = tf.keras.models.load_model(model_path)

Ricevo il seguente messaggio di errore.

  File "sampleModel.py", line 342, in <module>
    model = tf.keras.models.load_model(model_path)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\saving\save.py", line 1
82, in load_model
    return hdf5_format.load_model_from_hdf5(filepath, custom_objects, c
ompile)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\saving\hdf5_format.py",
 line 178, in load_model_from_hdf5
    custom_objects=custom_objects)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\saving\model_config.py"
, line 55, in model_from_config
    return deserialize(config, custom_objects=custom_objects)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\layers\serialization.py
", line 175, in deserialize
    printable_module_name='layer')
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\utils\generic_utils.py"
, line 358, in deserialize_keras_object
    list(custom_objects.items())))
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\engine\sequential.py",
line 487, in from_config
    custom_objects=custom_objects)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\layers\serialization.py
", line 175, in deserialize
    printable_module_name='layer')
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\utils\generic_utils.py"
, line 358, in deserialize_keras_object
    list(custom_objects.items())))
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\keras\feature_column\base_fea
ture_layer.py", line 141, in from_config
    config['feature_columns'], custom_objects=custom_objects)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\feature_column\serialization.
py", line 186, in deserialize_feature_columns
    for c in configs
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\feature_column\serialization.
py", line 186, in <listcomp>
    for c in configs
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\feature_column\serialization.
py", line 138, in deserialize_feature_column
    columns_by_name=columns_by_name)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\feature_column\feature_column
_v2.py", line 2622, in from_config
    config['normalizer_fn'], custom_objects=custom_objects)
  File "C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Python
\Python37\site-packages\tensorflow\python\feature_column\serialization.
py", line 273, in _deserialize_keras_object
    obj = module_objects.get(object_name)
AttributeError: 'NoneType' object has no attribute 'get'

Guardandomi intorno, sospetto che abbia qualcosa a che fare con il custom_objectstag per la load_modelfunzione, ma non sono sicuro al 100% di come implementarlo.

Risposte

John Aug 21 2020 at 20:55

Prova questo collegamento https://github.com/keras-team/keras/issues/11418

C'è una risposta da ethanfowler che sembra risolvere il problema usando custom_objects

AaronJones Sep 05 2020 at 01:54

Dopo aver guardato un po 'di più e aver analizzato alcuni problemi di Github, credo di aver risolto il problema. Per la mia situazione specifica, non avevo bisogno di salvare l'intero modello, piuttosto che solo i pesi. Per la mia configurazione sto usando Tensorflow 2.3.0 e Keras 2.4.3.

RISPOSTA BREVE:

Adatta il tuo modello per almeno un'epoca, quindi carica i pesi.

RISPOSTA LUNGA:

Per salvare i pesi, utilizzo la seguente funzione aggiunta con il percorso del file del modello sopra di essa.

# Create a path for the saving location of the model
model_dir = dir_path + '/model.h5'

# Save the model
model.save_weights(model_dir)

Per prima cosa costruisco il mio modello dalla mia domanda sopra e lo memorizzo in un oggetto modello

model = build_model(arguments)

Aggiungo la mia funzione di perdita e ottimizzatore, quindi compilo il mio modello per assicurarmi che abbia tutte le funzionalità rilevanti prima di caricare i pesi.

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
    
#Declare and set the parametors of the optimizer
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, decay=0.001)
    
#Compile the model
model.compile(loss=loss_object, optimizer=optimizer, metrics=['accuracy'])

Ho trovato la mia risposta da questa riga qui , ma in fondo dice di adattarsi al modello per 1 epoca prima di caricare i pesi.

history = model.fit(test_data, batch_size=1, epochs=1)

Successivamente, dovresti essere in grado di caricare i pesi correttamente utilizzando la funzione di seguito.

model.load_weights(model_path)