Convert code from Keras 1 to Keras 2: TypeError: __call__() missing 1 required positional argument: 'shape'

◇◆丶佛笑我妖孽 提交于 2020-01-05 07:49:37

问题


I am trying to convert a V-net code that was written in Keras 1 into Keras 2. It seems that I have an issue with the following class:

class Deconv3D(Layer):
    def __init__(self, nb_filter, kernel_dims, output_shape, strides):
        assert K.backend() == 'tensorflow'
        self.nb_filter = nb_filter
        self.kernel_dims = kernel_dims
        self.strides = (1,) + strides + (1,)
        self.output_shape_ = output_shape
        super(Deconv3D, self).__init__()

    def build(self, input_shape):
        assert len(input_shape) == 5
        self.input_shape_ = input_shape
        W_shape = self.kernel_dims + (self.nb_filter, input_shape[4], )
        self.W = self.add_weight(W_shape, initializer=functools.partial(initializers.glorot_uniform), name='{}_W'.format(self.name))
        self.b = self.add_weight((1,1,1,self.nb_filter,), initializer='zero', name='{}_b'.format(self.name))
        self.built = True

    def get_output_shape_for(self, input_shape):
        return (None, ) + self.output_shape_[1:]

    def call(self, x, mask=None):
        return tf.nn.conv3d_transpose(x, self.W, output_shape=self.output_shape_, strides=self.strides, padding='same', name=self.name) + self.b

When I try to call it using Deconv3D(128, (2, 2, 2), (1, 16, 16, 8, 128), (2, 2, 2))(), I get the following error that I don't understand:

Traceback (most recent call last):
File "V-net.py", line 118, in <module>
downsample_5 = Deconv3D(128, (2, 2, 2), (1, 16, 16, 8, 128), (2, 2, 2))(prelu_5_1) # Check the 8
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/keras/engine/topology.py", line 569, in __call__
self.build(input_shapes[0])
File "V-net.py", line 35, in build
self.W = self.add_weight(W_shape, initializer=functools.partial(initializers.glorot_uniform), name='{}_W'.format(self.name))
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/keras/legacy/interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/keras/engine/topology.py", line 391, in add_weight
weight = K.variable(initializer(shape), dtype=dtype, name=name)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 321, in variable
v = tf.Variable(value, dtype=_convert_string_dtype(dtype), name=name)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/ops/variables.py", line 200, in __init__
expected_shape=expected_shape)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/ops/variables.py", line 278, in _init_from_args
initial_value(), name="initial_value", dtype=dtype)
TypeError: __call__() missing 1 required positional argument: 'shape'

What am I doing wrong?


回答1:


The class Deconv3D has to match Keras 2 architecture.

class Deconvolution3D(Layer):

    def __init__(self, nb_filter, kernel_dims, output_shape, subsample, **kwargs):
        self.nb_filter = nb_filter
        self.kernel_dims = kernel_dims
        self.strides = (1, ) + subsample + (1, )
        self.output_shape_ = output_shape
        assert K.backend() == 'tensorflow'
        super(Deconvolution3D, self).__init__(**kwargs)

    def build(self, input_shape):
        assert len(input_shape) == 5
        self.W = self.add_weight(shape=self.kernel_dims + (self.nb_filter, input_shape[4], ),
                             initializer='glorot_uniform',
                             name='{}_W'.format(self.name),
                             trainable=True)
        self.b = self.add_weight(shape=(1, 1, 1, self.nb_filter,), 
                             initializer='zero', 
                             name='{}_b'.format(self.name),
                             trainable=True)
        super(Deconvolution3D, self).build(input_shape) 

    def call(self, x, mask=None):
        return tf.nn.conv3d_transpose(x, self.W, output_shape=self.output_shape_,
                                  strides=self.strides, padding='SAME', name=self.name) + self.b

    def compute_output_shape(self, input_shape):
        return (input_shape[0], ) + self.output_shape_[1:]


来源:https://stackoverflow.com/questions/48533216/convert-code-from-keras-1-to-keras-2-typeerror-call-missing-1-required-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!