Tensorflow 2.2.0 和 Keras 保存模型/加载模型问题

Tensorflow 2.2.0 and Keras save model / load model problems

在我的 keras DQN 添加自定义损失函数 @tf.function 后,keras 模型停止加载(似乎保存模型,但无法重新加载模型)。文档表明这非常简单,但是...

各种 SO 答案表明使用一个 Keras 版本训练的模型无法加载到其他 Keras 版本中。所以我卸载了 Keras 2.4.3(来自 Anaconda env),以避免任何混淆,并尝试使用 Tensorflow-keras 单独建模和 save/load。

所以,现在尝试保存一个 Tensorflow-keras 模型,然后再次加载该模型,但不会重新加载,各种错误(如下)。环境是Anaconda3 python3.8(带Keras 2.4.3,后来卸载了这个)和Tensorflow 2.2.0(含Keras 2.3.0-tf).

是否有一些解决方案可以简单地保存模型然后在 tf 2.2.0(使用 keras 2.3.0-tf)中重新加载模型?

import tensorflow as tf
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Dense,  LSTM, Masking, Input
from tensorflow.keras.optimizers import Adam

然后所有 tf.keras 建模和保存/加载应该由 Keras-2.3.0-tf 在 Tensorflow 中完成。模型保存完成:

agent.model.save(os.path.join(pathOUT, PAIR, 'models' + modelNum, modelFolder), 
save_format='tf')

但在保存期间生成弃用警告:

2020-11-26 00:19:03.388858: W tensorflow/python/util/util.cc:329] Sets are not currently 
considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:tensorflow:From C:\..mypath......\lib\site- 
packages\tensorflow\python\ops\resource_variable_ops.py:1813: calling 
BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with 
constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
Saved an Intermediate model...

然后尝试加载模型:

model = load_model(LOAD_MODEL)

但在加载过程中产生错误:

TypeError: __init__() got an unexpected keyword argument 'reduction'

同样,是否有一些解决方案可以简单地保存模型然后在 tf 2.2.0(使用 keras 2.3.0-tf)中重新加载模型?

完整错误:

Traceback (most recent call last):
File mypath, line 851, in <module>
  agent = DQNAgent()   
File mypath, line 266, in __init__
  self.model = self.create_model()
File mypath, line 336, in create_model
  model = load_model(LOAD_MODEL)
File mypath\lib\site-packages\tensorflow\python\keras\saving\save.py", line 190, in load_model
  return saved_model_load.load(filepath, compile)
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 116, 
  in load
  model = tf_load.load_internal(path, loader_cls=KerasObjectLoader)
File mypath\lib\site-packages\tensorflow\python\saved_model\load.py", line 602, in 
  load_internal
  loader = loader_cls(object_graph_proto,
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 188, 
  in __init__
  super(KerasObjectLoader, self).__init__(*args, **kwargs)
File mypath\lib\site-packages\tensorflow\python\saved_model\load.py", line 123, in __init__
  self._load_all()
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 209, 
   in _load_all
 self._layer_nodes = self._load_layers()
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 312, 
  in _load_layers
  layers[node_id] = self._load_layer(proto.user_object, node_id)
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 335, 
  in _load_layer
  obj, setter = self._revive_from_config(proto.identifier, metadata, node_id)
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 349, 
  in _revive_from_config
  obj = self._revive_metric_from_config(metadata, node_id)
File mypath\lib\site-packages\tensorflow\python\keras\saving\saved_model\load.py", line 441, 
  in _revive_metric_from_config
  obj = metrics.deserialize(
File mypath\lib\site-packages\tensorflow\python\keras\metrics.py", line 3345, in deserialize
  return deserialize_keras_object(
File mypath\lib\site-packages\tensorflow\python\keras\utils\generic_utils.py", line 361, in 
  deserialize_keras_object
  (cls, cls_config) = class_and_config_for_serialized_keras_object(
File mypath\lib\site-packages\tensorflow\python\keras\utils\generic_utils.py", line 327, in 
  class_and_config_for_serialized_keras_object
  deserialized_objects[key] = deserialize_keras_object(
File mypath\lib\site-packages\tensorflow\python\keras\utils\generic_utils.py", line 375, in 
  deserialize_keras_object
  return cls.from_config(cls_config)
File mypath\lib\site-packages\tensorflow\python\keras\metrics.py", line 628, in from_config
  return super(MeanMetricWrapper, cls).from_config(config)
File mypath\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 655, in 
  from_config
  return cls(**config)
TypeError: __init__() got an unexpected keyword argument 'reduction'

附加代码: 自定义损失函数(尝试通过 'flipping' 误差梯度实现梯度上升),已在不同位置(在与模型相同的代理 class 内,在代理 class 外部,其他。

@tf.function
def positive_mse(y_true, y_pred):
    return -1 * tf.keras.losses.MSE(y_true, y_pred)

我使用的顺序模型是

通过在原始模型的模型编译期间删除 MeanSquareError() 指标,使原始关键字参数 'reduction' 出现 resolved/bypassed 错误。原型号:

model.compile(loss=positive_mse,
              optimizer=Adam(lr=LEARNING_RATE, decay=DECAY),
              metrics=[tf.keras.losses.MeanSquaredError()])

来自 Keras 文档:“请注意,这是像 tf.keras.losses.mean_squared_error 这样的损失函数和像 tf.keras.losses.MeanSquaredError 这样的默认损失 class 实例之间的一个重要区别:函数版本不执行缩减,但默认情况下 class 实例执行。"

MeanSquaaredError 损失 class 函数在小批量损失评估期间传递 'reduction' 关键字。删除此指标允许重新加载模型而不会出错。