[关闭]
@w460461339 2019-02-26T11:09:31.000000Z 字数 3694 阅读 2269

Tensorflow Day8: YoloV3

Tensorflow


0、参考

很不错:https://blog.csdn.net/leviopku/article/details/82660381
关于loss部分的一些解释:https://www.jianshu.com/p/67163d52946f

1、YoloV3原理

yolo_v3的原理其实和yolov1没有大的改变,还是cell+一步到位预测的组合。

一些有意思的地方主要是在细节上。

比如在loss设计上,将anchors技术和yolov1采用的cell限制bbox中心偏移的方法结合在一起。

在网络设计上,采用多尺度。

。。。

2、anchors聚类(训练)

yolo系列运用anchors比较成功的地方在于,它没有人工指定anchors,而是通过对已有数据进行聚类,来得到。

聚类方法:k_means。

聚类输入:【None,2】其中,2表示每个gt的宽和高。

距离计算

1、计算两个gt可能的最大IOU。
    1.1 选择两者宽度的最小值w_min,和高度的最小值h_min.
    1.2 w_min*h_min表示最大的相交面积。
    1.3 计算IOU完事。
2、1-IOU表示两个gt的距离。

完全体的yolo而言,一般选择聚类中心=9

3、主干网络(训练)

主干网络是比较简单的部分了。

网络的结构图如下图:
配图来自于上面参考1

注意几个点:

聚类完成后,anchors有9种,按照面积从大到小排序,得到3组anchors。
那么第一组面积最大的anchors,对应于上图y1;
第二组面积中等的anchors,对应于上图y2;
第三组面积最小的anchors,对应于上图y3;

就是不同的尺度,对应的anchors面积也不一样,简单易懂。

这里涉及到一个问题,bbox的坐标信息是怎么表示的?是Faster_rcnn那一套相对偏移?还是yolo_v1的中心限制?

image_1d4ho0pcmvji1d2s1iihhjcghm.png-84.2kB

我们看上图,上图是解释yolo_v3中坐标输出的内容的。

在这里,是网络的输出,也就是啊上面3*(4+1+80)中的4.

其中,在经过sigmoid后,是相对于当前cell左上角的偏移,再加上cell位置,才是绝对位置。
在经过后,得到的是原图下bbox的宽,其中表示anchors的宽。

那么可以看到,yolo_v3其实是Faster_Rcnn系和yolo_v1的结合体。

在中心预测上,用了yolo_v1的方法,限制中心在一个cell内。
在宽高预测上,用了faster的方法,寻找相对于anchors的比例。

因此,我们总结:

对于bbox的坐标信息而言,它预测的t_x,t_y,t_w,t_h是在当前尺度(当前划分,就是把原图划分成几份)的情况下,预测的一个相对值,需要通过上图的转换,得到在当前尺度的bbox坐标信息。

4、数据获取(训练)

我们想想该如何准备训练数据。

已有条件:

1、不同尺度的预测结果上,用了不同的anchors。
2、预测结果和anchors是依赖的。
3、不同尺度之间,互不重复。

那么,对于gt而言,它需要确定:

1、它对应于哪个anchors;
2、一旦确定了它对应哪个anchors,那么gt在哪个尺度上被预测也就能够知道了。

解析完毕后,得到 img_path:1,gt_cor=[None,4],gt_label=[None,4]的返回值

5、loss设计

loss设计上,其实和yolo_v1大同小异,都是分这么几部分:

1、坐标的loss
2、置信度loss
3、分类loss

同样,并不是所有的bbox都会用于loss。

由于yolo_v3还是基于cell的,我们可以把bbox分为这么几类:

1、确定被用于预测物体的。
2、确定不被用于预测物体的,并且和gt的IOU小于阈值。
3、确定不被用于预测物体的,但是和gt的IOU大于阈值。

大意就是,‘狗拿耗子,我也不惩罚,也不奖励’。

综上:

1、对于坐标loss和分类loss而言,仅有确定用于寻找物体的bbox,会被计算loss。
2、对于置信度而言,计算:
    2.1 计算用于预测物体的bbox。
    2.2 确定不被用于预测物体的,并且和gt的IOU小于阈值。

另外,很重要的一点是,所有的IOU,包括上面的anchors聚类,数据准备,和接下来的bbox分类,IOU的计算都是需要在原图的尺寸上进行的

而loss的计算,都要在自己的尺度下进行。

那么LOSS的操作,步骤如下。

回想这幅图:
image_1d4ho0pcmvji1d2s1iihhjcghm.png-84.2kB

那么,最终的loss:

6、其他细节

获取数据上,我们用DataSet或者其子类,来读取数据。当我们需要对读取的数据进行处理,才能够得到我们最终要的数据时,还可以使用apply方法来操作。

返回数据,用的是迭代器,iterator,根据读取数据的不同采用不同的迭代器。

但有时会出现,这个物体属于两个类别,那么用sigmoid就能解决这个问题。它会对每个类别都都单独打分,然后利用每个类别的NMS进行边框筛选就好。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注