多通道的输入输出
深入理解多通道卷积操作原理,掌握多输入多输出卷积层的实现方法和1×1卷积的应用技巧

展开文章目录
在之前的案例中,我们只使用了单通道演示卷积操作,但在实际应用中,更多情况是以 RGB 的色彩模式处理图像数据。因此,我们需要考虑数据维度为 的多通道情况。
1. 多通道输入
1.1 计算过程
以双通道输入为例:

1.2 代码实现
下面的实现复用了互相关运算中的 corr2d() 函数来演示多通道卷积:
import torch
def corr2d(X, K):
"""二维互相关运算"""
h, w = K.shape
Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
return Y
# 双通道输入数据
i = torch.tensor([[[0., 1., 2.],
[3., 4., 5.],
[6., 7., 8.]],
[[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]]]) # (2, 3, 3)
# 双通道卷积核
k = torch.tensor([[[0., 1.],
[2., 3.]],
[[1., 2.],
[3., 4.]]]) # (2, 2, 2)
# 多通道卷积计算
temp = torch.stack([corr2d(c_i, c_k) for c_i, c_k in zip(i, k)]) # 三维中间结果
result = temp.sum(dim=0) # 二维特征图
print(f'输入形状: {i.shape}')
print(f'卷积核形状: {k.shape}')
print(f'中间结果形状: {temp.shape}')
print(f'最终输出形状: {result.shape}')
print(f'\n输出结果:\n{result}')
查看输出结果
输入形状: torch.Size([2, 3, 3])
卷积核形状: torch.Size([2, 2, 2])
中间结果形状: torch.Size([2, 2, 2])
最终输出形状: torch.Size([2, 2])
输出结果:
tensor([[ 56., 72.],
[104., 120.]])2. 多通道输出
实际上,每个卷积层中的 个卷积核(形状为 )以堆栈 (stack) 的方式组织成一个大的卷积核(形状为 )。
2.1 网络演化规律
2.2 协同优化
在网络训练的过程中,卷积层与卷积层之间、卷积层内部各个卷积核之间的参数更新是以整体网络性能的提升而协同优化的。
2.3 代码示例
import torch
# 双通道输入数据(与之前相同)
i = torch.tensor([[[0., 1., 2.],
[3., 4., 5.],
[6., 7., 8.]],
[[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]]]) # (2, 3, 3)
# 定义三个不同的卷积核
k0 = torch.tensor([[[0., 1.],
[2., 3.]],
[[1., 2.],
[3., 4.]]]) # (2, 2, 2)
k1 = k0 + 1 # 每个元素加1
k2 = k0 + 2 # 每个元素加2
# 将三个卷积核堆叠为多输出通道
k_stack = torch.stack((k0, k1, k2)) # (3, 2, 2, 2)
# 计算多输出通道的卷积
def multi_in_out_corr2d(X, K):
"""多输入多输出卷积"""
return torch.stack([torch.stack([corr2d(c_x, c_k) for c_x, c_k in zip(X, k)]).sum(dim=0)
for k in K])
result = multi_in_out_corr2d(i, k_stack)
print(f'输出通道数: {result.shape[0]}')
print(f'输出形状: {result.shape}')
print(f'输出结果:\n{result}')
查看输出结果
输出通道数: 3
输出形状: torch.Size([3, 2, 2])
输出结果:
tensor([[[ 56., 72.],
[104., 120.]],
[[ 76., 100.],
[148., 172.]],
[[ 96., 128.],
[192., 224.]]])3. 1×1 卷积层
以 3 通道输入、2 通道输出的 1×1 卷积层为例:

3.1 1×1 卷积的主要作用
1x1卷积作用
降维与升维
在不改变输出的空间维度前提下,调整卷积核数量改变输出通道数,实现降维与升维。可以在处理较大卷积核时作为”瓶颈层”,减小计算量或提高模型的表达能力。
线性组合通道信息
通过对每个像素位置的通道值加权求和,(与全连接层类似)实现通道间的线性组合。
增加非线性特征的表达能力
与非线性激活函数(如 ReLU)联用后,能增加网络的非线性特征表达能力。
3.2 代码实现
1×1 卷积层可以直接用 torch.nn.Conv2d 实现:
import torch
import torch.nn as nn
# 创建输入数据:(batch_size, channels, height, width)
input_data = torch.randn(1, 3, 32, 32)
# 定义1×1卷积层:3个输入通道 -> 64个输出通道
conv_1x1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=1)
# 前向传播
output = conv_1x1(input_data)
print(f'输入形状: {input_data.shape}')
print(f'输入通道数: {input_data.shape[1]}')
print(f'输出形状: {output.shape}')
print(f'输出通道数: {output.shape[1]}')
查看输出结果
输入形状: torch.Size([1, 3, 32, 32])
输入通道数: 3
输出形状: torch.Size([1, 64, 32, 32])
输出通道数: 64参考资料
如果这篇记录对你有帮助,可以留下一句回应。

DISCUSSION
讨论与回应
欢迎补充细节、指出问题,或分享与这篇文章有关的经验。
昵称与邮箱为必填项,邮箱仅用于头像和回复通知,不会公开。网址可以留空。