【SSD论文解读】 模型部分:骨干网络 VGG16 + 特征提取层 Extra Feature Layers

一、骨干网络

1、原始的骨干网络——VGG16

VGGNet是继AlexNet后的一个隐含层更多的深度卷积神经网络。VGGNet结构根据层数的不同有不同的版本,常用结构是VGG16和VGG19。SSD使用的是VGG16。

VGG16有13个卷积层,5个最大池化层以及3个全连接层

  • 卷积层卷积核的大小为3×3,步长为1,通过卷积层可以实现通道数的增加
  • 池化层大小为2×2,步长为2,作用是降低特征图尺寸并能提高网络抗干扰能力
  • 3个全连接层中的前两层通道数为4096,第三层通道数为1000,代表1000个标签类别

所有隐藏层后都带有ReLU非线性激活函数。VGG16网络结构图如下图:
VGG16网络结构图

VGG16网络结构图

2、SSD对VGG16的改进

【论文内容】
论文第7页
论文第7页

  • 为了能够与在骨干网络之后增加特征提取层,将全连接层fc6和fc7转换为卷积层conv6和conv7,并对fc6和fc7的参数进行二次采样,并移除了fc8层
  • 将池化层pool5从2×2大小,步长为2更改为3×3大小,步长为1,并使用atrous算法来填充“漏洞”;
  • 由于SSD网络结构移除了VGG16的全连接层,因此防止过拟合的dropout层也被移除
  • 由于conv4_3与其他特征层相比具有不同的特征比例,因此使用L2归一化将特征图中每个位置的特征比例进行缩放,并在反向传播过程中学习该比例。

L1 norm、L2 norm:
L1 norm是绝对值相加,又称曼哈顿距离
L2 norm是平方和,即欧几里德距离之和
L1归一化和L2归一化范数的详解和区别


每一层详细的更改,如图:来源【SSD算法】史上最全代码解析-核心篇
VGG Backbone

3、代码

#数字代表卷积层的通道数,'M'代表普通池化层,'C'代表池化层但ceil_mode=True
cfg= {
   
    '300': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'C', 512, 512, 512, 'M',
            512, 512, 512],
    '512': [],
}
# vgg网络初始通道数为“原图像通道数”:3
i = 3

def vgg(cfg, i, batch_norm=False):
    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

输出骨干网的网络结构,如下所示:

Sequential(
  (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (1): ReLU(inplace)
  (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (3): ReLU(inplace)
  (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (6): ReLU(inplace)
  (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (8): ReLU(inplace)
  (9)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值