物体检测简述
物体检测主流的算法可以分为:
- 基于候选区域的目标检测(Two-Stage):滑动窗口检测器、R-CNN、Fast R-CNN、RPN、F-RCN
- One-Stage(单次)目标检测:SSD、YOLO、YOLOv2、YOLOv3
Two-Stage的主流思想是首先通过启发式算法或者CNN网络产生一系列稀疏的候选框,然后对这些候选框进行分类或者回归。这类算法的优势是准确率高。
One-Stage的思路是均匀地在图片的不同位置进行密集抽样,抽样时可以采用不同尺度和长宽比,然后利用CNN提取特征后直接进行分类与回归,整个过程只需要一步,所以其优势是速度快,但是均匀的密集采样的一个重要缺点是训练比较困难,这主要是因为正样本与负样本(背景)极其不均衡。Yolo算法缺点是难以检测小目标,而且定位不准,但是这几点重要改进使得SSD在一定程度上克服这些缺点。
SSD算法的网络架构
SSD(Single-Shot MultiBox Detector),使用 VGG19 网络作为特征提取器(和 Faster R-CNN 中使用的 CNN 一样)的单次检测器。我们在该网络之后添加自定义卷积层(蓝色),并使用卷积核(绿色)执行预测。
然而,卷积层降低了空间维度和分辨率。因此上述模型仅可以检测较大的目标。为了解决该问题,我们从多个特征图上执行独立的目标检测。
这里需要说明的是:在SSD目标检测算法中大的特征图往往用来检测小的目标物体,而小的特征图用来检测大的物体。这是因为在原始图片经过卷积以后将原本大物体的特征凝聚起来,更容易被检测到,而在大的特征图里面,通过预设定的先验框比例可更容易抓取小物体的特征。
因此若从多个特征图上执行独立的目标检测就可以尽可能的抓取图片内的信息。
以下是特征图所示:
SSD算法的原理
SSD和Yolo一样都是采用一个CNN网络来进行检测,但是却采用了多尺度的特征图。SSD核心设计理念为如下三点:
- 采用多尺度特征图用于检测:如上
- 采用卷积进行检测:与Yolo最后采用全连接层不同,SSD直接采用卷积对不同的特征图来进行提取检测结果。对于形状为 m ∗ n ∗ p m*n*p m∗n∗p 的特征图,只需要采用 3 ∗ 3 ∗ p 3*3*p 3∗3∗p 这样比较小的卷积核得到检测值。
- 设置先验框:SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。
SSD对于每个单元的每个先验框,都输出一套独立的检测值。对应一个边界框,主要分为两个部分:
- 各个类别的置信度或者评分
- 边界框的位置坐标 l l l
边界框的中心坐标、宽和高按如下表示(模型训练中存在放缩):
l
=
(
l
c
x
,
l
c
y
,
l
w
,
l
h
)
l = (l^{cx},l^{cy},l^w,l^h)
l=(lcx,lcy,lw,lh) 先验框的位置(模型训练中存在放缩):
d
=
(
d
c
x
,
d
c
y
,
d
w
,
d
h
)
d = (d^{cx},d^{cy},d^w,d^h)
d=(dcx,dcy,dw,dh)
先验框对应的边界框(现实坐标):
b
=
(
b
c
x
,
b
c
y
,
b
w
,
b
h
)
b = (b^{cx},b^{cy},b^w,b^h)
b=(bcx,bcy,bw,bh),则边界框的预测值
l
l
l 其实是
b
b
b 相对于
d
d
d 的转换值:
l
c
x
=
b
c
x
−
d
c
x
d
w
,
l
c
y
=
b
c
y
−
d
c
y
d
h
l^{cx} = \frac{b^{cx}-d^{cx}}{d^w} , l^{cy} = \frac{b^{cy}-d^{cy}}{d^h}
lcx=dwbcx−dcx,lcy=dhbcy−dcy
l
w
=
l
o
g
b
w
d
w
,
l
w
=
l
o
g
b
h
d
h
l^w = log\frac{b^w}{d^w } ,l^w = log\frac{b^h}{d^h}
lw=logdwbw,lw=logdhbh
如上的过程为边界框的编码(encode),预测时只需要反向这个过程,即进行解码(decode),从预测值
l
l
l 中得到边界框的真实位置
b
b
b 。本质上这个过程就是两个不同量纲坐标系下的坐标转化!
b
c
x
=
d
w
l
c
x
,
b
c
y
=
d
y
l
c
y
+
d
c
y
b^{cx} = d^wl^{cx}, b^{cy}=d^yl^{cy}+d^{cy}
bcx=dwlcx,bcy=dylcy+dcy
b
w
=
d
w
e
x
p
(
l
w
)
,
b
h
=
d
h
e
x
p
(
l
h
)
b^w = d^w exp(l^w), b^h = d^hexp(l^h)
bw=dwexp(lw),bh=dhexp(lh)
总的来说,对于一个大小为 m ∗ n m*n m∗n 的特征图共有 m n mn mn 个单元,每个单元设置的先验框数目记为 l l l,那么每个单元共需要 ( c + 4 ) k (c+4)k (c+4)k 个预测值,所有的单元共需要 ( c + 4 ) k m n (c+4)kmn (c+4)kmn 个预测值,由于SSD采用卷积做检测,所以就需要 ( c + 4 ) k (c+4)k (c+4)k 个卷积核完成这个特征图的检测过程。
先验框的设置,包括尺度(或者说大小)和长宽比两个方面。由于在CNN训练过程中我们能够得到多个特征图,因此根据不同的特征图,先验框的尺度应该成线性变化。
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}+\frac{s_{max}-s_{min}}{m-1}(k-1), k\in [1,m]
sk=smin+m−1smax−smin(k−1),k∈[1,m]
其中
m
m
m是指特征图个数,
s
k
s_k
sk表示先验框大小相对于图片的比例,
s
m
i
n
,
s
m
a
x
s_{min}, s_{max}
smin,smax分别表示比例的最大值和最小值。
对于长宽比,一般选取:
a
r
∈
1
,
2
,
3
,
1
/
2
,
1
/
3
a_r \in {1,2,3,1/2,1/3}
ar∈1,2,3,1/2,1/3,对于特定的长宽比,按照如下公式计算先验框的宽度与高度(后面的
s
k
s_k
sk均指的是先验框实际尺度,而不是尺度比例):
w
k
a
=
s
k
a
r
,
h
k
a
=
s
k
/
a
r
w^a_k=s_k\sqrt{a_r}, h^a_k=s_k/\sqrt{a_r}
wka=skar,hka=sk/ar
每个单元的先验框的中心点分布在各个单元的中心
(
i
+
0.5
∣
f
k
∣
,
j
+
0.5
∣
f
k
∣
)
,
i
,
j
∈
[
0
,
∣
f
k
∣
)
(\frac{i+0.5}{|f_k|},\frac{j+0.5}{|f_k|}), i,j\in [0,|f_k|)
(∣fk∣i+0.5,∣fk∣j+0.5),i,j∈[0,∣fk∣) 其中
∣
f
k
∣
|f_k|
∣fk∣为特征图的大小。
SSD训练过程
先验框匹配
I O U IOU IOU : I O U IOU IOU 的全称为交并比(Intersection over Union),IoU 计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。
在训练过程中,首先要确定训练图片中的ground truth(真实目标)与哪个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它。
在Yolo中,ground truth的中心落在哪个单元格,该单元格中与其IOU最大的边界框负责预测它。但是在SSD中却完全不一样,SSD的先验框与ground truth的匹配原则主要有两点。
- 对于图片中每个ground truth,找到与其IOU最大的先验框,该先验框与其匹配。
- 对于剩余的未匹配先验框,若某个ground truth的 I O U IOU IOU 大于某个阈值(一般是0.5),那么该先验框也与这个ground truth进行匹配。
第一原则可以保证每个ground truth一定与某个先验框匹配。通常称与ground truth匹配的先验框为正样本(其实应该是先验框对应的预测box,不过由于是一一对应的就这样称呼了),反之,若一个先验框没有与任何ground truth进行匹配,那么该先验框只能与背景匹配,就是负样本。一个图片中ground truth是非常少的, 而先验框却很多,如果仅按第一个原则匹配,很多先验框会是负样本,正负样本极其不平衡,所以需要第二个原则。
第二个原则意味着某个ground truth可能与多个先验框匹配,这是可以的。但是反过来却不可以,因为一个先验框只能匹配一个ground truth,如果多个ground truth与某个先验框 I O U IOU IOU 大于阈值,那么先验框只与 I O U IOU IOU最大的那个ground truth进行匹配。
尽管一个ground truth可以与多个先验框匹配,但是ground truth相对先验框还是太少了,所以负样本相对正样本会很多。为了保证正负样本尽量平衡,SSD采用了hard negative mining,就是对负样本进行抽样,抽样时按照置信度误差(预测背景的置信度越小,误差越大)进行降序排列,选取误差的较大的top-k作为训练的负样本,以保证正负样本比例接近1:3。
损失函数(重点)
损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和:
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)=\frac{1}{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
N
N 时先验框的正样本数量,
c
c
c 为类别置信度预测值,
l
l
l 为先验框的所对应边界框的位置预测值,
g
g
g 时ground truch的位置参数。
x
i
j
p
∈
1
,
0
x_{ij}^p\in{1,0}
xijp∈1,0作为一个指示参数,当其为1是表示第
i
i
i 个先验框与第
j
j
j 个ground truth匹配,并且groud truth的类别为
p
p
p 。对于位置误差,采用Smooth L1 Loss,定义为:
L
l
o
c
(
x
,
l
,
g
)
=
∑
i
∈
P
o
s
N
∑
m
∈
{
c
x
,
c
y
,
w
,
h
}
x
i
j
k
s
m
o
o
t
h
L
1
(
l
i
m
−
g
^
j
m
)
L_{loc}(x,l,g)=\sum^{N}_{i\in Pos}\sum_{m\in{\{cx,cy,w,h\}}}x^k_{ij}smooth_{L1}(l^m_i -\hat{g}_j^m)
Lloc(x,l,g)=i∈Pos∑Nm∈{cx,cy,w,h}∑xijksmoothL1(lim−g^jm)
g
^
j
c
x
=
(
g
j
c
x
−
d
i
c
x
)
/
d
i
w
,
g
^
j
c
y
=
(
g
j
c
y
−
d
i
c
y
)
/
d
i
h
\hat{g}_j^{cx}=(g^{cx}_j - d^{cx}_i)/d^w_i, \hat{g}_j^{cy}=(g^{cy}_j - d^{cy}_i)/d^h_i
g^jcx=(gjcx−dicx)/diw,g^jcy=(gjcy−dicy)/dih
g
^
j
w
=
l
o
g
(
g
j
w
d
i
w
)
,
g
^
j
h
=
l
o
g
(
g
j
h
d
i
h
)
\hat{g}_j^w=log(\frac{g^w_j}{d^w_i}), \hat{g}_j^h=log(\frac{g^h_j}{d^h_i})
g^jw=log(diwgjw),g^jh=log(dihgjh)
s
m
o
o
t
h
L
1
(
x
)
=
{
0.5
x
2
if |x|<1
∣
x
∣
−
0.5
otherwise
smooth_{L1}(x)=\begin{cases}0.5x^2 \text{ if |x|<1}\\|x|-0.5 \text{ otherwise} \end{cases}
smoothL1(x)={0.5x2 if |x|<1∣x∣−0.5 otherwise
对于置信度为u查,采用Softmax Loss:
L
c
o
n
f
(
x
,
c
)
=
−
∑
i
∈
P
o
s
N
x
i
j
p
l
o
g
(
c
^
i
p
)
−
∑
i
∈
N
e
g
l
o
g
(
c
^
i
0
)
,
w
h
e
r
e
c
^
i
p
=
e
x
p
(
c
i
p
)
∑
p
e
x
p
(
c
i
p
)
L_{conf}(x,c)=-\sum^N_{i \in Pos}x^p_{ij}log(\hat{c}^p_i)-\sum_{i\in Neg}log(\hat{c}^0_i), where\ \ \hat{c}^p_i =\frac {exp(c_i^p)}{\sum_p exp(c^p_i)}
Lconf(x,c)=−i∈Pos∑Nxijplog(c^ip)−i∈Neg∑log(c^i0),where c^ip=∑pexp(cip)exp(cip)
数据扩增
采用数据扩增(Data Augmentation)可以提升SSD的性能,主要采用的技术有水平翻转(horizontal flip),随机裁剪加颜色扭曲(random crop & color distortion),随机采集块域(Randomly sample a patch)(获取小目标训练样本)。
预测过程
- 对于每个预测框,首先根据类别置信度确定其类别(置信度最大者)与置信度值,并过滤掉属于背景的预测框。
- 之后根据置信度阈值(如0.5)过滤掉阈值较低的预测框。
- 对于留下的预测框进行解码,根据先验框得到其真实的位置参数(解码后一般还需要做clip,防止预测框位置超出图片)。
- 解码之后,一般需要根据置信度进行降序排列,然后仅保留top-k(如400)个预测框。
- 最后就是进行NMS算法,过滤掉那些重叠度较大的预测框。最后剩余的预测框就是检测结果了。