【发布时间】:2018-05-01 02:14:20
【问题描述】:
在使用输入内核和偏差实现自定义 conv2d 层时遇到问题。这个内核和偏差是另一层 A 的输出,然后使用这些权重进行 conv2d。而我只是想让这一层使用权重而不是学习,所以如果这一层不可训练,梯度是否会转移到A层,这意味着我希望A层是可训练的
【问题讨论】:
在使用输入内核和偏差实现自定义 conv2d 层时遇到问题。这个内核和偏差是另一层 A 的输出,然后使用这些权重进行 conv2d。而我只是想让这一层使用权重而不是学习,所以如果这一层不可训练,梯度是否会转移到A层,这意味着我希望A层是可训练的
【问题讨论】:
你不需要用不可学习的参数编写这样的层。如果我理解正确,您需要以下内容。
import keras
from keras.layers import Conv2D, Dense, Input, Flatten, Lambda
from keras.models import Model
from keras import backend as K
img = Input(shape=(32,32,3), name='img_in')
# this is the standard way of calling a learnable conv kernel and bias
# but kernel and bias are independent of input
x = Conv2D( 64,(5,5),padding='same',name='StandardConv')(img)
# this is a custom way of calling a learnable conv kernel and bias
# but this time they are dependent on the input
img_flat = Flatten(name='flat')(img)
conv_kernel = Dense( 3*5*5*64, name='regConvKernel' )( img_flat )
conv_bias = Dense( 64, name='regConvBias' )( img_flat )
# of course, you need to use conv_kernel and conv_bias to apply conv operation
# and this happens here
def custom_conv( input_vars ) :
x, kernel, bias = input_vars
kernel = K.reshape( kernel, (5,5,3,64))
bias = K.reshape( bias, [1,1,1,64])
x = K.conv2d( x, kernel, padding='same' )
x += bias
return x
def custom_conv_shape( input_shapes ) :
x_shape, kernel_shape, bias_shape = input_shapes
return x_shape[:3] + bias_shape[-1:]
y = Lambda( custom_conv, output_shape=custom_conv_shape, name='CustomConv')([img, conv_kernel, conv_bias])
# define your final model
model = Model( inputs=img, outputs=[x,y], name='compareConv')
print model.summary()
# test use dummy numpy arrays
import numpy as np
a = np.random.randn(1,32,32,3)
b, c = model.predict(a)
print "standard conv output shape =", b.shape
print "custom conv output shape =", c.shape
你会看到如下输出。
Layer (type) Output Shape Param # Connected to
==================================================================================================
img_in (InputLayer) (None, 32, 32, 3) 0
__________________________________________________________________________________________________
flat (Flatten) (None, 3072) 0 img_in[0][0]
__________________________________________________________________________________________________
regConvKernel (Dense) (None, 4800) 14750400 flat[0][0]
__________________________________________________________________________________________________
regConvBias (Dense) (None, 64) 196672 flat[0][0]
__________________________________________________________________________________________________
StandardConv (Conv2D) (None, 32, 32, 64) 4864 img_in[0][0]
__________________________________________________________________________________________________
CustomConv (Lambda) (None, 32, 32, 64) 0 img_in[0][0]
regConvKernel[0][0]
regConvBias[0][0]
==================================================================================================
Total params: 14,951,936
Trainable params: 14,951,936
Non-trainable params: 0
__________________________________________________________________________________________________
None
standard conv output shape = (1, 32, 32, 64)
custom conv output shape = (1, 32, 32, 64)
当然,您可以使用不同的内核大小或填充方案。您可以考虑更合理的方法来估计conv_kernel 和conv_bias,而不是直接从输入中回归。
【讨论】:
conv_kernel 和conv_bias 直接定义为keras 变量,例如import numpy as np val = np.random.random((3, 4, 5)) conv_kernel = K.variable(value=val)
TimeDistributed( XXX ) 层应该没问题,它会将输入的第二维视为时间维度,并将 4D 输入提供给XXX 层。