SSD原理及Pytorch代码解读——网络架构(一):基础结构

基础VGG结构

SSD采用VGG16作为基础网络,并在其基础上做了一些改动,如下图所示。输入图像经过预处理后大小固定为300×300,首先经过VGG16网络的前13个卷积层,然后利用两个卷积Conv 6与Conv 7取代了原来的全连接网络,进一步提取特征。
在这里插入图片描述与原来的VGG16的网络结构相比,主要的改动在这三个方面:

  1. 使用两个卷积模块Conv 6与Conv 7取代了原来的全连接网络。
  2. 原始的VGG 16的池化层统一大小为2×2,步长为2(这样设计使得特征图经过conv层不改变特征图的尺寸,经过pool层特征图尺寸会缩小到原来的一半),而在SSD中,Conv 5后接的Maxpooling层池化大小为3,步长为1,这样做可以在增加感受野的同时,维持特征图的尺寸不变。
  3. Conv 6中使用了空洞数为6的空洞卷积,其padding也为6,这样做同样也是为了增加感受野的同时保持参数量与特征图尺寸的不变。

深度卷积层

在VGG 16的基础上,SSD进一步增加了4个深度卷积层,用于更高语义信息的提取,如下图所示。可以看出,Conv 8的通道数为512,而Conv 9、Conv 10与Conv 11的通道数都为256。从Conv 7到Conv 11,这5个卷积后输出特征图的尺寸依次为19×19、10×10、5×5、3×3和1×1。
在这里插入图片描述为了降低参数量,在此使用了1×1卷积先降低通道数为该层输出通道数的一半,再利用3×3卷积进行特征提取。

整个SSD的网络结构图如下(特征图尺寸以通道优先模式表示):
在这里插入图片描述

源码

SSD的基础网络代码主要在ssd.py中,具体如下:

基础VGG结构

# 这里的base为VGG-16前13个卷积层构造,M代表maxpooling,C代表ceil_mode为True, 数字是ConV2d的输出通道数
base = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'C', 512, 512, 512, 'M',
            512, 512, 512]
            
def vgg(cfg, i, batch_norm=False):
	"""
	建立VGG基础结构
	parameter:
		cfg:每一层的结构信息,即base列表
		i: 初始通道数
		batch_norm:是否接上BN层
	return:
		layers:vgg基础结构列表
	"""
    layers = []
    in_channels = i
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        elif v == 'C':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
            in_channels = v
    pool5 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
    conv6 = nn.Conv2d(512, 1024, kernel_size=3, padding=6, dilation=6)
    conv7 = nn.Conv2d(1024, 1024, kernel_size=1)
    layers += [pool5, conv6,
               nn.ReLU(inplace=True), conv7, nn.ReLU(inplace=True)]
    return layers

深度卷积层

# 额外部分的卷积通道数,S代表了步长为2,其余卷积层默认步长为1, 数字是ConV2d的输出通道数
extras = [256, 'S', 512, 128, 'S', 256, 128, 256, 128, 256]

# 额外的深度卷积层构造函数
def add_extras(cfg, i, batch_norm=False):
    """
	建立VGG基础结构
	parameter:
		cfg:每一层的结构信息,即extras列表
		i: 初始通道数
		batch_norm:是否接上BN层
	return:
		layers:深度卷积层结构列表
	"""
    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

Guess you like

Origin blog.csdn.net/weixin_41693877/article/details/107501715