Press "Enter" to skip to content

深度学习目标检测(object detection)系列 YOLO2

YOLO系列的实现有一个自己的框架叫做draknet,这是一个纯C的框架,无论是YOLO还是YOLO2,在代码实现上都是用darknet,改变的是网络结构的配置文件,首先我们来看一下它到底是什么样的:

从上面的图我们可以看到YOLO 2有32层。结构还是比较常规的,主要就是在用3 3的卷积,2 2的池化和1*1的卷积。除了上面三个常规操作外,还有reorg和route,其中route在25层和28层,reorg在27层。

route:

route层是合并的意思,比如28层的route把27层和24层合并到一起输出到下一层,第27层的输出是13 13 256,24层输出是13 13 1024,所以在第三个维度上做拼接就是28层的输出了,同样也是29层的输入:13 13 1280。同理,第24层route只有16,那么就不做合并了,直接把16层的输出拿过来作为24层输出:26 26 512。

reorg:

reorg很像是一种reshape,但是reshape的方式很新奇,它将26 26 64的输出形变为13 13 256,这是因为26 26 1可以变为13 13 4。
这样一来,YOLO2的32层结构就梳理清楚输入输出了,最后我们关注一第30层的输出,是13 13 125。由于第30层做的是1 1卷积,所以是用了125个1 1 1024的卷积核,最后输出13 13*125。那么为什么输出是这样的shape呢?
13 13没什么好说的,就是169个像素点,每一个像素点都有125层的厚度。而在这一层之后就直接预测了,所以这169 125个数包含了YOLO2需要的所有信息,边框,类别等等。
125指的是25*5,其中的5指的是5个区域建议框,这种操作是在参考faster r-cnn中的anchor建议框,如果看过这个系列的话,在faster r-cnn这个数字是9,只是在YOLO2中,它变成了5。
还剩最后一个数字:25,这是和要检测类别数量有关系,YOLO2在预测20类(VOC数据集),所以25的排布是20+4+1,其中:
20是class的分数(probability),就是当前的某一个像素,对应的某个参考框中是某一个class的概率;
4是δ(tx)δ(tx),δ(ty)δ(ty),txtx,tyty,这4个数会被用来计算边框的位置和大小;
1是confidence,表示边框预测里有真正的对象的概率。
所以,YOLO2的结构是在根据检测的类别数变化的,如果我们做单目标检测,其他的和上述相同的话,那么最后一层的输出将是: 13 13 (5*(1+4+1)),即13 13 30。在这里顺便吐槽一下CNN结构,我们在做网络结构分析或网络结构设计的时候,经常会有这样的感觉,输出的数想让它代表什么就代表什么,有时候甚至看起来很没有道理,但是最后这样的操作却能有效果,最重要的原因就在于卷积操作是没有实际的意义的,它只是很强的抽取能力,但是它并不知道会抽取出什么东西,所以如果我们设计合适的损失函数,就可以任意指定输出,哪怕这种指定看起来并没有道理。CNN本质上就是连接input与output之间的一个极其复杂的,表达能力很强的,并且很有潜力的函数,但是这个函数最终的能力能不能充分发挥出来,要取决于很多东西,损失函数,训练技巧,数据集等等。

YOLO2边框计算

YOLO2的边框是与最后的特征图上每一个像素点相关的,每一个像素点都会出五个参考框,这五个参考框是与anchor和stx、sty、tw、th这些数相关的,我们直接看下面的公式:

在之前我们一直在说anchor这个东西,其实它一点都不抽象,反而非常具体。一个anchor就是一对数,分别是width与height,比如我们写一对(1,1),那么它就是一个anchor,在上图的公式中width是PwPw,height是PhPh。YOLO2在决定anchor的取值的时候,是根据要预测的数据集来的,它事先统计了VOC中的boundingbox的长宽分布情况,选择了5对比较合适anchor,这种统计的方式在论文里称为Dimension Clusters(维度聚类),其实就是个K-means,以聚类个数k为anchor boxs个数,以k个聚类中心box的宽高维度为anchor box的维度。但是使用标准的K-means有一个问题,那就是大的bbox会比小的bbox产生更大的error,哪怕他们离实际的聚类中心更近,所以为了解决这个问题,维度聚类重新设计了距离评价: d(box,centroid)=1−IOU(box,centroid)d(box,centroid)=1−IOU(box,centroid)
经过K-means预测之后,它们分别是:
(1.3221,1.73145)
(3.19275,4.00944)
(5.00587,8.09892)
(9.47112,4.84053)
(11.2364,10.0071)
除此之外,CxCx与CyCy就是特征图上的像素点位置,δ(tx)δ(tx),δ(ty)δ(ty),txtx,tyty就是特征图上的输出。
最后这个在特征图上计算出来的bbox是要向原图上映射的,这就是一个对应比例的坐标变换。

YOLO2阈值与分类

YOLO2最后会对20个class都打分,显然分值最高的那个,就是最后的这个建议框的类别,并拿出该类别的probability。
YOLO2对于VOC的结构,最后将产生13 13 5的目标,但是一张正常的图片中是不可能有这么多物体的,所以最后需要一个阈值限定这些输出,这个阈值论文中给出的是0.24,那么拿什么值和0.24比较呢?上面我们已经拿出了一个probability,还有一个输出是confidence,比较的就是二者的乘积。
在darknet的官网给出了一个图,说明了如果阈值取的非常小的话,就会是这样:

YOLO2损失函数

YOLO2同样是一个多任务损失,在R-CNN系列中,一般是把分类的回归的加在一起作为最后的loss function的,而在YOLO2中loss function有四项,并且这四项的weight不同,他们分别是:
object_scale:5
noobject_scale:1
class_scale:1
corrd_scale:1
什么意思呢?object是对于存在物体的区域判定为无物体,noobject是没有存在物体的区域判定为存在物体,class是分错类别,corrd是bbox的偏差,可以看到,YOLO2对于检测不到物体时给的惩罚是很大的。
具体的过程是,YOLO2最先关注的是noobject的类,最后一层会输出13 13 5个bbox,把这些bbox逐个与每一个ground truth比较,如果还是有一些bbox与ground truth的IOU小于0.6的话,那么就认为属于noobject,传回去的东西就是noobject_scale*confidence。 下一步,关注和ground truth重合度最大的bbox,计算剩下的三个loss,这三个loss是没有判定条件的,不管什么样都会输出:
1.object类会回传object_scale*(1-confidence)
2.corrd类会回传四个数的L1距离
3.class类就直接回传交叉熵

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注