【问题标题】:A custom layer with a input kernel and bias具有输入内核和偏差的自定义层
【发布时间】:2018-05-01 02:14:20
【问题描述】:

在使用输入内核和偏差实现自定义 conv2d 层时遇到问题。这个内核和偏差是另一层 A 的输出,然后使用这些权重进行 conv2d。而我只是想让这一层使用权重而不是学习,所以如果这一层不可训练,梯度是否会转移到A层,这意味着我希望A层是可训练的

【问题讨论】:

    标签: keras layer


    【解决方案1】:

    你不需要用不可学习的参数编写这样的层。如果我理解正确,您需要以下内容。

    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_kernelconv_bias,而不是直接从输入中回归。

    【讨论】:

    • 非常感谢!你的想法非常完美!因此,通过这种方式,conv_kernel 和 conv_bias 只是 Dense 层的输出,并优化了这些 fc 层的权重。而我的内核和偏差来自另一个模型的 h5 文件,我使用已经训练好的模型分类器的权重,所以你知道我是否可以在 keras 中使用固定输入,并且这个输入只给出一次而不是给出批处理的方式大小的图像。谢谢!
    • 当然可以。您需要做的就是将conv_kernelconv_bias 直接定义为keras 变量,例如import numpy as np val = np.random.random((3, 4, 5)) conv_kernel = K.variable(value=val)
    • 嗨,我想知道我是否使用 TimeDistributed 层来包装调用 customconv 的 Lambda(),input_x 是 5D 张量,但如果我扩展维度,内核和偏差不是内核和偏差似乎不合理?
    • 如果您使用TimeDistributed( XXX ) 层应该没问题,它会将输入的第二维视为时间维度,并将 4D 输入提供给XXX 层。
    • 但是你知道 TimeDistributed 的 input 的 shape 应该大于 3,如果我给出一个类似 [input_x, kernel, bias] 的列表可能会报错,可能这个列表应该是 5D ,但我现在不知道。
    猜你喜欢
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多