文章目录
前文阅读
-
本文中的改进是针对YOLO v1中的问题,进行改进的。
-
论文开篇就提到,目前目标检测都是在小数据集上训练的,只能检测很少的一部分数据,但是在实际应用时都会检测大量的目标。
-
为了检测出更多的目标,本文提出了一种联合训练的机制,可以在分类和检测的数据集上共同训练目标检测。
-
本文的方法利用标记的检测图像来学习精确定位对象,而它使用分类图像来增加其词汇量和鲁棒性。
一、YOLO v1 存在的问题
- 未使用 Batch Normalization
- 对小目标检测不好
- 因为是YOLO v1直接回归坐标
- 对拥挤目标检测不好
- 7×7的 格子太稀疏了。
- 多个物体落在同一个 cell 里面,YOLO v1无法解决。
- 对 New Height-Weight ratio检测效果不好。
可以总结为以下两个问题:
- 预测的框不准确
- 很多目标(小目标,拥挤目标)找不到
二、YOLO v2 算法的改进
如下图所示,列出了YOLO v2的所有改进策略:
-
Batch Normalization
-
hi-res classifier (更高精度的分类器)
- 细粒度特征 (passthrough)
- multi-scale → \rightarrow → 多尺度
-
new Network → \rightarrow → 新的网络结构 → \rightarrow → DarkNet-19
-
Anchor Boxes → \rightarrow → 使用先验框
- dimension prior → \rightarrow → 维度先验 → \rightarrow → 聚类提取先验框尺度 → \rightarrow →YOLO v2进一步对先验框进行了改良
- location prediction → \rightarrow → 直接位置预测 → \rightarrow →约束预测框的位置【采用 Precision - Anchor的偏差值进行回归】
2.1 引入 Batch Normalization → \rightarrow → 使模型更收敛
- Batch Normalization 使mAP有 2.4 的提升。
- BN 有助于解决反向传播过程中的梯度消失和梯度爆炸问题,降低对一些超参数(比如:学习率、网络参数的大小范围、激活函数的选择)的敏感性。
- BN导致收敛的显著改进,同时消除了对其他形式正则化的需要。
- 有助于模型的规范化。我们可以在不过度拟合的情况下从模型中删除Dropout。
2.2 更高精度的 Classifier(分类器)[Focusing on backbone]
- a. 用小 Size 在 ImageNet 上训练:224 ×224
- b. 用大 Size 继续 finetune:448×448
- c.在 Customized(特定任务) 的数据集上 finetune
- d.最终获得13 × 13的feature map。
2.2.1 细粒度(fine-grained)特征
-
针对小目标
13 × 13 13 × 13 13×13的Feature Map用来预测大目标是够了。但是若是预测小目标,就需要更细粒度的特征来预测。 -
处理策略:
- 在Faster R-CNN或SSD中都是使用区域提取网络,来得到更细粒度的特征。
- 在YOLO中采用增加一个 passthrough layer,从更早的层中提取 26 ∗ 26 26 * 26 26∗26的特征。
2.2.1.1 (1)浅层特征直连高层特征
- 浅层特征:表示图像的物理特征;
- 物理特征 → \rightarrow → 决定物体在哪; → \rightarrow → 从而对物体边框进行定位
- 高层特征:表示图像的语义特征
- 语义特征 → \rightarrow → 决定物体是什么; → \rightarrow → 对物体进行分类
对于检测任务而言,物理特征和语义特征同样重要。
- 随着 卷积深度的加深,高层特征只有语义特定,缺乏物理特征;
- 为了引入物理特征,使用跳跃连接(Skip Connection; short cup)
2.2.1.2 (2)引入新层:reorg
- 目的:使得不同维度的特征一致,便于计算
降 维 : 大 图 变 成 小 图 { 卷 积 计 算 P o o l i n g : 很 少 用 , 因 为 一 定 会 有 信 息 损 失 。 降维:大图变成小图 \begin{cases} 卷积计算 \\ Pooling:很少用,因为一定会有信息损失。 \end{cases} 降维:大图变成小图{卷积计算Pooling:很少用,因为一定会有信息损失。
升
维
:
小
图
变
成
大
图
{
反
卷
积
(
转
置
卷
积
)
U
p
S
a
m
p
l
i
n
g
(
上
采
样
)
:
线
性
插
值
的
方
法
升维:小图变成大图 \begin{cases} 反卷积(转置卷积) \\ Up \ Sampling(上采样):线性插值的方法 \end{cases}
升维:小图变成大图{反卷积(转置卷积)Up Sampling(上采样):线性插值的方法
相对于转置卷积,Up Sampling的方法,可能效果更好。
2.2.2 多尺度
- 目的:
- 我们希望yolo v2对在不同大小的图像上运行具有鲁棒性;【帮助网络适应不同大小的图像】
- 当只有一个 Image Size时,大目标就会缩小化 → \rightarrow → 从而造成信息损失
- 当训练的时候使用不同的 Size,测试的时候也就会适应 Size的变化。
- 所以我们每隔几次迭代就会改变网络,而不是固定输入图像的大小。
- 这种方法迫使网络学会在各种输入维度上很好地预测。 这意味着相同的网络可以预测不同分辨率的图像。
- 这种网络在较小的尺寸下运行得更快,因此Yolov2提供了速度和精度之间的简单权衡。
- 我们希望yolo v2对在不同大小的图像上运行具有鲁棒性;【帮助网络适应不同大小的图像】
- 具体做法:
- 为什么可以实现多尺度(不同大小的输入)?
移除 FC层(Fully Connected):能够承接任意 Size 的输入,提高模型鲁棒性。- 为什么?
1)会限制输入信号一致。
比如:初始出入是 10 × 10 × 10 10 × 10 × 10 10×10×10 变成 1000,然后进行FC变化;
若是改变维度为 20 × 20 × 10 20 × 20 × 10 20×20×10就好变成4000,则无法继续使用。
2)计算量大
- 为什么?
- 输入 Size 横跨 320,352,…,608。训练时,每10个epoch改一下
- 为什么可以实现多尺度(不同大小的输入)?
2.2.3 微调
使用高分辨率图像微调分类模型 → \rightarrow → 缓解分辨率突然切换造成的影响
- 使用 微调 的效果:
- mAP提升了3.7。
- 具体做法:
- 采用 224*224 图像进行分类模型预训练后;
- 采用 448 * 448 的高分辨率样本对分类模型进行微调(10个epoch),使网络特征逐渐适应 448 * 448 的分辨率;
- 然后再使用 448 * 448 的检测样本进行训练,缓解了分辨率突然切换造成的影响。
- 这么做的原因:
- 图像分类的训练样本很多,而标注了边框的用于训练对象检测的样本相比而言就比较少了,因为标注边框的人工成本比较高。
- 检测模型通常都先用图像分类样本训练卷积层,提取图像特征。
- 这引出的另一个问题是,图像分类样本的分辨率不是很高。
- 所以YOLO v1使用ImageNet的图像分类样本采用 224 * 224 作为输入,来训练CNN卷积层。
- 然后在训练对象检测时,检测用的图像样本采用更高分辨率的 448 * 448 的图像作为输入。
- 但这样切换对模型性能有一定影响。
2.3 使用 Anchor
-
使用 Anchor 的效果:
- 召回率大幅提升到88%,同时mAP轻微下降了0.2。
- 为什么会有上述程度的变化?
- 之前YOLO v1并没有采用先验框,并且每个grid只预测两个bounding box,整个图像98个。
- YOLO v2如果每个grid采用9个先验框,总共有13139=1521个先验框。
- 所以,相对YOLO v1的81%的召回率,YOLO v2的召回率大幅提升到88%。同时mAP有0.2%的轻微下降。
-
具体做法:
借鉴Faster RCNN的做法,YOLO v2也尝试采用先验框(Anchor)。- 在每个grid预先设定一组不同大小和宽高比的边框,来覆盖整个图像的不同位置和多种尺度,
- 这些先验框作为预定义的候选区在神经网络中将检测其中是否存在对象,以及微调边框的位置。
- 在 Faster RCNN 中手动设置了 9 个Anchor;
在 YOLO v2 中 通过聚类得到了 5 个Anchor (dist = 1 - IoU)
-
同时YOLO v2移除了全连接层。
另外去掉了一个池化层,使网络卷积层输出具有更高的分辨率。 -
缩小了网络,由之前的 448 ∗ 448 448 * 448 448∗448 变为 416 416 416 的输入。
- YOLO的卷积层将图像降采样为32倍,因此,通过使用 416 416 416 的输入图像,我们得到了 13 × 13 13×13 13×13 的输出特征映射。
- 这样做的目的是:我们希望在我们的特征映射中有一个奇数的位置,所以有一个中心单元格。
- 特别是大的物体,往往占据图像的中心,所以在中心有一个位置来预测这些物体是很好的,而不是所有附近的四个位置。
2.3.1 Anchor 是什么?Anchor为了什么?
- Anchor 是什么?
- Anchor 是预先定义的虚拟边框。
- Anchor为了什么?
- 预测框是由 Anchor 回归得到的。
2.3.2 Anchor; Ground Truth BBoxes 和 Prediction 的关系是什么?
- 图形直观表示Anchor; Ground Truth BBoxes 和 Prediction 的关系
- Anchor; Ground Truth BBoxes 和 Prediction 在公式中的具体表示
- 如何选择 Anchor?
- Anchor离哪个物体最近。
根据 Anchor 与 Label的 IoU,来选择对应的 Anchor。
- Anchor离哪个物体最近。
- 举个例子:解释一下Ground Truth,
t
x
g
=
g
x
−
g
x
.
f
l
o
o
r
t_x^g = g_x - g_{x.floor}
txg=gx−gx.floor
假设Label的 中心点,归一化0~13之后的值为 9.6;
那么再次归一化到0~1,则是直接用 9.6 - 9 = 0.6,在第9个 cell的坐标。【相对于 Cell 进行归一化】
2.3.3 使用偏移量进行预测框的回归(约束预测框的位置)
-
针对的问题:
- 模型不稳定,特别是在早期迭代期间。
-
解决方法:
-
(6)直接位置预测–约束预测框的位置
-
借鉴于 Faster R-CNN 的先验框方法,在训练的早期阶段,其预测位置容易不稳定。其位置预测公式为:
x = ( t x ∗ w a ) + x a {x = ({t_x} * {w_a}) + {x_a}} x=(tx∗wa)+xa
y = ( t y ∗ h a ) + y a {y = ({t_y} * {h_a}) + {y_a}} y=(ty∗ha)+ya- 其中, x , y {x, y} x,y是预测边框的中心, x a , y a {{x_a}, {y_a}} xa,ya是先验框(anchor)的中心点坐标, w a , h a {{w_a}, {h_a}} wa,ha是 Anchor 的宽和高, t x , t y {{t_x}, {t_y}} tx,ty是要学习的参数。
- 注意,在论文这个位置写的是 x = ( t x ∗ w a ) − x a {x = ({t_x} * {w_a}) - {x_a}} x=(tx∗wa)−xa,根据Faster R-CNN,这里应该是“+”
-
由于 t x , t y {{t_x}, {t_y}} tx,ty的取值没有任何约束,因此预测边框的中心可能出现在任何位置,训练早期不容易稳定。
YOLO调整了预测公式,将预测边框的中心约束在特定的 grid 网格内。-
b x = σ ( t x ) + c x {{b_x} = {\sigma}({t_x}) + {c_x}} bx=σ(tx)+cx
b y = σ ( t y ) + c y {{b_y} = {\sigma}({t_y}) + {c_y}} by=σ(ty)+cy
b w = p w e t w {b_w} = {p_w}{e^{t_w}} bw=pwetw
b h = p h e t h {b_h} = {p_h}{e^{t_h}} bh=pheth
P r ( o b j e c t ) ∗ I O U ( b , o b j e c t ) = σ ( t o ) Pr(object) * IOU(b, object)={\sigma}({t_o}) Pr(object)∗IOU(b,object)=σ(to) -
其中, b x , b y , b w , b h {b_x,b_y,b_w,b_h} bx,by,bw,bh是预测边框的中心和宽高。
P r ( o b j e c t ) ∗ I O U ( b , o b j e c t ) Pr(object) * IOU(b, object) Pr(object)∗IOU(b,object)是预测边框的置信度,这里对预测参数 t o {t_o} to 进行 σ {\sigma} σ变换后作为置信度的值。 -
c x , c y {c_x,c_y} cx,cy是当前网格左上角到图像左上角的距离,要先将网格大小归一化,即令一个网络的 宽 = 1 , 高 = 1 宽=1,高=1 宽=1,高=1。
-
p w , p h {p_w,p_h} pw,ph是先验框(Anchor)的宽和高。 σ {\sigma} σ是Sigmoid激活函数。
-
t x , t y , t w , t h , t o {t_x,t_y,t_w,t_h,t_o} tx,ty,tw,th,to是要学习的参数,分别用于预测边框的中心和宽高,以及置信度。
-
-
2.3.3.1 问题一:为什么使用偏移量比直接预测真实值的效果好?
- 直接预测边框,可能会落到图片中的任何位置,会导致模型不稳定,训练时间加长。【相当于,从无穷回归】
- 使用偏移量进行回归预测,【相当于,从有穷进行回归,且和Label 目标框相似。】
2.3.3 维度先验 → \rightarrow → 聚类提取先验框尺度
-
存在的问题:
- 框的维度是手工提取的。
→ \rightarrow → 在用网络学习的过程中,如果我们选择比较好的先验,那么就会比较容易的得到好的结果。
- 框的维度是手工提取的。
-
聚类提取先验框尺度 的效果
- 结合下面的约束预测边框的位置,使得mAP有4.8的提升。
-
如何实现的?
- 对训练集中标注的边框进行聚类分析,以寻找尽可能匹配样本的边框尺寸。
- 之前先验框都是手工设定的,YOLO2尝试统计出更符合样本中对象尺寸的先验框,这样就可以减少网络微调先验框到实际位置的难度。
- 聚类算法最重要的是选择如何计算两个边框之间的“距离”。
- 对于常用的欧式距离,大边框会产生更大的误差;
- 但我们关心的是边框的IOU。
- YOLO2在聚类时采用以下公式来计算两个边框之间的“距离”。
d ( b o x ; c e n t r o i d ) = 1 − I O U ( b o x ; c e n t r o i d ) {d(box; centroid) = 1 − IOU(box; centroid)} d(box;centroid)=1−IOU(box;centroid)
【centroid是聚类时被选作中心的边框,box就是其它边框,d就是两者间的“距离”。IOU越大,“距离”越近。】
- 对训练集中标注的边框进行聚类分析,以寻找尽可能匹配样本的边框尺寸。
- 上图左边是选择不同的聚类k值情况下,得到的k个centroid边框,计算样本中标注的边框与各centroid的Avg IOU。
- 显然,边框数k越多,Avg IOU越大。
- YOLO2选择k=5作为边框数量(模型复杂度)与IOU(精度)的折中。
- 对比手工选择的先验框,使用5个聚类框即可达到61 Avg IOU,相当于9个手工设置的先验框60.9 Avg IOU。
- 上图右边显示了5种聚类得到的先验框,VOC和COCO数据集略有差异,不过都有较多的瘦高形边框。
Faster
更改分类预训练网络
之前采用的都是VGG-16,作为分类预测网络,本文提出了新的分类网络,Darknet-19。
Stronger
- 1、分类检测联合训练。
这种方法带有一些挑战:检测的数据只有常见的一些数据和标签,分类数据集的标签更加广泛。–》》需要特定的方法来合并这些标签。 - 2、 层次分类
ImageNet 的标签是从WordNet中提取出来的。
WordNet的结构是有向图,而不是树。
我们不使用完整的图结构,而是通过从Image Net中的概念构建层次树来简化问题。
为了构建这棵树,我们检查了Image Net中的视觉名词,并查看它们通过WordNet图到根节点的路径,在这种情况下是“物理对象”。 许多同步集只有一条路径通过图,所以首先我们将所有这些路径添加到我们的树中。 然后我们迭代地检查我们留下的概念,并尽可能少地添加增长树的路径。 因此,如果一个概念有两条通往根的路径,一条路径将向我们的树添加三条边,而另一条只添加一条边,我们选择较短的路径。
Loss损失函数
l o s s t = ∑ i = 0 W ∑ j = 0 H ∑ k = 0 A 1 M a x I O U < T h r e s h λ n o o b j ∗ ( − b i j k o ) 2 − 置 信 度 损 失 ( 不 是 目 标 ) + 1 t < 12800 λ p r i o r ∗ ∑ r ϵ ( x , y , w , h ) ( p r i o r k r − b i j k r ) 2 − t 是 迭 代 次 数 ( 预 测 与 A n c h o r 的 距 离 ) + 1 k t r u t h ( λ c o o r d ∗ ∑ r ϵ ( x , y , w , h ) ( t r u t h r − b i j k r ) 2 − 预 测 与 G T 的 距 离 + λ o b j ∗ ( I O U t r u t h k − b i j k o ) 2 − 置 信 度 损 失 ( 是 目 标 ) + λ c l a s s ∗ ( ∑ c = 1 C ( t r u t h c − b i j k c ) 2 ) ) − 分 类 损 失 {loss_t} = \sum_{i=0}^W {\sum_{j=0}^H{\sum_{k=0}^A}} 1_{Max IOU < Thresh }{\lambda_{noobj} * (-b_{ijk}^o)^2} \ \ -置信度损失(不是目标) \\ {+1_{t<12800}\lambda_{prior}*\sum_{r\epsilon(x,y,w,h)}(prior_k^r - b_{ijk}^r)^2}\ \ \ \ -t是迭代次数(预测与Anchor的距离) \\ {+1_k^{truth}(\lambda_{coord}*\sum_{r \epsilon(x,y,w,h)} (truth^r - b_{ijk}^r)^2}\ \ \ \ \ \ \ \ \ \ \ \ \ -预测与GT的距离 \\ {+\lambda_{obj} * (IOU_{truth}^k - b_{ijk}^o)^2}\ \ \ \ \ \ \ -置信度损失(是目标) \\{+\lambda_{class} * (\sum_{c=1}^C({truth}^c - b_{ijk}^c)^2))}\ \ \ \ \ \ \ \ \ -分类损失 losst=i=0∑Wj=0∑Hk=0∑A1MaxIOU<Threshλnoobj∗(−bijko)2 −置信度损失(不是目标)+1t<12800λprior∗rϵ(x,y,w,h)∑(priorkr−bijkr)2 −t是迭代次数(预测与Anchor的距离)+1ktruth(λcoord∗rϵ(x,y,w,h)∑(truthr−bijkr)2 −预测与GT的距离+λobj∗(IOUtruthk−bijko)2 −置信度损失(是目标)+λclass∗(c=1∑C(truthc−bijkc)2)) −分类损失
-
这里的W=13,H=13,A=5。
-
每个都是一个权重值。c表示类别,r表示rectangle,即(x,y,w,h)。
-
第1,4行是confidence_loss,注意这里的真值变成了0和IoU(GT, anchor)的值,你看看这些细节…
-
第5行是class_loss。
-
第2,3行:t是迭代次数,即前12800步我们计算这个损失,后面不计算了。这部分意义何在?
意思是:前12800步我们会优化预测的(x,y,w,h)与anchor的(x,y,w,h)的距离+预测的(x,y,w,h)与GT的(x,y,w,h)的距离,12800步之后就只优化预测的(x,y,w,h)与GT的(x,y,w,h)的距离。
为什么?因为这时的预测结果已经较为准确了,anchor已经满足我了我们了,而在一开始预测不准的时候,用上anchor可以加速训练。
1 k t r u t h {1_k^{truth}} 1ktruth是什么?第k个anchor与所有GT的IoU的maximum,如果大于一个阈值,就 1 k t r u t h = 1 {1_k^{truth}=1} 1ktruth=1,否则的话 1 k t r u t h = 0 {1_k^{truth}=0} 1ktruth=0。