如何从 .h5 文件正确加载带有自定义层的 Keras 模型?
How to load the Keras model with custom layers from .h5 file correctly?
我构建了一个带有自定义层的 Keras 模型,并通过回调 ModelCheckPoint
将其保存到 .h5
文件中。
当我在训练后尝试加载此模型时,出现以下错误消息:
__init__() missing 1 required positional argument: 'pool_size'
这是自定义层的定义及其__init__
方法:
class MyMeanPooling(Layer):
def __init__(self, pool_size, axis=1, **kwargs):
self.supports_masking = True
self.pool_size = pool_size
self.axis = axis
self.y_shape = None
self.y_mask = None
super(MyMeanPooling, self).__init__(**kwargs)
这就是我将这一层添加到我的模型中的方式:
x = MyMeanPooling(globalvars.pool_size)(x)
这是我加载模型的方式:
from keras.models import load_model
model = load_model(model_path, custom_objects={'MyMeanPooling': MyMeanPooling})
这些是完整的错误信息:
Traceback (most recent call last):
File "D:/My Projects/Attention_BLSTM/script3.py", line 9, in <module>
model = load_model(model_path, custom_objects={'MyMeanPooling': MyMeanPooling})
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py", line 419, in load_model
model = _deserialize_model(f, custom_objects, compile)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py", line 225, in _deserialize_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py", line 458, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\layers\__init__.py", line 55, in deserialize
printable_module_name='layer')
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\utils\generic_utils.py", line 145, in deserialize_keras_object
list(custom_objects.items())))
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\network.py", line 1022, in from_config
process_layer(layer_data)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\network.py", line 1008, in process_layer
custom_objects=custom_objects)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\layers\__init__.py", line 55, in deserialize
printable_module_name='layer')
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\utils\generic_utils.py", line 147, in deserialize_keras_object
return cls.from_config(config['config'])
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\base_layer.py", line 1109, in from_config
return cls(**config)
TypeError: __init__() missing 1 required positional argument: 'pool_size'
来自 "LiamHe commented on Sep 27, 2017" 对以下问题的回答:https://github.com/keras-team/keras/issues/4871。
我今天遇到了同样的问题:**类型错误:init() 缺少 1 个必需的位置参数**。这是我解决问题的方法:(Keras 2.0.2)
- 为层的位置参数提供一些默认值
- 用
之类的东西覆盖层的get_config函数
def get_config(self):
config = super().get_config()
config['pool_size'] = # say self._pool_size if you store the argument in __init__
return config
- 加载模型时将图层 class 添加到 custom_objects。
其实我不认为你可以加载这个模型。
最有可能的问题是您没有在层中实现 get_config()
方法。此方法 returns 应保存的配置值字典:
def get_config(self):
config = {'pool_size': self.pool_size,
'axis': self.axis}
base_config = super(MyMeanPooling, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
将此方法添加到图层后,您必须重新训练模型,因为之前保存的模型没有保存此图层的配置。这就是为什么你不能加载它的原因,它需要在进行此更改后重新训练。
如果您没有足够的时间以 Matias Valdenegro 的解决方案方式重新训练模型。可以在classMyMeanPooling中设置pool_size的默认值,如下代码。注意pool_size的值要和训练模型时的值保持一致。然后就可以加载模型了。
class MyMeanPooling(Layer):
def __init__(self, pool_size, axis=1, **kwargs):
self.supports_masking = True
self.pool_size = 2 # The value should be consistent with the value while training the model
self.axis = axis
self.y_shape = None
self.y_mask = None
super(MyMeanPooling, self).__init__(**kwargs)
我构建了一个带有自定义层的 Keras 模型,并通过回调 ModelCheckPoint
将其保存到 .h5
文件中。
当我在训练后尝试加载此模型时,出现以下错误消息:
__init__() missing 1 required positional argument: 'pool_size'
这是自定义层的定义及其__init__
方法:
class MyMeanPooling(Layer):
def __init__(self, pool_size, axis=1, **kwargs):
self.supports_masking = True
self.pool_size = pool_size
self.axis = axis
self.y_shape = None
self.y_mask = None
super(MyMeanPooling, self).__init__(**kwargs)
这就是我将这一层添加到我的模型中的方式:
x = MyMeanPooling(globalvars.pool_size)(x)
这是我加载模型的方式:
from keras.models import load_model
model = load_model(model_path, custom_objects={'MyMeanPooling': MyMeanPooling})
这些是完整的错误信息:
Traceback (most recent call last):
File "D:/My Projects/Attention_BLSTM/script3.py", line 9, in <module>
model = load_model(model_path, custom_objects={'MyMeanPooling': MyMeanPooling})
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py", line 419, in load_model
model = _deserialize_model(f, custom_objects, compile)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py", line 225, in _deserialize_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py", line 458, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\layers\__init__.py", line 55, in deserialize
printable_module_name='layer')
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\utils\generic_utils.py", line 145, in deserialize_keras_object
list(custom_objects.items())))
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\network.py", line 1022, in from_config
process_layer(layer_data)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\network.py", line 1008, in process_layer
custom_objects=custom_objects)
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\layers\__init__.py", line 55, in deserialize
printable_module_name='layer')
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\utils\generic_utils.py", line 147, in deserialize_keras_object
return cls.from_config(config['config'])
File "D:\ProgramData\Anaconda3\envs\tf\lib\site-packages\keras\engine\base_layer.py", line 1109, in from_config
return cls(**config)
TypeError: __init__() missing 1 required positional argument: 'pool_size'
来自 "LiamHe commented on Sep 27, 2017" 对以下问题的回答:https://github.com/keras-team/keras/issues/4871。
我今天遇到了同样的问题:**类型错误:init() 缺少 1 个必需的位置参数**。这是我解决问题的方法:(Keras 2.0.2)
- 为层的位置参数提供一些默认值
- 用 之类的东西覆盖层的get_config函数
def get_config(self):
config = super().get_config()
config['pool_size'] = # say self._pool_size if you store the argument in __init__
return config
- 加载模型时将图层 class 添加到 custom_objects。
其实我不认为你可以加载这个模型。
最有可能的问题是您没有在层中实现 get_config()
方法。此方法 returns 应保存的配置值字典:
def get_config(self):
config = {'pool_size': self.pool_size,
'axis': self.axis}
base_config = super(MyMeanPooling, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
将此方法添加到图层后,您必须重新训练模型,因为之前保存的模型没有保存此图层的配置。这就是为什么你不能加载它的原因,它需要在进行此更改后重新训练。
如果您没有足够的时间以 Matias Valdenegro 的解决方案方式重新训练模型。可以在classMyMeanPooling中设置pool_size的默认值,如下代码。注意pool_size的值要和训练模型时的值保持一致。然后就可以加载模型了。
class MyMeanPooling(Layer):
def __init__(self, pool_size, axis=1, **kwargs):
self.supports_masking = True
self.pool_size = 2 # The value should be consistent with the value while training the model
self.axis = axis
self.y_shape = None
self.y_mask = None
super(MyMeanPooling, self).__init__(**kwargs)