这两天把SSD论文读了一下,SSD也是一个端到端的目标检测模型,SSD在检测的准确率和速度上相对于YOLO有了很大的提高,并且在检测小目标上也有不俗的效果。
1. 使用多尺度特征图进行预测
大多数目标检测算法都是使用最后一层特征图进行目标位置和类别的确定,但是这样有个缺点就是高层次的特征图对小物体的特征信息丢失严重,导致对小目标检测效果不好,这也时YOLO对小目标检测不好的原因之一。所以,SSD不仅使用高层的特征图进行预测,还是用了低层的特征图进行预测。高层的特征图主要负责大目标,底层的特征图负责小目标。
SSD网络结构如图1所示:可以看到新增加的特征图大小逐渐减小,而且每个特征图的每个卷积核是相互独立的。
2. 使用卷积进行预测;
SSD直接在特征图上使用卷积进行目标位置和类别的预测。对于一个形状为 ( m × n × p ) (m\times n \times p) (m×n×p)的特征图来说,只需要 ( 3 × 3 × p ) (3 \times 3 \times p) (3×3×p)的小卷积核进行分类和位置的计算。
卷积核在特征图 ( m × n ) (m\times n) (m×n)的每一个位置上都会产生 ( c + 1 + 4 ) (c+1+4) (c+1+4)个输出值,其中c是类别的个数,加1是因为背景算一个类别,4是位置信息;位置信息包含 ( c x , c y , d w , d h ) (cx,cy,dw,dh) (cx,cy,dw,dh),前两个表示框的中心点坐标,后两个表示框的长和宽,但是这里的预测值是相对于先验框的转换值。
假设先验框的位置用 d = ( d x , d y , d w , d h ) d=(d^{x},d^{y},d^{w},d^{h}) d=(dx,dy,dw,dh)表示,边界框的位置用 b = ( b x , b y , b w , b h ) b=(b^{x},b^{y},b^{w},b^{h}) b=(bx,by,bw,bh)表示,则该边界框的预测值用 l = ( l x , l y , l w , l h ) l=(l^{x},l^{y},l^{w},l^{h}) l=(lx,ly,lw,lh)表示。转换关系为:
l x = ( b x − d x ) ÷ d w l^{x}=(b^{x}-d^{x})\div d^{w} lx=(bx−dx)÷dw l y = ( b y − d y ) ÷ d h l^{y}=(b^{y}-d^{y})\div d^{h} ly=(by−dy)÷dh l w = log ( b w / d w ) l^{w}=\log(b^{w}/d^{w}) lw=log(bw/dw) l h = log ( b h / d h ) l^{h}=\log(b^{h}/d^{h}) lh=log(bh/dh)
从边界框的真实值到转换值的过程常称为编码;从转换值到真实值是解码的过程;解码关系:
b x = l x × d w + d x b^{x}=l^{x}\times d^{w} +d^{x} bx=lx×dw+dx b y = l y × d h + d y b^{y}=l^{y}\times d^{h} +d^{y} by=ly×dh+dy b w = exp ( l w ) d w b^{w}=\exp(l^{w})d^{w} bw=exp(lw)dw b h = exp ( l h ) d h b^{h}=\exp(l^{h})d^{h} bh=exp(lh)dh
3. 先验框和宽高比
SSD的先验框和FasterRCNN的anchor box相似,不同的是在不同的特征图上应用不同大小的默认框,这样做的目的是有效的离散化输出框的形状,以满足真实目标形状多变的情况。
对于一个大小为 m × n m\times n m×n的特征图来说,特征图的每个单元需要 k k k个先验框,则该特征图需要 m n k ( c + 4 ) mnk(c+4) mnk(c+4)个卷积核。
1. 网络结构
SSD使用VGG16网络结构,并且在ILSVRC CLS-LOC训练集上进行预训练,但是将fc6和fc7换成了卷积层,从网络结构图中可以看到conv_6的卷积核大小为 3 × 3 3\times 3 3×3,conv_7的卷积核大小为 1 × 1 1\times 1 1×1。并且将pool5的核大小由stride=2, 2 × 2 2\times 2 2×2改为stride=1, 3 × 3 3\times 3 3×3,同时在预训练过程中使用多孔卷积(atrous algorithm),以增加感受野的大小。除此之外,移除了所有的drop_out。至于超参数的设定,详见论文。
2. 先验框的匹配策略
在训练之前,需要确定图片中GT Box(ground truth)与哪个先验框匹配,与之匹配的先验框所对应的边界框负责去计算和GTBox的位置损失,边界框(说白了就是预测框)以先验框为基准,降低了训练难度;在YOLO中,由于没有先验框,单元框直接预测K个边界框去拟合真实框,并选择与真实框IOU最大的边界框进行预测,使得YOLO模型在训练中需要自拟合不同物体的多种形状,提高了训练的难度。
先验框的大小随着不同的位置(此位置我理解的是不同的特征图)、长宽比和尺度而不断变化。
匹配的策略:首先选择与GT Box具有最大IOU的先验框作为正样本;其次,若某个先验框的的IOU>0.5,也认为是正样本。这样使得网络可以对多个先验框进行预测,可以预测目标的多种形状。
当先验框个数很多时,正负样本之间的数量可能非常不平衡,SSD使用Hard Negative Mining方法将一些负样本改为正样本,使正负样本比例在1:3左右。
Hard Negative Mining方法:首先计算所有先验框的loss,然后从负样本中对分类loss降序排列,因为负样本不计算位置Loss;选择前m个负样本,使得正负样本比例在1:3;将m个负样本设为正样本,即计算它的分类Loss,然后进行反向传播。
3.先验框尺度和长宽比的选择
为了处理不同物体大小的尺度问题,一些方法是用不同的尺寸的图像进行训练,然后将结果结合起来。但是SSD将不同层的特征图整合起来以达到同样的效果。
假设使用m个特征图进行预测,则每个特征图先验框的尺度大小为:
s k = s m i n + s m a x − s m i n m − 1 ( k − 1 ) , k ∈ [ 1 , m ] s_k=s_{min}+{s_{max}-s_{min}\over {m-1}}(k-1),k\in [1,m] sk=smin+m−1smax−smin(k−1),k∈[1,m]
可以看到随着特征图大小的减小,先验框尺度线性增加,m是指特征图的个数, s m i n , s m a x s_{min},s_{max} smin,smax表示比例的最小值和最大值。SSD中 s m i n = 0.2 , s m a x = 0.9 s_{min}=0.2,s_{max}=0.9 smin=0.2,smax=0.9,在实际计算中,先求尺度增长的步长,[ [ s m a x × 100 ] − [ s m i n × 100 ] m − 1 {[s_{max}\times 100]}-[s_{min}\times 100]\over {m-1} m−1[smax×100]−[smin×100]],[]代表结果向下取整。[ [ 0.9 × 100 ] − [ 0.2 × 100 ] 5 − 1 {[0.9\times 100]}-[0.2\times 100]\over {5-1} 5−1[0.9×100]−[0.2×100]]=17, s 1 = 0.2 ∗ 100 = 20 s_1=0.2*100=20 s1=0.2∗100=20,即 s k = 20 , 37 , 54 , 71 , 88 s_k=20,37,54,71,88 sk=20,37,54,71,88。将这些比例除以100,然后再乘以图片大小,可以得到各个特征图的尺度为, s k = 60 , 111 , 162 , 213 , 264 s_k=60,111, 162,213,264 sk=60,111,162,213,264,根据SSD的caffe源码,conv4_3比较特殊 s = s m i n × 300 / 2 / 100 = 30 s=s_{min}\times 300/2/100=30 s=smin×300/2/100=30。所以,SSD中每个特征图的先验框实际尺度是30,60,111, 162,213,264。
对于长宽比的设定, a r ∈ { 1 , 2 , 3 , 1 2 , 1 3 } a_r\in \{ 1,2,3,{1\over2},{1\over3}\} ar∈{1,2,3,21,31},然后可以计算出相应的长和宽, w k = s k a r w_k=s_k\sqrt{a_r} wk=skar, h k = s k a r h_k={s_k\over\sqrt{a_r}} hk=arsk。除此之外,还会设置一个尺度为 s m ∗ = s m s m + 1 s^*_m=\sqrt{s_ms_{m+1}} sm∗=smsm+1且 a r = 1 a_r=1 ar=1的先验框, s m + 1 = 300 ∗ ( 105 ) / 100 s_{m+1}=300*(105)/100 sm+1=300∗(105)/100,这样特征图每个单元会对应两个大小不同的正方形先验框,共有6个不同长宽比的先验框 a r ∈ { 1 , 2 , 3 , 1 2 , 1 3 , 1 ∗ } a_r\in \{ 1,2,3,{1\over2},{1\over3},1^*\} ar∈{1,2,3,21,31,1∗}。在SSD训练过程中,conv4,conv10,conv11仅使用了4个先验框,舍弃了 1 3 , 3 {1\over3},3 31,3的长宽比。而且每个先验框的中心就是每个单元框的中心,( i + 0.5 m , j + 0.5 m {{i+0.5}\over m},{{j+0.5}\over m} mi+0.5,mj+0.5), i , j ∈ [ 0 , m ) i,j\in[0,m) i,j∈[0,m),m是特征图的大小。
4. 损失函数
SSD采用的损失函数与YOLO损失函数基本相同,总的损失函数是位置Loss和分类Loss的加权求和。
L ( x , c , l , g ) = 1 N ( L c o n f ( x , c ) + α L l o c ( x , l , g ) ) L(x,c,l,g)={1\over N}(L_{conf}(x,c)+\alpha L_{loc}(x,l,g)) L(x,c,l,g)=N1(Lconf(x,c)+αLloc(x,l,g))
其中,N是正样本数量; α = 1 \alpha=1 α=1通过交叉验证得到。
位置Loss只计算正样本,并且GTBox需要进行编码,因为预测值是编码值。 x i , j k x^k_{i,j} xi,jk表示第i个先验框与第j个真实框匹配,并且真实框的类别为k。 x i , j k ∈ { 0 , 1 } x^k_{i,j}\in\{0,1\} xi,jk∈{0,1}
预测相对简单,根据置信度确定每个预测框的类别,并将背景框去掉,然后从剩下的预测框中留下置信度大于阈值的预测框,并对其进行解码,根据先验框得到真实的位置(需要clip,防止超过图片的大小)。根据置信度进行降序排列,然后仅保留top-k(如400)个预测框。最后就是进行NMS算法,过滤掉那些重叠度较大的预测框,剩余的预测框就是检测结果了。
目标检测|SSD原理与实现