【问题标题】:keras.models.load_model() gives ValueErrorkeras.models.load_model() 给出 ValueError
【发布时间】:2021-07-20 22:58:57
【问题描述】:

我已经保存了训练好的模型和权重如下。

model, history, score = fit_model(model, train_batches, val_batches, callbacks=[callback])
model.save('./model')
model.save_weights('./weights')

然后我尝试通过以下方式获取保存的模型

if __name__ == '__main__':
  model = keras.models.load_model('./model', compile= False,custom_objects={"F1Score": tfa.metrics.F1Score})
  test_batches, nb_samples = test_gen(dataset_test_path, 32, img_width, img_height)
  predict, loss, acc = predict_model(model,test_batches, nb_samples)
  print(predict)
  print(acc)
  print(loss)

但它给了我一个错误。我应该怎么做才能克服这个问题?

Traceback (most recent call last):
  File "test_pro.py", line 34, in <module>
    model = keras.models.load_model('./model',compile= False,custom_objects={"F1Score": tfa.metrics.F1Score})
  File "/home/dcs2016csc007/.local/lib/python3.8/site-packages/tensorflow/python/keras/saving/save.py", line 212, in load_model
    return saved_model_load.load(filepath, compile, options)
  File "/home/dcs2016csc007/.local/lib/python3.8/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 138, in load
    keras_loader.load_layers()
  File "/home/dcs2016csc007/.local/lib/python3.8/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 379, in load_layers
    self.loaded_nodes[node_metadata.node_id] = self._load_layer(
  File "/home/dcs2016csc007/.local/lib/python3.8/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 407, in _load_layer
    obj, setter = revive_custom_object(identifier, metadata)
  File "/home/dcs2016csc007/.local/lib/python3.8/site-packages/tensorflow/python/keras/saving/saved_model/load.py", line 921, in revive_custom_object
    raise ValueError('Unable to restore custom object of type {} currently. '
ValueError: Unable to restore custom object of type _tf_keras_metric currently. Please make sure that the layer implements `get_config`and `from_config` when saving. In addition, please use the `custom_objects` arg when calling `load_model()`.

【问题讨论】:

    标签: tensorflow keras deep-learning conv-neural-network mobilenet


    【解决方案1】:

    查看Keras的源码,报错when trying to load a model with a custom object

    def revive_custom_object(identifier, metadata):
      """Revives object from SavedModel."""
      if ops.executing_eagerly_outside_functions():
        model_class = training_lib.Model
      else:
        model_class = training_lib_v1.Model
    
      revived_classes = {
          constants.INPUT_LAYER_IDENTIFIER: (
              RevivedInputLayer, input_layer.InputLayer),
          constants.LAYER_IDENTIFIER: (RevivedLayer, base_layer.Layer),
          constants.MODEL_IDENTIFIER: (RevivedNetwork, model_class),
          constants.NETWORK_IDENTIFIER: (RevivedNetwork, functional_lib.Functional),
          constants.SEQUENTIAL_IDENTIFIER: (RevivedNetwork, models_lib.Sequential),
      }
      parent_classes = revived_classes.get(identifier, None)
    
      if parent_classes is not None:
        parent_classes = revived_classes[identifier]
        revived_cls = type(
            compat.as_str(metadata['class_name']), parent_classes, {})
        return revived_cls._init_from_metadata(metadata)  # pylint: disable=protected-access
      else:
        raise ValueError('Unable to restore custom object of type {} currently. '
                         'Please make sure that the layer implements `get_config`'
                         'and `from_config` when saving. In addition, please use '
                         'the `custom_objects` arg when calling `load_model()`.'
                         .format(identifier))
    

    该方法仅适用于revived_classes 中定义的类型的自定义对象。如您所见,它目前仅适用于输入层、层、模型、网络和顺序自定义对象。

    在您的代码中,您在 custom_objects 参数中传递了一个 tfa.metrics.F1Score 类,它的类型为 METRIC_IDENTIFIER,因此不受支持(可能是因为它没有实现 get_configfrom_config 函数正如错误输出所说):

    keras.models.load_model('./model', compile=False, custom_objects={"F1Score": tfa.metrics.F1Score})
    

    自从我上次使用 Keras 已经有一段时间了,但也许您可以尝试遵循 this other related answer 中提出的建议,并将对 tfa.metrics.F1Score 的调用封装在一个方法中。像这样的东西(根据您的需要调整):

    def f1(y_true, y_pred):
        metric = tfa.metrics.F1Score(num_classes=3, threshold=0.5)
        metric.update_state(y_true, y_pred)
        return metric.result()
    
    keras.models.load_model('./model', compile=False, custom_objects={'f1': f1})
    

    【讨论】:

    • 感谢您的回答。我升级了我的 tensorflow 和 tensorflow_addons,然后尝试了这个。有效。谢谢你。但是现在它在加载模型时说另一个错误。你知道吗??stackoverflow.com/questions/67287768/…
    • 我使用了多头注意力机制,所以代码包含批量矩阵乘法。@Matheus Portela 有没有什么具体的方法来保存和加载这样的模型?
    猜你喜欢
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 2022-08-21
    • 1970-01-01
    • 2018-08-25
    • 2020-11-17
    • 2019-04-22
    相关资源
    最近更新 更多