Keras中卷积层的稀疏训练

时间:2019-12-23 08:55:05

标签: python tensorflow keras conv-neural-network

我想使用

这样的卷积层在Keras中训练CNN
x_1 = Conv2D(16, (kernel_size, kernel_size))(x_in)

x_in此处包含3个输入要素图层,因此必须在此处训练3 * 16 = 48个kernel_size * kernel_size内核。假设我希望这48个内核中的5个完全是0(所以它的所有元素),那么我该如何有效地训练呢?

谢谢。

我的总配置如下:

x_in = Input(shape=(None, None, 3))

x_1 = Conv2D(16, (kernel_size, kernel_size))(x_in)
x_1 = ReLU()(x_1)
x_2 = Conv2D(16, (kernel_size, kernel_size))(x_1)
x_2 = ReLU()(x_2)
x_3 = Conv2D(16, (kernel_size, kernel_size))(x_2)
return Model(inputs=x_in, outputs=x_3) 

1 个答案:

答案 0 :(得分:1)

在这种情况下,您将必须实现自定义卷积层。您必须创建一个类,该类应该是keras的Layer类的实例。这需要实现call方法用于前馈计算。

这可能是您正在寻找的东西。

class CustomConv2D(Layer):
    def __init__(self, k=3):
      super(CustomConv2D, self).__init__()

      c1_1 = self.add_weight(shape=(k,k, 1, 5), initializer='zeros', dtype=tf.float32, trainable=False)
      c1_2 = self.add_weight(shape=(k,k, 1, 11), initializer='zeros', dtype=tf.float32, trainable=True)
      self.c1 = tf.concat([c1_1,c1_2], axis=-1)

      self.c2 = self.add_weight(shape=(k,k, 1, 16), initializer='zeros', dtype=tf.float32, trainable=True)
      self.c3 = self.add_weight(shape=(k,k, 1, 16), initializer='zeros', dtype=tf.float32, trainable=True)

    def call(self, inputs):
        x_1_c1 = tf.nn.conv2d(tf.expand_dims(inputs[:,:,:,0],-1), self.c1,padding='VALID')
        x_1_c2 = tf.nn.conv2d(tf.expand_dims(inputs[:,:,:,1],-1), self.c2,padding='VALID')
        x_1_c3 = tf.nn.conv2d(tf.expand_dims(inputs[:,:,:,2],-1), self.c3,padding='VALID')

        x_1 = tf.concat([x_1_c1,x_1_c2, x_1_c3], -1)
        return x_1

在这种情况下,我们有三组滤镜(每个通道16个),对于第一个通道,我们将5个滤镜设为不可训练,其余11个设为可训练,其余的32个(针对通道2和3)滤镜可以训练的。

这是keras中的Layer类的实例,可以像任何普通图层一样使用。

model = tf.keras.models.Sequential()
model.add(CustomConv2D(3))

model.build(input_shape=(None,None,None,3))
I = tf.keras.Input((None,None,3))
model.call(I)
model.summary()
'''
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
custom_conv2d_2 (CustomConv2 (None, None, None, 48)    432       
=================================================================
Total params: 432
Trainable params: 387
Non-trainable params: 45
_________________________________________________________________
'''


如您所见,我们没有训练5个过滤器,因此没有训练45个(3x3x5)不可训练参数

在这里,我没有未添加偏见一词。您可以进一步添加并自定义转换层。同样,可以更改过滤器的顺序,只需将可训练参数设置为False,然后将initializer更改为您想训练的图层的其他值即可。