TensorFlow/PyTorch中不同滤波器数Conv2D层连接的工作机制是什么?
查阅LeNet5架构说明时了解到,当带有6个filters的Max Pooling层与带有16个filters的Conv2D层连接时,需要采用如下特殊filter映射规则:
- 从每3个连续的feature maps子集取输入
- 从每4个连续的feature maps子集取输入
- 从每4个连续的feature maps子集取输入
- 从4个不连续的feature maps子集取输入
- 取全部feature maps作为输入
对应LeNet论文标注图如下:
框架默认卷积连接逻辑
你提到的上述映射是LeNet5论文中为了降低计算量、模拟不同特征提取组合的手工定制规则,本质是限制输出层的每个卷积核只和输入特征图的指定子集做运算。现在TensorFlow、PyTorch等主流深度学习框架的默认Conv2D实现不需要做这种手工适配,逻辑非常简单:
- 只要前一层输出的通道数(即上一层的filter数量,本场景下对应池化后的6个通道)和当前Conv2D层声明的输入通道数匹配,不管当前层设置多少个输出filter,都会默认让每个输出filter和全部输入通道做卷积运算,最终输出对应数量的特征图。
举个实际例子:本场景下输入通道为6,设置输出16个filter,框架会自动给每个filter生成尺寸为[卷积核高, 卷积核宽, 6]的权重,每个filter扫过全部6个输入特征图计算后得到1张输出特征图,最终输出总通道数为16。
PyTorch自定义映射适配方法
如果需要复刻LeNet5的特殊映射规则,不需要修改框架底层,有两种常见实现方案:
- 方案1:拆分输入通道,分别给不同输出filter做卷积,最后拼接所有输出特征图。比如给需要输入3个连续通道的filter单独提取对应通道的输入做卷积,再和其他组的输出合并。
- 方案2:使用
nn.Conv2d初始化卷积层后,手动给不需要参与计算的输入通道对应的权重置0,同时冻结这部分权重的更新,等价于只和指定子集的输入通道做运算。示例代码片段如下:
import torch import torch.nn as nn # 定义输入6通道,输出16通道,卷积核大小5的卷积层 conv = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5) # 比如让第0个输出filter只和前3个输入通道卷积,后3个通道权重置0并冻结 with torch.no_grad(): conv.weight[0, 3:, :, :] = 0 conv.weight[0, 3:, :, :].requires_grad = False
TensorFlow/Keras自定义映射适配方法
TensorFlow的逻辑和PyTorch完全一致,默认全通道卷积,要实现自定义映射也有两种成熟方案:
- 方案1:用
tf.gather筛选指定通道的输入特征图,分别送入不同的卷积计算分支,最后拼接所有分支的输出特征图。 - 方案2:自定义卷积核的初始化逻辑和权重约束,让不需要参与计算的位置权重始终为0,达到只和指定输入通道卷积的效果。
补充说明
LeNet5的手工映射规则是早年算力不足情况下的特殊优化,现在绝大多数场景下直接用框架默认的全通道卷积即可,不需要针对输入输出的filter数量做特殊适配,泛用性更强。
内容的提问来源于stack exchange,提问作者LambdaDelta34
相关产品推荐
相关产品推荐


