【发布时间】:2018-02-05 06:48:59
【问题描述】:
最近我从tensorflow切换到keras,我需要创建一个自定义层。
我将类定义如下:
class Apply_conv2d(Layer):
def __init__(self, **kwargs):
super(Apply_conv2d, self).__init__(**kwargs)
def build(self, input_shape):
super(Apply_conv2d, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x):
res = Conv2D(32, (1, 1), padding='same')(x)
self.shape = res.shape
res = k.reshape(res, [-1, self.shape[1] * self.shape[2] * self.shape[3]])
return res
def compute_output_shape(self, input_shape):
return (None, input_shape[3])
但是当我打印 model.summary() 时,我得到了 0 个使用该层的可训练参数。
这个实现有什么问题? 谢谢
编辑
我将类定义更改为:
class Apply_conv2d(Layer):
def __init__(self, **kwargs):
self.trainable = True
super(Apply_conv2d, self).__init__(**kwargs)
def build(self, input_shape):
w = self.add_weight(name='kernel', shape=(1, 1, 2048, 32), initializer='uniform', trainable=True)
b = self.add_weight(name='kernel', shape=(32,), initializer='uniform', trainable=True)
self.kernel = [w, b]
super(Apply_conv2d, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x):
res = Conv2D(32, (1, 1), padding='same', name='feature_conv', weights=self.kernel)(x)
self.shape = res.shape
res = k.reshape(res, [-1, self.shape[1] * self.shape[2] * self.shape[3]])
return res
def compute_output_shape(self, input_shape):
return (None, input_shape[3])
但这仍然不起作用...
错误是:
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition
2017.2.3\helpers\pydev\pydevd.py", line 1668, in <module>
main()
File "C:\Program Files\JetBrains\PyCharm Community Edition
2017.2.3\helpers\pydev\pydevd.py", line 1662, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.2.3\helpers\pydev\pydevd.py", line 1072, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.2.3\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/Reza/Dropbox/Reza/VOC2012-D/script.py", line 123, in <module>
model = cl.get_model(inputs)
File "C:/Users/Reza/Dropbox/Reza/VOC2012-D\custom_layers.py", line 77, in get_model
x3 = Apply_conv2d()(x)
File "C:\Program Files\Python35\lib\site-packages\keras\engine\topology.py", line 603, in __call__
output = self.call(inputs, **kwargs)
File "C:/Users/Reza/Dropbox/Reza/VOC2012-D\custom_layers.py", line 104, in call
res = Conv2D(32, (1, 1), padding='same', name='feature_conv', weights=self.kernel)(x)
File "C:\Program Files\Python35\lib\site-packages\keras\engine\topology.py", line 583, in __call__
self.set_weights(self._initial_weights)
File "C:\Program Files\Python35\lib\site-packages\keras\engine\topology.py", line 1203, in set_weights
K.batch_set_value(weight_value_tuples)
File "C:\Program Files\Python35\lib\site-packages\keras\backend\tensorflow_backend.py", line 2239, in batch_set_value
value = np.asarray(value, dtype=dtype(x))
File "C:\Program Files\Python35\lib\site-packages\numpy\core\numeric.py", line 531, in asarray
return array(a, dtype, copy=False, order=order)
ValueError: setting an array element with a sequence.
有什么建议吗?
【问题讨论】:
-
你少了一步,你需要在
build()期间创建可训练的权重数组。但是由于您的自定义层看起来像Conv2D -> Flatten()的层吗?您可能希望将权重数组设置为res.get_weights()。顺便说一下,每次调用该层时都会初始化一个新的 Conv2D 层。不确定它是否是故意的,也许你想移动它来构建? -
@umutto 我已经按照你说的做了,但还是不行
标签: python tensorflow deep-learning keras layer