Keras 带有输入内核和偏差的自定义层

Keras 带有输入内核和偏差的自定义层,keras,layer,Keras,Layer,在使用输入内核和偏差实现定制的conv2d层时,我遇到了一个问题。该内核和偏差是另一层A的输出,然后使用这些权重来执行conv2d。我只是想让这个层使用权重,而不是学习,所以如果这个层是不可训练的,梯度会转移到层A,这意味着我想层A是可训练的,你不需要用不可学习的参数编写这样的层。如果我理解正确,你需要下面的东西 import keras from keras.layers import Conv2D, Dense, Input, Flatten, Lambda from keras.model

在使用输入内核和偏差实现定制的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)

当然,您可以使用不同的内核大小或填充方案。您可以考虑更合理的方式来估计<代码>凸出核和<代码> 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,但我现在不知道。