类中调用conv_layer报TypeError:意外关键字参数shape问题排查
问题原因分析
你遇到的这个错误核心原因是Python类的实例方法缺少了必要的self参数,导致调用时参数传递逻辑完全混乱了。
具体细节拆解:
当你把这些函数放到cnnUtils类中并通过实例调用时,Python会自动把实例对象(也就是你的utils)作为第一个参数传递给类中的方法。但你的conv_layer方法定义是:
def conv_layer(input,shape):
这里没有预留第一个参数给实例对象,所以当你执行utils.conv_layer(x, shape=[5,5,3,32])时:
- Python自动把
utils实例传给了input参数 - 你传入的
x被传给了shape参数 - 最后你又加了一个关键字参数
shape=[...],这就导致方法收到了两个对应shape的参数(一个是位置传递的x,一个是关键字传递的列表),所以抛出了TypeError: conv_layer() got an unexpected keyword argument 'shape'的错误。
而当你把这些方法作为普通函数调用时,不存在Python自动传递实例的逻辑,参数完全按照你写的顺序/关键字匹配,所以不会出错。
解决方案:
给类中所有的实例方法加上self作为第一个参数,并且调用类内其他方法时也要加上self.前缀(比如self.get_bias、self.conv2d),否则会报错找不到这些函数。修正后的代码如下:
import tensorflow as tf class cnnUtils: def get_weight(self, shape): init = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(init) def get_bias(self, shape): init = tf.constant(0.1, shape=shape) return tf.Variable(init) def conv2d(self, x, w): return tf.nn.conv2d(x, w, strides=[1,1,1,1], padding="SAME") def maxpool_2d(self, x): return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME") def conv_layer(self, input, shape): b = self.get_bias([shape[3]]) w = self.get_weight(shape) return tf.nn.relu(self.conv2d(input, w) + b) def full_layer(self, input, size): in_size = int(input.get_shape()[1]) w = self.get_weight([in_size, size]) b = self.get_bias([size]) return tf.matmul(input, w) + b
之后你再实例化调用:
utils = cnnUtils() conv1 = utils.conv_layer(x, shape=[5,5,3,32])
就可以正常运行了。
另外补充一点:如果你不想用实例方法,也可以把这些方法定义为静态方法(加上@staticmethod装饰器),这样就不需要self参数,但调用类内其他方法时也要对应改成静态方法,不过对于工具类来说,用实例方法加self是更常规的写法。
内容的提问来源于stack exchange,提问作者Edison
相关产品推荐
相关产品推荐

