参考论文: http://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/44872.pdf
参考代码: https://github.com/amdegroot/ssd.pytorch
SSD作为one-stage的目标检测算法,与Faster-RCNN这类的two-stage算法相比,可以在一个神经网络中实现端到端的训练,而不用事先通过RPN网络选出候选框,再用另一个网络做分类和回归。
因此在我看来,SSD主要包括两个核心部分:第一是SSD模型结构,包括他的输入输出,中间的layer等等,由于SSD是one-stage算法,如果对模型结构了解就算成功了一半;第二是SSD的Loss,要实现端到端训练,合理的Loss是必不可少的,而这里的MultiBoxLoss比较复杂,因此这一块可以作为第二个核心部分。
那么就基于这两个核心部分,依次谈一下我看论文和跑代码后一些粗浅的理解。
1. SSD模型结构
论文中的SSD的模型图如下所示:
从图中可以看出,SSD模型主要三个部分(不要看最后的NMS):
- 预训练好的VGG16模型(图中虚线立方体内),去除掉最后用于分类的fully connected层(关于中间pool5的stride和conv4_3后的L2 Norm这种细节可以先忽略);
- 接在VGG16后面的Extra Feature Layer,即图中VGG后面的各种卷积层;
- 模型的输出部分MultiBox Layer,即图中六个黑色箭头指向的Layer,这一层用于得到模型的输出(图中方框里的文字不用管)。
在VGG16网络中,没有被修改的Layer可直接拿来预训练的参数使用。这里的VGG16将后面的Classifier砍掉,此时的最后一层为Conv5_3(图中未标出)。值得注意的是,VGG中的Conv4_3特征图需要拿出来,输入到模型最后的MultiBox Layer。
Extra Layer包括若干个卷积层block,在每一个block最后的卷积层处,将kernal的stride设定为2(其余stride为1),这样就会得到长宽缩小到一半的小特征图。经过几个这样的block,就可以得到不同尺度的feature map。图中将Conv7, Conv8_2, Conv9_2, Conv10_2, Pool11这五个不同尺度特征图拿出来,与之前VGG网络中的特征图Conv4_3,一并送到模型的MultiBox Layer搞一些事情。
模型的输出部分可以称为MultiBox Layer,其目的是根据前面得到的六张Feature Map,生成一系列的候选Box。假设特征图的尺寸为m∗nm*nm∗n,数据集中的类别有c类(包括背景类),box的位置信息为(x,y,w,h)的四元组,那么一个box对应的参数有(c+4)个。我们知道,特征图中每一个像素称为一个cell,一个cell上面可以根据不同的ratio选取若干个box(与Faster RCNN中anchor的选取类似,ratio和先验框尺度的选取可以参照上述论文),这里假设一个cell能产生k个box。因此,这一张Feature map选出的box的个数为mnk,所有的参数总量为mnk*(c+4)。
关于k的选取,从前到后六张特征图依次取4,6,6,6,4,4。因此训练阶段一张输入image可以得到38∗38∗4+19∗19∗6+10∗10∗6+5∗5∗6+3∗3∗4+1∗1∗4=873238*38*4+19*19*6+10*10*6+5*5*6+3*3*4+1*1*4=873238∗38∗4+