为什么我只传入一个参数,却显示有两个位置参数?

以下代码片段用于在TensorFlow后端的Keras中定义一个CNN架构:

class DownBlock(object):    def __init__(self, prev_layer, num_chann = 16, depthwise_initializer = 'glorot_uniform', kernel_initializer = 'glorot_uniform', bias_initializer = 'zeros', drop_rate = None, spdrop_rate = None, activation = 'relu', pool = True):        self.prev_layer = prev_layer        if pool == True:            self.prev_layer = MaxPooling2D((2, 2)) (self.prev_layer)            self.prev_layer = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.prev_layer)        self.convo = Activation(activation) (self.prev_layer)        self.convo = BatchNormalization() (self.convo)        if not spdrop_rate == None:                         self.convo = SpatialDropout2D(spdrop_rate) (self.convo)        if not drop_rate == None:                         self.convo = Dropout(drop_rate) (self.convo)        self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)        self.convo = DepthwiseConv2D((3, 3), depthwise_initializer = depthwise_initializer, bias_initializer = bias_initializer, padding = 'same') (self.convo)        self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)        self.convo = Activation(activation) (self.convo)        self.convo = BatchNormalization() (self.convo)        if not spdrop_rate == None:                         self.convo = SpatialDropout2D(spdrop_rate) (self.convo)        if not drop_rate == None:                         self.convo = Dropout(drop_rate) (self.convo)        self.convo = DepthwiseConv2D((3, 3), depthwise_initializer = depthwise_initializer, bias_initializer = bias_initializer, padding = 'same') (self.convo)        self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)        self.convo = Add([self.prev_layer, self.convo])    def get(self):        return self.convoclass UpBlock(object):    def __init__(self, prev_layer, bridge_layer, num_chann = 16, depthwise_initializer = 'glorot_uniform', kernel_initializer = 'glorot_uniform', bias_initializer = 'zeros', drop_rate = None, spdrop_rate = None, activation = 'relu', up = True):        self.prev_layer = prev_layer        self.bridge_layer = bridge_layer        self.convo = Activation(activation) (self.prev_layer)        self.convo = BatchNormalization() (self.convo)        if not spdrop_rate == None:                         self.convo = SpatialDropout2D(spdrop_rate) (self.convo)        if not drop_rate == None:                         self.convo = Dropout(drop_rate) (self.convo)        self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)        self.convo = DepthwiseConv2D((3, 3), depthwise_initializer = depthwise_initializer, bias_initializer = bias_initializer, padding = 'same') (self.convo)        self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)        self.convo = Activation(activation) (self.convo)        self.convo = BatchNormalization() (self.convo)        if not spdrop_rate == None:                         self.convo = SpatialDropout2D(spdrop_rate) (self.convo)        if not drop_rate == None:                         self.convo = Dropout(drop_rate) (self.convo)        self.convo = DepthwiseConv2D((3, 3), depthwise_initializer = depthwise_initializer, bias_initializer = bias_initializer, padding = 'same') (self.convo)        self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)        self.convo = Add([self.prev_layer, self.convo])        if up == True:            self.convo = Conv2D(num_chann/2, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)            self.convo = Conv2DTranspose(num_chann/2, (2, 2), strides = (2, 2), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer, padding = 'same') (self.convo)        self.convo = Add([self.bridge_layer, self.convo])    def get(self):        return self.convoinputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))s = Lambda(lambda x: x / 255) (inputs)s = Conv2D(8, (1, 1)) (s)d1 = DownBlock(s, num_chann = 16, drop_rate = 0.1)d2 = DownBlock(d1.get(), num_chann = 32, drop_rate = 0.1)d3 = DownBlock(d2.get(), num_chann = 64, drop_rate = 0.1)d4 = DownBlock(d3.get(), num_chann = 128, drop_rate = 0.1)d5 = DownBlock(d4.get(), num_chann = 256, drop_rate = 0.1)m = DownBlock(d5.get(), num_chann = 512, drop_rate = 0.1)u5 = UpBlock(m.get(), d4.get(), num_chann = 256, drop_rate = 0.1)u4 = UpBlock(u5.get(), d3.get(), num_chann = 128, drop_rate = 0.1)u3 = UpBlock(u4.get(), d2.get(), num_chann = 64, drop_rate = 0.1)u2 = UpBlock(u3.get(), d1.get(), num_chann = 32, drop_rate = 0.1)u1 = UpBlock(u2.get(), s, num_chann = 16, drop_rate = 0.1)final = Conv2D(1, (1, 1)) (u1.get())# final = SpatialDropout2D(0.1) (final)final = Dropout(0.1) (final)final = BatchNormalization() (final)outputs = Activation("sigmoid") (final)model = Model(inputs = [inputs], outputs = [outputs])

在Jupyter笔记本中执行时,会生成以下堆栈跟踪:

TypeError                                 Traceback (most recent call last)<ipython-input-31-f23b70d0be6d> in <module>()    79 s = Conv2D(8, (1, 1)) (s)    80 ---> 81 d1 = DownBlock(s, num_chann = 16, drop_rate = 0.1)    82     83 d2 = DownBlock(d1.get(), num_chann = 32, drop_rate = 0.1)<ipython-input-31-f23b70d0be6d> in __init__(self, prev_layer, num_chann, depthwise_initializer, kernel_initializer, bias_initializer, drop_rate, spdrop_rate, activation, pool)    29         self.convo = Conv2D(num_chann, (1, 1), kernel_initializer = kernel_initializer, bias_initializer = bias_initializer) (self.convo)    30 ---> 31         self.convo = Add([self.prev_layer, self.convo])    32     33     def get(self):TypeError: __init__() takes 1 positional argument but 2 were given

堆栈跟踪中的最后一行…

TypeError: __init__() takes 1 positional argument but 2 were given

…提到向第一个UpBlock()调用传递了两个位置参数,而我明明只传递了一个-

d1 = DownBlock(s, num_chann = 16, drop_rate = 0.1)

另一个位置参数在哪里?如果没有第二个位置参数,为什么我会收到这个错误?


回答:

虽然错误源自于对DownBlock构造函数的调用,但Python也指出错误回溯是(most recent call last)。此错误指的是向Add构造函数传递了过多的参数。Python告诉您的是,您对Add()的调用参数过多。

这里的技巧是,虽然看起来您只向Add()提供了一个列表参数,但Python类构造函数都会隐式地接收self作为其第一个位置参数。请参阅Python文档

来自评论:

在使用Keras的函数式API时,必须先创建层对象,如a = Add(),然后通过调用生成的对象将其添加到计算图中,如下所示:

out = a([input1, input2, ...])

或者在您的原始示例中:

self.convo = Add()([self.prev_layer, self.convo])

Related Posts

在使用k近邻算法时,有没有办法获取被使用的“邻居”?

我想找到一种方法来确定在我的knn算法中实际使用了哪些…

Theano在Google Colab上无法启用GPU支持

我在尝试使用Theano库训练一个模型。由于我的电脑内…

准确性评分似乎有误

这里是代码: from sklearn.metrics…

Keras Functional API: “错误检查输入时:期望input_1具有4个维度,但得到形状为(X, Y)的数组”

我在尝试使用Keras的fit_generator来训…

如何使用sklearn.datasets.make_classification在指定范围内生成合成数据?

我想为分类问题创建合成数据。我使用了sklearn.d…

如何处理预测时不在训练集中的标签

已关闭。 此问题与编程或软件开发无关。目前不接受回答。…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注