【问题标题】:Implementing LeNet in keras. How can I only combine some feature maps in a convolution layer?在 keras 中实现 LeNet。如何只在卷积层中组合一些特征图?
【发布时间】:2023-03-13 19:18:01
【问题描述】:

我目前正在尝试从其在 keras 中的原始论文中实现 LeNet。在那里,架构定义如下

作者还描述,在卷积层 C3 中,并非所有过滤器都应用于前一层的所有特征图。他们还提供此表来定义哪些特征图与哪些过滤器结合使用。似乎我发现的每个实现都没有这样做。

所以我的问题是

  • 如何添加这种行为?
  • 另外,为什么我发现的每个 LeNet 实现似乎都忽略了这部分?

这是我当前的代码,没有选择性地应用过滤器。

model = keras.Sequential()

#C1
model.add(layers.Conv2D(filters=6, kernel_size=(3, 3), activation='relu', input_shape=(32,32,1)))
#S2    
model.add(layers.AveragePooling2D())
#C3
model.add(layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
model.add(layers.AveragePooling2D())

model.add(layers.Flatten())

model.add(layers.Dense(units=120, activation='relu'))

model.add(layers.Dense(units=84, activation='relu'))

model.add(layers.Dense(units=10, activation = 'softmax'))

【问题讨论】:

    标签: tensorflow keras conv-neural-network


    【解决方案1】:

    您可以使用函数式 API 轻松获取由 NN 层生成的张量的某些切片。

    也就是说,让conv_1=tf.keras.layers.Conv2D(parameters) 成为您要从中提取某些特征图的层。相应地,在模型的定义中你会拥有

        features = conv_1(previous_features)
    

    如果你想从通道 3、4 和 5 获取特征图,你可以使用 tf.slice 或使用 pythonic/numpy 索引(TF 支持):

        # assuming dimensions are (batch_size, height, width, channels)
        feature_maps = features[:,:,:,3:6] 
    

    要获取任意频道,您可能首先需要使用tf.unstack 沿频道轴取消堆叠features,从features 中创建一个列表:

        features_list = tf.unstack(feature_maps, axis=-1)
    

    这会产生一个张量列表,每个张量都是一个特定的特征图。然后你可以使用tf.satck 将它们组合成一个新的张量:

        # let a1, ..., an are indexes of the channels you need.
        particular_features = tf.stack( [features_list[a1], ... , features_list[an] ], axis=-1 )
    

    您可以通过将由此获得的特征图作为参数传递给更多层,从而在网络中进一步使用它们。这应该可以完成工作。

    我不熟悉 LeNet 模型的任何实现,因此我无法对此发表评论。

    【讨论】: