Keras 带有输入内核和偏差的自定义层
在使用输入内核和偏差实现定制的conv2d层时,我遇到了一个问题。该内核和偏差是另一层A的输出,然后使用这些权重来执行conv2d。我只是想让这个层使用权重,而不是学习,所以如果这个层是不可训练的,梯度会转移到层A,这意味着我想层A是可训练的,你不需要用不可学习的参数编写这样的层。如果我理解正确,你需要下面的东西Keras 带有输入内核和偏差的自定义层,keras,layer,Keras,Layer,在使用输入内核和偏差实现定制的conv2d层时,我遇到了一个问题。该内核和偏差是另一层A的输出,然后使用这些权重来执行conv2d。我只是想让这个层使用权重,而不是学习,所以如果这个层是不可训练的,梯度会转移到层A,这意味着我想层A是可训练的,你不需要用不可学习的参数编写这样的层。如果我理解正确,你需要下面的东西 import keras from keras.layers import Conv2D, Dense, Input, Flatten, Lambda from keras.model
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)
当然,您可以使用不同的内核大小或填充方案。您可以考虑更合理的方式来估计<代码>凸出核和<代码> ValueBase<代码>,而不是直接从输入中还原它们。非常感谢!你的想法太完美了!因此,通过这种方式,conv_内核和conv_偏差只是密集层的输出,用于优化这些fc层的权重。我的内核和偏差来自另一个模型的h5文件,我使用已经训练过的模型分类器的权重,所以你知道我是否可以在keras中使用固定的输入,这个输入只给出一次,而不是给出批量大小的图像。谢谢当然可以。您需要做的就是直接将
conv_内核
和conv_偏差
定义为keras
变量,例如import numpy作为np val=np.random.random((3,4,5))conv_内核=K.variable(value=val)
嗨,我想知道我是否使用了一个时间分布层来包装Lambda(),它调用customconv,输入_x是一个5D张量,但核和偏差不是,如果我扩展核和偏差的维数,这似乎不合理?如果你应该很好,因为你使用的是TimeDistributed(XXX)
层,这将把你的输入的第二个维度作为时间维度,并将一个4D输入馈送到XXX
层。但是你知道时间分布的输入形状应该大于3,如果我给出一个类似[input_x,kernel,bias]的列表,可能会抛出一个错误,可能列表应该是5D,但我现在不知道。