def add_extras(cfg, i, batch_norm=False):
# Extra layers added to VGG for feature scaling
layers = []
in_channels = i
flag = False
for k, v in enumerate(cfg):
if in_channels != 'S':
if v == 'S':
layers += [nn.Conv2d(in_channels, cfg[k + 1],
kernel_size=(1, 3)[flag], stride=2, padding=1)]
else:
layers += [nn.Conv2d(in_channels, v, kernel_size=(1, 3)[flag])]
flag = not flag
in_channels = v
return layers
这一块代码是用来定义SSD模型中的额外层的,也就是在VGG主干网络之后添加的一些卷积层,用来提取不同尺度的特征图,从而实现多尺度的目标检测。这些额外层的结构和参数由cfg参数指定,其中"S"表示需要进行降采样的卷积层,其余的表示输出通道数。这一块代码的功能是根据cfg参数,循环地添加卷积层,并将它们存储在一个列表layers中,最后返回这个列表。具体来说:
- 定义一个空列表layers,用来存储额外层
- 定义一个布尔变量flag,用来控制卷积核的大小,初始为False
- 对cfg参数进行遍历,每次取出一个元素v
- 如果当前的输入通道数in_channels不等于"S",说明还没有到达降采样的卷积层
- 如果v等于"S",说明当前需要添加一个降采样的卷积层,其输出通道数为cfg中下一个元素,其卷积核大小为(1, 3)中由flag决定的一个值,其步长为2,其填充为1
- 如果v不等于"S",说明当前需要添加一个普通的卷积层,其输出通道数为v,其卷积核大小为(1, 3)中由flag决定的一个值
- 将添加的卷积层加入到layers列表中
- 将flag取反,以便下一次循环时切换卷积核大小
- 将输入通道数in_channels更新为v
这样,当遍历完cfg参数后,就得到了一个包含所有额外层的列表layers。
一些断点测试,便于更加了解代码。
1.打印cfg和最后返回的layers
extra layers cfg: [256, 'S', 512, 128, 'S', 256, 128, 256, 128, 256]
extra layers:
[Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1)),
Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)),
Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1)),
Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)),
Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1)),
Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1)),
Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1)),
Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1))]
为什么这个额外层可以提取不同尺度的特征图?
这样一个额外层可以提取不同尺度的特征图,是因为它使用了不同的步长和卷积核大小,来对上一层的特征图进行降采样,从而得到更小的特征图。这些更小的特征图相当于具有更大的感受野,可以覆盖更大范围的原始图像,因此可以检测到更大尺寸的目标。同时,这些额外层也保留了一定的空间分辨率和语义信息,可以提供足够的细节来定位目标。
对于cfg配置文件和返回的额外层是这样的实例,能提取以下不同尺度的特征图:
Layer | Feature map size |
---|---|
Conv8_2 | 19 x 19 |
Conv9_2 | 10 x 10 |
Conv10_2 | 5 x 5 |
Conv11_2 | 3 x 3 |
Conv12_2 | 2 x 2 |
Conv13_2 | 1 x 1 |
这些特征图的尺寸是由额外层中的卷积层的步长和填充决定的,其中"S"表示步长为2的卷积层,用来降采样特征图。例如,Conv8_2是从Conv7_2(38 x 38)降采样得到的,因为它的步长为2,所以特征图尺寸减半为19 x 19。同理,Conv9_2是从Conv8_2降采样得到的,因此尺寸为10 x 10。而Conv10_2到Conv13_2之间的卷积层都没有降采样,只是改变了通道数,所以特征图尺寸只是逐渐减小1。