- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
问题:在上一章代码中是ResNeXt-50的残差单元,问题:如果conv shortcut=False那么在执行“x=Add0)…“语句时,通道数不一致的,为什么不会报错?
思路:
当conv_shortcut=False时,shortcut直接取x,也就是输入张量。然后x经过第一个1x1卷积,输出的通道数是filters,接着是分组卷积。假设分组卷积后的通道数是filters,那么最后的1x1卷积将filters通道转换为filters2,因为最后的Conv2D层是filters2。
那如果输入x的通道数原本是filters2,而经过第一层1x1卷积后变成filters,再分组卷积可能还是filters,然后最后一层1x1转成filters2,这样最终x的通道数是filters2,而shortcut是输入的x,假设输入x的通道数也是filters2,那么它们的通道数一致,Add操作没问题。
但问题在于,当conv_shortcut=False时,通常意味着输入的通道数和输出的通道数一致,所以不需要用1x1卷积调整。比如在ResNet中,当strides=1时,输入和输出通道数相同,所以不需要shortcut卷积。这时候ResNeXt的结构可能也类似。例如,ResNeXt的每个stage中的第一个block可能使用conv_shortcut=True来调整通道数和尺寸,而后续的block使用conv_shortcut=False,此时输入和输出通道数一致,所以Add操作不会出错。
在ResNeXt-50中,每个stage的block数可能不同,第一个block需要调整通道数,后面的不需要。所以当conv_shortcut=False时,输入x的通道数已经等于输出的通道数,因此可以直接相加,不会报错。考虑到如下几种情况:
1. conv_shortcut=False
的使用场景
在ResNeXt中,conv_shortcut=False
通常出现在同一特征图尺寸的残差块(如每组块中的非首个块)。此时,输入和输出的通道数已经匹配,无需通过1×1
卷积调整通道数。
例如,ResNeXt-50的结构中,每个stage的第一个残差块会使用conv_shortcut=True
来调整通道数(如从64→128),而后续块则使用conv_shortcut=False
,输入和输出通道数一致,因此不会触发通道不匹配的问题。
2. ResNeXt的通道数设计
ResNeXt的残差单元输出通道数为filters×2
(通过最后一层Conv2D(filters×2, 1×1)
实现)。当conv_shortcut=False
时,输入张量x
的通道数应已经为filters×2
,与输出通道数一致。例如:
- 输入张量通道数为
256
(假设filters=128
) - 残差单元输出通道数也是
256
(filters×2=128×2
)
此时Add
操作的两个输入(x
和shortcut
)通道数相同,不会报错。
3. 代码中的隐含条件
代码本身要求调用者在conv_shortcut=False
时保证输入x
的通道数与残差单元的输出通道数一致。如果调用者违反了这一条件(例如误传了通道数不匹配的输入),仍然会触发错误。
例如,若输入张量通道数为64
,filters=128
且conv_shortcut=False
,则:
shortcut = x
的通道数为64
- 残差路径输出的通道数
为128×2=256
- 此时
Add
操作会因通道数不匹配而报错。
问题:conv_shortcut 为 False 时,输入通道数如何设置?
在 ResNeXt 的残差单元中,当 conv_shortcut=False
时,输入张量的通道数需要与残差单元的输出通道数一致。这是通过网络的设计和残差单元的参数设置来确保的。
ResNeXt 的输出通道数计算
ResNeXt 的残差单元输出通道数为 filters * 2
,这是因为在残差单元的最后一步使用了一个 1×1
卷积,将通道数从 filters
增加到 filters * 2
。
输入通道数的要求
当 conv_shortcut=False
时,输入张量的通道数应已经为 filters * 2
。这是因为:
- 残差单元的输出通道数为
filters * 2
shortcut
路径直接使用输入张量x
因此,只有当输入张量的通道数为 filters * 2
时,Add
操作才能正确执行。
如何设置输入通道数
在 ResNeXt 的典型实现中,输入通道数是通过网络结构的设计来确保的。例如:
ResNeXt-50 的结构
ResNeXt-50 通常包含 4 个阶段(stage),每个阶段包含多个残差单元:
- Stage 1: 卷积核大小为
7×7
,输出通道数为64
- Stage 2: 包含 3 个残差单元,输出通道数为
128
- Stage 3: 包含 4 个残差单元,输出通道数为
256
- Stage 4: 包含 6 个残差单元,输出通道数为
512
- Stage 5: 包含 3 个残差单元,输出通道数为
1024
在每个阶段的第一个残差单元中,通常会使用 conv_shortcut=True
来调整通道数(例如,从 64
调整到 128
)。而在同一阶段的后续残差单元中,conv_shortcut=False
,输入通道数与输出通道数一致。
示例:Stage 2 的第一个和第二个残差单元
假设在 Stage 2 中,filters=64
,输出通道数为 filters * 2 = 128
。
第一个残差单元:
- 输入通道数为
64
- 使用
conv_shortcut=True
,通过1×1
卷积将通道数从64
调整到128
- 输出通道数为
128
- 输入通道数为
第二个残差单元:
- 输入通道数为
128
(与输出通道数一致) - 使用
conv_shortcut=False
- 输出通道数为
128
- 输入通道数为