Python Keras中卷积层的稀疏训练

Python Keras中卷积层的稀疏训练,python,tensorflow,keras,conv-neural-network,Python,Tensorflow,Keras,Conv Neural Network,我想在Keras训练一个CNN,使用卷积层,比如 x_1 = Conv2D(16, (kernel_size, kernel_size))(x_in) x_in在这里包含3个输入特征层,因此3*16=48个内核大小*内核大小的内核必须在这里进行训练。假设我希望这48个内核中有5个完全为0(所以它的所有元素),我如何有效地训练它 提前谢谢 我的总配置如下所示: x_in = Input(shape=(None, None, 3)) x_1 = Conv2D(16, (kernel_size,

我想在Keras训练一个CNN,使用卷积层,比如

x_1 = Conv2D(16, (kernel_size, kernel_size))(x_in)
x_in在这里包含3个输入特征层,因此3*16=48个内核大小*内核大小的内核必须在这里进行训练。假设我希望这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) 

在这种情况下,您必须实现一个自定义卷积层。您必须创建一个类,该类应该是keras的
类的实例。这需要为前馈计算实现
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中图层类的实例,可以像任何普通图层一样使用

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)个不可训练的参数


在这里我没有添加偏差项。您可以进一步添加和自定义Conv层。此外,过滤器的顺序也可以更改,只需将可训练参数设置为False,并将要训练的层的初始值设定项更改为其他值。

在中,
x_的形状是什么?3个通道,通道的尺寸未知,因为我使用具有不同分辨率的图像的数据集,如果我没有弄错16个内核的话(3x3)必须训练,不是48对吗?16个内核将在3个通道中共享,进行48次卷积运算?不,必须训练48个内核。每个输入通道输出通道组合一个。在默认卷积运算的情况下,16个过滤器(不是48个)将在通道之间共享,进行48次卷积运算(3x3x16(权重)+16(偏差)=448可训练参数)。那么,您是否正在尝试自定义此操作?非常感谢,这看起来像我正在寻找的东西,我将尝试它。还有一个问题:您现在已确定5个未经训练的内核都来自第一个输入通道。模型能否训练这5个内核中有多少个从第1、第2和第3个开始,以及它是从哪个输出通道开始的t内核的修剪发生了吗?或者这太难了吗?如果它最终检查每个通道,那么没有什么是不可训练的!在训练时检查权值修剪的tensorflow。