保存和加载Tensorflow模型导致Keras错误

时间:2020-08-20 13:35:29

标签: python tensorflow keras

对于我正在从事的项目,我已经在TensorFlow中创建了一个简单的模型,该模型由一个密集要素层和三个密集层组成。

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

我无法详细介绍参数arguments,但是上述模型函数可以很好地工作,并且可以使用下面的代码很好地训练和保存.h5文件。

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

# Save the model
model.save(model_dir)

但是,当我尝试从.h5文件中加载模型时,

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

我收到以下错误消息。

  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'

环顾四周,我怀疑它与custom_objects函数的load_model标签有关,但是我不确定100%如何实现它。

我唯一可以使用的自定义对象是我在下面声明的损失以及我使用的accuracy指标。

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

2 个答案:

答案 0 :(得分:0)

假设您的“参数”是您创建的feature_columns的列表。 假设您尚未创建任何自定义训练对象。
使用TF格式保存模型。
已针对TF 2.3进行了测试

model.save("./my_model/",save_format="tf")

对于加载模型:

model2 = tf.keras.models.load_model('/content/my_model')

答案 1 :(得分:0)

在仔细研究了一些Github问题之后,我相信我已经解决了这个问题。对于我的特定情况,我不需要保存整个模型,而不仅仅是保存权重。对于我的配置,我使用的是Tensorflow 2.3.0和Keras 2.4.3。

短答案:

让模型至少适应一个时期,然后加载权重。

长答案:

为保存权重,我使用以下函数,并在其上方添加了模型文件路径。

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

# Save the model
model.save_weights(model_dir)

我首先根据上面的问题构建模型并将其存储在模型对象中

model = build_model(arguments)

我添加了损失函数和优化器,然后在加载权重之前编译模型以确保其具有所有相关功能。

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'])

我从这一行here找到了答案,但是在最底部,它说要在加载权重之前将模型拟合1个纪元。

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

然后,您应该可以使用下面的功能来加载砝码。

model.load_weights(model_path)