在Keras中保存和加载Tensorflow模型结果出现错误

3

我正在处理的一个项目中,我在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'

浏览一下,我怀疑这与load_model函数的custom_objects标签有关,但我不确定如何实现它。

我可能使用的唯一自定义对象是我的损失函数,如下所述,以及我使用的accuracy指标。

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


你需要包含完整的回溯信息,只有错误/异常本身并不是很有用。 - Dr. Snoopy
@Dr.Snoopy 对不起,我添加了完整的回溯信息。 - Aaron Jones
2个回答

2

在进一步查看并研究了一些Github问题后,我相信我已经找到了解决问题的方法。对于我的特定情况,我不需要保存整个模型,而只需要保存权重。我使用的配置是Tensorflow 2.3.0和Keras 2.4.3。

简短回答:

至少训练模型一个epoch,然后加载权重。

详细回答:

为了保存权重,我使用以下函数,并将其附加到我的模型文件路径上。

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

我从这一行这里找到了答案,但底部说要在加载权重之前为模型适合一个时期。
history = model.fit(test_data, batch_size=1, epochs=1)

之后,您应该能够使用以下函数成功加载权重。
model.load_weights(model_path)

0
假设你的“arguments”是一个你创建的feature_columns列表。 假设你没有创建任何自定义的训练对象。
使用TF格式保存模型。
这在TF 2.3版本中经过测试。
model.save("./my_model/",save_format="tf")

加载模型:

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

我已经尝试了你上面的代码,但仍然遇到相同的错误。我能想到可能使用的唯一自定义对象是 loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),并且在编译模型时,我使用 accuracy 作为度量指标。 - Aaron Jones
你能分享一个独立的代码来重现这个错误吗?同时也请分享你使用的Python和TensorFlow版本。因为你提到的两个对象都是由TensorFlow提供并且可序列化的。 - Aniket Bote

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接