在Keras中实现自定义卷积层加载mod时出错

2024-04-23 18:27:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经实现了一个最小的Wavenet示例,紧跟着这里的步骤-https://github.com/basveeling/wavenet。你知道吗

问题是,模型使用了一个自定义层,在训练期间可以正常工作,但是一旦模型重新加载,Keras就找不到因果层,即使我使用的是自定义对象。

我使用的是tensorflow 1.13和keras 2.2.4

下面是对象的前三个键/值对的示例。你知道吗

objects = {'initial_causal_conv': <class 'wavenet_utils.CausalConv1D'>,
           'dilated_conv_1_tanh_s0': <class 'wavenet_utils.CausalConv1D'>,
           'dilated_conv_1_sigm_s0': <class 'wavenet_utils.CausalConv1D'>,
           '...': <class 'wavenet_utils.CausalConv1D'>,
           '...': <class 'wavenet_utils.CausalConv1D'>}
model.fit(x=[x_tr1, x_tr2],
             y=y_tr1,
             epochs=epochs,
             batch_size=batch_size,
             validation_data=([x_vl1, x_vl2], y_vl1),
             callbacks=[checkpoint, early_stopping],
             verbose=verbose,
             shuffle=True,
             class_weight=class_weight)
model = load_model('model.h5', custom_objects=objects)

然后返回以下错误:

Traceback (most recent call last):
  File "/home/xxx/PycharmProjects/WAVE/DATA_NN.py", line 48, in <module>
    objects=objects)
  File "/home/xxx/PycharmProjects/WAVE/functions.py", line 572, in run_neural_net
    model = load_model('model_conv.h5', custom_objects=objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/saving.py", line 419, in load_model
    model = _deserialize_model(f, custom_objects, compile)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/saving.py", line 225, in _deserialize_model
    model = model_from_config(model_config, custom_objects=custom_objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/saving.py", line 458, in model_from_config
    return deserialize(config, custom_objects=custom_objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/layers/__init__.py", line 55, in deserialize
    printable_module_name='layer')
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/utils/generic_utils.py", line 145, in deserialize_keras_object
    list(custom_objects.items())))
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/network.py", line 1022, in from_config
    process_layer(layer_data)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/network.py", line 1008, in process_layer
    custom_objects=custom_objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/layers/__init__.py", line 55, in deserialize
    printable_module_name='layer')
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/utils/generic_utils.py", line 138, in deserialize_keras_object
    ': ' + class_name)
ValueError: Unknown layer: CausalConv1D

在构建模型时,必须从wavenet导入CausalConv1D_实用程序.py你知道吗

下面是完整的构建模型功能 这里是wavenet实用程序,包含CausalConv1D类:

from keras.layers import Conv1D
from keras.utils.conv_utils import conv_output_length
import tensorflow as tf


class CausalConv1D(Conv1D):
    def __init__(self, filters, kernel_size, init='glorot_uniform', activation=None,
                 padding='valid', strides=1, dilation_rate=1, bias_regularizer=None,
                 activity_regularizer=None, kernel_constraint=None, bias_constraint=None, use_bias=True, causal=False,
                 output_dim=1,
                 **kwargs):
        self.output_dim = output_dim

        super(CausalConv1D, self).__init__(filters,
                                           kernel_size=kernel_size,
                                           strides=strides,
                                           padding=padding,
                                           dilation_rate=dilation_rate,
                                           activation=activation,
                                           use_bias=use_bias,
                                           kernel_initializer=init,
                                           activity_regularizer=activity_regularizer,
                                           bias_regularizer=bias_regularizer,
                                           kernel_constraint=kernel_constraint,
                                           bias_constraint=bias_constraint,
                                           **kwargs)

        self.causal = causal
        if self.causal and padding != 'valid':
            raise ValueError("Causal mode dictates border_mode=valid.")

    def build(self, input_shape):
        super(CausalConv1D, self).build(input_shape)

    def call(self, x):
        if self.causal:
            def asymmetric_temporal_padding(x, left_pad=1, right_pad=1):
                pattern = [[0, 0], [left_pad, right_pad], [0, 0]]
                return tf.pad(x, pattern)

            x = asymmetric_temporal_padding(x, self.dilation_rate[0] * (self.kernel_size[0] - 1), 0)
        return super(CausalConv1D, self).call(x)

    def compute_output_shape(self, input_shape):
        input_length = input_shape[1]

        if self.causal:
            input_length += self.dilation_rate[0] * (self.kernel_size[0] - 1)

        length = conv_output_length(input_length,
                                    self.kernel_size[0],
                                    self.padding,
                                    self.strides[0],
                                    dilation=self.dilation_rate[0])

        shape = tf.TensorShape(input_shape).as_list()
        shape[-1] = self.output_dim
        return (input_shape[0], length, self.filters)

    def get_config(self):
        base_config = super(CausalConv1D, self).get_config()
        base_config['output_dim'] = self.output_dim
        return base_config

编辑:

我以前也尝试过这种方法。你知道吗

objects = {'CausalConv1D': <class 'wavenet_utils.CausalConv1D'>}
model.fit(x=[x_tr1, x_tr2],
             y=y_tr1,
             epochs=epochs,
             batch_size=batch_size,
             validation_data=([x_vl1, x_vl2], y_vl1),
             callbacks=[checkpoint, early_stopping],
             verbose=verbose,
             shuffle=True,
             class_weight=class_weight)
model = load_model('model.h5', custom_objects=objects)

然后返回以下错误:

Traceback (most recent call last):
  File "/home/xxx/PycharmProjects/WAVE/DATA_NN.py", line 47, in <module>
    objects=objects)
  File "/home/xxx/PycharmProjects/WAVE/functions.py", line 574, in run_neural_net
    model = load_model('model.h5', custom_objects=objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/saving.py", line 419, in load_model
    model = _deserialize_model(f, custom_objects, compile)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/saving.py", line 225, in _deserialize_model
    model = model_from_config(model_config, custom_objects=custom_objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/saving.py", line 458, in model_from_config
    return deserialize(config, custom_objects=custom_objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/layers/__init__.py", line 55, in deserialize
    printable_module_name='layer')
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/utils/generic_utils.py", line 145, in deserialize_keras_object
    list(custom_objects.items())))
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/network.py", line 1022, in from_config
    process_layer(layer_data)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/network.py", line 1008, in process_layer
    custom_objects=custom_objects)
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/layers/__init__.py", line 55, in deserialize
    printable_module_name='layer')
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/utils/generic_utils.py", line 147, in deserialize_keras_object
    return cls.from_config(config['config'])
  File "/home/xxx/PycharmProjects/WAVE/venv/lib/python3.6/site-packages/keras/engine/base_layer.py", line 1109, in from_config
    return cls(**config)
  File "/home/xxx/PycharmProjects/WAVE/wavenet_utils.py", line 26, in __init__
    **kwargs)
TypeError: __init__() got multiple values for keyword argument 'kernel_initializer'

这可能是这里提到的问题吗https://github.com/keras-team/keras/issues/12316?你知道吗

如果是的话,有什么办法可以解决吗?你知道吗


Tags: inpyselfconfighomemodelobjectsvenv
2条回答

不知何故,到目前为止,我尝试的任何方法都无法在使用load_model时正确加载模型。下面是一个简单的解决方法,它只保存权重,然后删除现有模型,构建一个新模型并再次编译,然后加载保存的权重,即使存在自定义层,这些权重也会正确保存。

model = build_model()

checkpoint = ModelCheckpoint('model.h5', monitor='val_acc',
                             verbose=1, save_best_only=True, save_weights_only=True, mode='max')

model.fit(x, y)

del model

model = build_model()

model.load_weights('model.h5')

model.predict(x_test)

只有一个自定义对象,即CausalConv1D。你知道吗

objects = {'CausalConv1D': wavenet_utils.CausalConv1D}

现在您必须确保您的get_config方法是正确的,并且包含了层的__init__方法中所需的所有内容。你知道吗

它缺少causal属性,并且有一个kernel_initializer来自您的__init__方法不支持的基类。你知道吗

让我们列出您需要的每个属性,然后检查基本配置中有哪些属性:

  • 过滤器:在基础中
  • 内核大小:底部
  • 初始化:不在base中,但是base中有kernel_initializer!!!!!
    • kernel_initializer__init__方法不支持的配置项
    • 将此init参数重命名为kernel_initializer
  • 激活:在基地
  • 填充:底部
  • 跨步:在基地
  • 扩张率:以基数
  • 偏移正则化器:在基中
  • 活动正则化器:在基础中
  • 内核\u约束:在基中
  • 偏置约束:在基础中
  • 使用偏差:在基础中
  • 原因:不在基础中
    • 必须在你的配置中添加这个!(或者模型将始终使用默认值)
  • 输出尺寸:不在底座中!你知道吗
  • **夸尔格:在基地

层的__init__

def __init__(self, filters, kernel_size, 

             ############## here:
             kernel_initializer='glorot_uniform', 
             #############

             activation=None,
             padding='valid', strides=1, dilation_rate=1, bias_regularizer=None,
             activity_regularizer=None, kernel_constraint=None, bias_constraint=None, use_bias=True, causal=False,
             output_dim=1,
             **kwargs):

层的get_config

它必须包含所有不在基类中的__init__参数:

def get_config(self):
    base_config = super(CausalConv1D, self).get_config()
    base_config['causal'] = self.causal
    base_config['output_dim'] = self.output_dim
    return base_config

相关问题 更多 >