我已经定义了一个名为CapsuleLayer
的自定义图层。实际模型已在单独的类中定义。我已将权重加载到实际模型中,并将模型保存在.h5
文件中。但是,当我尝试使用load_model(filepath)
加载模型时,我收到错误
ValueError:未知图层:CapsuleLayer
如何在加载保存的模型时将自定义图层合并到我的模型中。
答案 0 :(得分:6)
C.f。 Keras常见问题,"Handling custom layers (or other custom objects) in saved models":
如果要加载的模型包括自定义图层或其他自定义 类或函数,您可以通过它们将它们传递给加载机制 custom_objects参数:
from keras.models import load_model # Assuming your model includes instance of an "AttentionLayer" class model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})
或者,您可以使用自定义对象范围:
from keras.utils import CustomObjectScope with CustomObjectScope({'AttentionLayer': AttentionLayer}): model = load_model('my_model.h5')
自定义对象处理对load_model的工作方式相同, model_from_json,model_from_yaml:
from keras.models import model_from_json model = model_from_json(json_string, custom_objects={'AttentionLayer': AttentionLayer})
在您的情况下,model = load_model('my_model.h5', custom_objects={'CapsuleLayer': CapsuleLayer})
应解决您的问题。
答案 1 :(得分:0)
为了完整起见,我仅在benjaminplanche的答案上添加一点。如果自定义层AttentionLayer
具有配置其行为的任何初始参数,则需要实现类的get_config
方法。否则它将无法加载。我写这篇文章是因为我在如何使用参数加载自定义层时遇到了很多麻烦,所以我将其留在这里。
例如,您的图层的虚拟实现:
class AttentionLayer(Layer):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self, input_shape):
return super().build(input_shape)
def call(self, x):
# Implementation about how to look with attention!
return x
def compute_output_shape(self, input_shape):
return input_shape
这将使用benjaminplanche答案中详述的任何方法,即使用custom_objects={'AttentionLayer': AttentionLayer}
。但是,如果您的图层有一些参数,则加载将失败。
想象一下您的类的init方法有2个参数:
class AttentionLayer(Layer):
def __init__(self, param1, param2, **kwargs):
self.param1 = param1
self.param2 = param2
super().__init__(**kwargs)
然后,当您加载时:
model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})
它将引发此错误:
Traceback (most recent call last):
File "/path/to/file/cstm_layer.py", line 62, in <module>
h = AttentionLayer()(x)
TypeError: __init__() missing 2 required positional arguments: 'param1' and 'param2'
要解决此问题,您需要在自定义图层类中实现get_config
方法。一个例子:
class AttentionLayer(Layer):
def __init__(self, param1, param2, **kwargs):
self.param1 = param1
self.param2 = param2
super().__init__(**kwargs)
# ...
def get_config(self):
# For serialization with 'custom_objects'
config = super().get_config()
config['idx_init'] = self.idx_init
config['idx_end'] = self.idx_end
return config
因此,当您保存模型时,保存例程将调用get_config并将序列化自定义层的内部状态,即self.params
。当您加载它时,加载器将知道如何初始化自定义层的内部状态。