Conv2D层对前一层特征图的过滤逻辑及输出通道数疑问
Conv2D层对前一层特征图的过滤逻辑及输出通道数疑问
你提的这个问题是理解卷积层时非常常见的误区,我来给你掰碎了说清楚:
核心逻辑是:每个Conv2D层的滤波器会同时作用于前一层的所有输入通道,而不是每个通道单独对应一个滤波器。
具体到你的例子:
- 第一层Conv2D输出了10个通道的特征图,所以第二层Conv2D的每个滤波器的深度和输入通道数完全一致——也就是每个滤波器的形状是
(3,3,10),而不是你误以为的(3,3,1)。 - 当这个滤波器在输入特征图上滑动时,会对每个位置的10个通道的像素值做加权求和(再加上该滤波器的偏置项),得到一个单一的数值——这个数值就是输出特征图对应位置的像素。
- 所以20个这样的滤波器,每个都会输出一个单通道的特征图,把这20个单通道特征图堆叠起来,就得到了最终的
(None,8,8,20)输出,而不是20*10=200个通道。
用参数计算验证这个逻辑:
你可以对照模型参数表的数值,完全能印证这个逻辑:
- 第一层Conv2D(10个滤波器):
每个滤波器的参数是4*4*3(卷积核权重,对应输入3通道) + 1(偏置)= 49个参数
10个滤波器总参数就是49*10=490,和表格里的Param # 490完全一致。 - 第二层Conv2D(20个滤波器):
每个滤波器的参数是3*3*10(卷积核权重,对应输入10通道) +1(偏置)=91个参数
20个滤波器总参数就是91*20=1820,正好匹配表格里的Param # 1820。
这就实锤了:每个滤波器是覆盖所有输入通道的,而不是和输入通道一一对应生成多个输出通道。
你提供的代码整理:
input_layer = layers.Input(shape=(32,32,3)) conv_layer_1 = layers.Conv2D( filters = 10 , kernel_size = (4,4) , strides = 2 , padding = 'same' )(input_layer) conv_layer_2 = layers.Conv2D( filters = 20 , kernel_size = (3,3) , strides = 2 , padding = 'same' )(conv_layer_1) flatten_layer = layers.Flatten()(conv_layer_2) output_layer = layers.Dense(units=10, activation = 'softmax')(flatten_layer) model = models.Model(input_layer, output_layer)
模型结构参数表:
| Layer (type) | Output shape | Param # |
|---|---|---|
| InputLayer | (None, 32, 32, 3) | 0 |
| Conv2D | (None, 16, 16, 10) | 490 |
| Conv2D | (None, 8, 8, 20) | 1,820 |
| Flatten | (None, 1280) | 0 |
| Dense | (None, 10) | 12,810 |
参考配图:

备注:内容来源于stack exchange,提问作者Steven Dascoli
相关产品推荐
相关产品推荐

