共计 2357 个字符,预计需要花费 6 分钟才能阅读完成。
背景介绍
1×1 卷积(Pointwise Convolution)是深度学习中一种特殊的卷积操作,它的卷积核大小为 1 ×1。虽然看起来简单,但在 CNN 中扮演着重要角色:

- 通道变换:可以灵活地增加或减少特征图的通道数
- 降维 / 升维:通过控制输出通道数实现特征空间的压缩或扩展
- 跨通道信息整合:在不改变空间分辨率的情况下混合通道信息
- 计算高效:相比大卷积核,计算量大幅减少
数学推导
前向传播
对于输入特征图 $X \in \mathbb{R}^{C_{in}\times H\times W}$,1×1 卷积核 $W \in \mathbb{R}^{C_{out}\times C_{in}}$,前向计算公式为:
$$
Y_{c_{out}} = \sum_{c_{in}=1}^{C_{in}} W_{c_{out},c_{in}} \ast X_{c_{in}}
$$
其中 $\ast$ 表示互相关运算(实际实现的卷积操作)。
反向传播
根据链式法则,我们需要计算三个梯度:
-
对输入的梯度:
$$
\frac{\partial L}{\partial X_{c_{in}}} = \sum_{c_{out}=1}^{C_{out}} W_{c_{out},c_{in}} \ast \frac{\partial L}{\partial Y_{c_{out}}}
$$ -
对权重的梯度:
$$
\frac{\partial L}{\partial W_{c_{out},c_{in}}} = \sum_{i,j} X_{c_{in}}[i,j] \cdot \frac{\partial L}{\partial Y_{c_{out}}}[i,j]
$$ -
对偏置的梯度(如果使用偏置项):
$$
\frac{\partial L}{\partial b_{c_{out}}} = \sum_{i,j} \frac{\partial L}{\partial Y_{c_{out}}}[i,j]
$$
PyTorch 实现
import torch
import torch.nn as nn
class Conv1x1(nn.Module):
def __init__(self, in_channels, out_channels, bias=True):
super().__init__()
self.weight = nn.Parameter(torch.randn(out_channels, in_channels, 1, 1))
if bias:
self.bias = nn.Parameter(torch.zeros(out_channels))
else:
self.register_parameter('bias', None)
def forward(self, x):
# x shape: [N, C_in, H, W]
# weight shape: [C_out, C_in, 1, 1]
out = torch.nn.functional.conv2d(x, self.weight, self.bias, stride=1, padding=0)
return out
def backward(self, grad_output):
# grad_output shape: [N, C_out, H, W]
# 计算对输入的梯度
grad_input = torch.nn.functional.conv_transpose2d(grad_output, self.weight, None, stride=1, padding=0)
# 计算对权重的梯度
grad_weight = torch.nn.functional.conv2d(self.input.transpose(0, 1),
grad_output.transpose(0, 1).contiguous(),
None,
stride=1,
padding=0
).transpose(0, 1)
# 计算对偏置的梯度
if self.bias is not None:
grad_bias = grad_output.sum(dim=(0, 2, 3))
else:
grad_bias = None
return grad_input, grad_weight, grad_bias
对比分析
| 对比项 | 1×1 卷积 | 3×3 卷积 |
|---|---|---|
| 每位置计算量 | $C_{in} \times C_{out}$ | $9 \times C_{in} \times C_{out}$ |
| 内存占用 | 低(仅存储 1 ×1 核) | 高(存储 3 ×3 核) |
| 感受野 | 1×1 | 3×3 |
| 反向传播复杂度 | $O(C_{in}C_{out}HW)$ | $O(9C_{in}C_{out}HW)$ |
避坑指南
- 梯度清零:在 PyTorch 中每次 backward 前记得
optimizer.zero_grad() - 通道匹配:确保输入输出通道数合理,避免维度不匹配
- 初始化问题:1×1 卷积核也需要合理初始化(如 Kaiming 初始化)
- BN 层配合:通常 1 ×1 卷积后接 BN 层加速训练
性能优化
使用 groups 参数可以实现通道分组计算,大幅减少计算量:
# 分组卷积实现
conv = nn.Conv2d(in_channels=256, out_channels=256,
kernel_size=1, groups=4) # 将 256 通道分为 4 组
思考题
- 1×1 卷积能否完全替代全连接层?
- 在全连接层输入输出尺寸匹配时理论上可以,但实际应用中 FC 层更擅长全局特征整合
-
1×1 卷积保持了空间信息,FC 层会丢失空间结构
-
ResNet 的 bottleneck 结构中 1 ×1 卷积的作用
- 第一个 1 ×1 卷积:降维减少计算量
- 中间 3 ×3 卷积:空间特征提取
- 最后一个 1 ×1 卷积:恢复通道维度
- 整体实现了 ” 压缩 - 处理 - 扩展 ” 的高效计算模式
总结
1×1 卷积虽然结构简单,但理解其反向传播机制对掌握 CNN 工作原理至关重要。通过手动实现可以加深对梯度流动的理解,在实际应用中灵活使用 1 ×1 卷积能显著提升模型效率。建议初学者多尝试用不同参数配置观察其对网络的影响。
