YOLOv3庖丁解牛(四):YOLOv3整体归纳总结

前三篇博客我们从三个方向过了一遍yolov3框架结构,最后这篇来总结一下yolo的亮点和不足。

以下就木有配图了,有兴趣的大家耐心过一下。

首先聊聊它出彩的地方。

1、yolo系列最让人激动的形式在于you only look once,一次性就完成所有的预测和检测任务,这是rcnn结构下没办法做到的。其主要得益于loss的逻辑设计上。

(1)在计算loss的时候,真实值和预测值设计成了batchsize x grid x grid x num_anchor x 25(或者85)的形式,其中grid代表着三层输出的大小,在数据feed阶段,把annotation值间接转换到grid维度上,参与计算。这一步,对相应的层的目标预测做足了准备,解决了“grid”与“绝对位置”的关系

(2)num_anchor直接代表着该输出层该使用哪一个anchor(第一层678三个anchor,第二层使用345,第三层使用012),这里,又把“grid”和“anchor”建立起了联系

(3)另外,在最后一个维度(25),前四个值(xywh),代表的是预测具体物体的相对位置和相对大小,这一步的设计,把“grid”和box(相对位置)给联系起来了

(4)以上三个点,把整个输出所需要的所有关键数据全部联系起来了,让整个数据做到端到端的完整映射。这一方面确确实实很大程度上归功于数据的结构设计与损失函数的设计的结合,让yolo能够实现一次完成任务。

2、说到损失函数,最后计算loss的几个分支loss的计算,设计得也是非常有意思。

(1)binary_crossentropy和sigmoid的应用,在我们看来,算是非常大胆的了。因为二分类是得到比较“绝对”的输出,非黑即白,非0即1,在链式结构中,非常容易造成“一失足成千古恨”的结果。比如:每次预测值都是0.9,十次以后(0.9的10次方)就非常非常小了。

但是,从作者设计的意思看,他认为:只要你跟我的实际值不对,我就认为你是错的,你必须得无限像我逼近。要么你就是有物体,要么你就是没有。要么你的坐标就是准的,要么就是错的,没有0.8的概率是这个坐标,0.1的概率是那个坐标,0.1的概率又是哪个坐标。

这里,正是作者使用二分类的计算思维,能够让第“1”的内容所涉及的预测值,在结果中对“某些东西”的预测非常到位(当然这也是有不足的,后面会说到这个的不足)

(2)分支损失函数的制衡也是有他的道理的。在分支函数中,一直出现着一个变量“object_mask”,这个可以理解为置信度,就是这个点位,这个锚点,或者这么个anchor下存在物体的可能性。所有的预测值都是在这个值的基础上进行计算的,也就是说,它是个终极把关值。

同时,还有一个值“box_loss_scale”,这个是关于宽和高的一个函数,或者可以理解为与面积成反比的一个函数。我们知道,置信度是受面积影响的,在anchor一定的情况下,面积越小,置信度相对越低,必然使得object_mask偏小;然而box_loss_scale是跟面积成反比的函数,这两个值一乘起来,必然需要找局部极值点,才能使得loss局部最小。

这样的设计,让机器在学习的过程中,存在一个制衡点,不能让一个特别大,也不能特别小。这是非常巧妙地的设计。一方面把表面无关的置信度和wh三个维度的数据联合起来了,另一方面把其内部联系在计算中也体现出来了,高明!

3、类金字塔形输出造就了多尺度的物体检测。yolo body中是有三个输出的,从上至下检测的物体越来越小,在这点上,在一定程度上能保证检测到的物体的多样性。

同时呢,在网络设计中,有三步“Concatenate”,有些文章也叫“route”,其实就是一个拼接操作,可以理解为inception结构的横向拼接,直接让感受野变大了,同时可检测物体也变多了。这是一步非常机智的设计,在yolo中加入这中设计是非常非常非常合理的。

4、anchor选择使用k-means聚类方法,让预测值在特定数据集上泛化能力更强。

 

接着咱们聊聊它的劣势

1、上面说到他使用二分类的策略构造损失函数,必然导致结果值是有偏向性的。比如:0和1两极分化相对失衡,如果训练的步数有限,可能使得某个类的预测值一直处于非常低的结果,或者非常高的结果,而没有过多的值跳跃。容易造成两种情况:a)0.1或者0.2或者0.8或者0.9的物体永无翻身的机会;b)0.51的物体和0.49的物体,存在无法逾越的鸿沟,老是被一棒子打死。

2、在数据feed阶段,对同一个grid下,物体绝对位置的参数是循环填入的,后者会覆盖前者。也就是说,同一个点位,同一个输出层,同一个anchor,先填充的数据,会被后者覆盖。举个例子,同一个位置,如果有一只大小差不多的猫和狗,yolo可能只能检测一个。

3、相比rcnn系列,精度还是欠缺一些的,这点是毋庸置疑的。

 

最后呢,分享下自己对yolo改进方向的看法:

(1)输出层肯定是可以继续做文章的,毕竟三层输出有速度上的优势,也有量上的缺点,所以要想检测相对多的物体,输出层的设计肯定可以做调整,这里可能是下个版本的优化点。

(2)对于上面提及的数据覆盖情况,我觉得也是下一个yolo版本的优化方向。在这里我们是可以退而求其次的,在遇到相同点位,我们可以做偏移的设置,但是这就得要求损失函数也得做维度上的调整。不太确定作者会不会因为同size的重叠物体做优化,这一点的优化能为小物体带来福音,也许是一个优化的点吧。

OK吧,对于yolov3的介绍到这也就结束了,有什么问题的欢迎大家留言。

同时,在这里希望找到一群志同道合的伙伴,结队编程,共同学习,有兴趣者欢迎戳:245176275

你可能感兴趣的:(YOLOv3庖丁解牛(四):YOLOv3整体归纳总结)