ValueError:未知层:CapsuleLayer

Sou*_*Ray 6 python keras keras-layer

我定义了一个名为的自定义图层CapsuleLayer。实际模型已在单独的类中定义。我已将权重加载到实际模型中,并将模型保存在.h5文件中。但是,当我尝试使用加载模型时load_model(filepath),出现错误

ValueError:未知层:CapsuleLayer

加载保存的模型时,如何将自定义图层合并到模型中。

ben*_*che 9

参见Keras常见问题,“在已保存的模型中处理自定义图层(或其他自定义对象)”

如果要加载的模型包括自定义图层或其他自定义类或函数,则可以通过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})
Run Code Online (Sandbox Code Playgroud)

另外,您可以使用自定义对象范围:

from keras.utils import CustomObjectScope

with CustomObjectScope({'AttentionLayer': AttentionLayer}):
    model = load_model('my_model.h5')
Run Code Online (Sandbox Code Playgroud)

自定义对象处理对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})
Run Code Online (Sandbox Code Playgroud)

就您而言,model = load_model('my_model.h5', custom_objects={'CapsuleLayer': CapsuleLayer})应该解决您的问题。


JVG*_*VGD 5

为了完整起见,我仅在本杰明普朗什的答案之上添加了一点。如果您的自定义层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
Run Code Online (Sandbox Code Playgroud)

这将加载本杰明普朗什的回答中详述的任何方法,即使用custom_objects={'AttentionLayer': AttentionLayer}. 但是,如果您的图层有一些参数,则加载将失败。

想象一下你的类的 init 方法有 2 个参数:

class AttentionLayer(Layer):
    def __init__(self, param1, param2, **kwargs):
        self.param1 = param1
        self.param2 = param2
        super().__init__(**kwargs)
Run Code Online (Sandbox Code Playgroud)

然后,当您加载它时:

model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})
Run Code Online (Sandbox Code Playgroud)

它会抛出这个错误:

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'
Run Code Online (Sandbox Code Playgroud)

为了解决它,您需要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['param1'] = self.param1
        config['param2'] = self.param2
        return config
Run Code Online (Sandbox Code Playgroud)

因此,当您保存模型时,保存例程将调用 get_config 并将序列化您的自定义层的内部状态,即self.params. 当你加载它时,加载器将知道如何初始化你的自定义层的内部状态。