YOLO V1全网最详细的解读

看了很多网上的关于YOLO的教程,发现大家都是相互抄袭,并没有很详细的讲解其中的算法,所以我结合网上的和自己的理解对其进行全网最详细讲解。
比较好理解的tensorflow版本的代码:https://github.com/dshahrokhian/YOLO_tensorflow/blob/master/network/YOLO_small_tf.py
https://github.com/gbyy422990/yolo_v1_tensorflow_guiyu

参考:https://zhuanlan.zhihu.com/p/37850811

一、YOLO:YOLO: Unified, Real-Time Object Detection概述

YOLO作者将物体检测作为回归问题求解,基于一个简单的end-to-end网络设计,和rcnn系列的区别主要如下:

1、YOLO训练和检测均是在一个单独的网络中进行,但是yolo没有rpn等层;

2、YOLO将物体检测作为一个回归问题来解决,输入一张图经过inference便能得到物体的位置和其所属的类别及其相应的置信度。

如下图所示:
​​​​​​在这里插入图片描述

二、YOLO的结构

YOLO检测网络包含24个卷积层(用来提取特征)和2个全联接层(用来预测图像位置和类类别置信度),并且使用了大量的1x1的卷积用来降低上一层的layer到下一层的特征空间。并且在paper中,作者还给出了fast-YOLO的构架,即:9个卷积层和2个全连接层。使用titan x GPU,fast YOLO可以达到155fps的检测速度,但是mAP值也从YOLO的63.4%降到了52.7%,但却仍然远高于以往的实时物体检测方法(DPM)的mAP值。
在这里插入图片描述
YOLO将输入图像分成SxS个格子,每个格子负责检测‘落入’该格子的物体。若某个物体的中心位置的坐标落入到某个格子,那么这个格子就负责检测出这个物体。如下图所示,图中物体狗的中心点(红色原点)落入第5行、第2列的格子内,所以这个格子负责预测图像中的物体狗。
在这里插入图片描述
其中,每个格子输出B个bounding box(包含物体的矩形区域),每个box的置信度,以及C个物体属于某个类别的概率信息。每个bounding box包含五个数据,分别为:x,y,w,h,confidence。其中x,y是指当前格子预测得到的物体的bounding box的中心位置的坐标。w,h是bounding box的宽度和高度。注意:实际训练过程中,w和h的值使用图像的宽度和高度进行归一化到[0,1]区间内;x,y是bounding box中心位置相对于当前格子位置的偏移值,并且被归一化到[0,1]。

confidence反映当前bounding box是否包含物体以及物体位置的准确性,计算方式如下:

confidence = Pr(object)* IOU

即置信度=包含物体的概率(0或1)乘以IOU。其中,若bounding box包含物体,则P(object) = 1;否则P(object) = 0。IOU(intersection over union)为预测bounding box与物体真实区域的交集面积(以像素为单位,用真实区域的像素面积归一化到[0,1]区间)。

所以,预测结果是一个 S x S x (B*5 + C)大小的tensor。对于paper中,作者选取的S=7,B=2,C=20,所以输出的维度为7 * 7 *(20+2 * 5)=1470,所以这也解释了为什么在网络代码中fc26的channel为1470维度。

三、训练数据处理

Yolo和其他检测网络不同,在训练数据处理上,yolo处理如下:

    def load_xml(self,index):
        path = self.data_path + '/JPEGImages/' + index  + '.jpg'
        xml_path = self.data_path + '/Annotations/' + index + '.xml'
        img = cv2.imread(path)
        w = self.img_size / img.shape[0]
        h = self.img_size / img.shape[1]

        label = np.zeros((7,7,25))
        tree = ET.parse(xml_path)
        objs = tree.findall('object')
        for i in objs:
            box = i.find('bndbox')
            x1 = max(min((float(box.find('xmin').text) - 1) * w,self.img_size-1),0)
            y1 = max(min((float(box.find('ymin').text) - 1) * h,self.img_size-1),0)
            x2 = max(min((float(box.find('xmax').text) - 1) * w,self.img_size-1),0)
            y2 = max(min((float(box.find('ymax').text) - 1) * w,self.img_size-1),0)
            boxes = [(x1+x2)/2.,(y1+y2)/2.,x2-x1,y2-y1]
            cls_id = self.class_id[i.find('name').text.lower().strip()]

            x_id = int(boxes[0] * 7 / self.img_size)
            y_id = int(boxes[1] * 7 / self.img_size)

            if label[y_id,x_id,0] == 1:
                continue
            label[y_id,x_id,0] = 1  #con
            label[y_id,x_id,1:5] = boxes
            label[y_id,x_id,5:cls_id] = 1

        return label,len(objs)

四、网络输出的详细的解读(细节):

1、输出的bbox和confidence解读:
在这里插入图片描述
448的图片经过google的inception的思想后加几层卷积(有更好的效果)。如上图所示物体的中心落在红色的grid里面,所以Pr=1。那么,为什么作者这个地方的confidence加了Pr呢?原因是为了后面计算的条件概率时候的需要。
在yolo的paper里面作者提到了预测的不是w和h,而是w平方和h平方。
对上面的(x,y,w,h)参数解释如下:
(x,y)coordinates represent the center of the box relative to the bounds of the grid cell.
(w,h)The width and height are predicted relative to the whole image.
在这里xywh我看网上都是千篇一律的解释,互相抄袭,这个地方比较难理解,我详细的讲一下bbox的预测的xywh的四个值的含义:
xy表示bbox的中心点相对于cell的左上角坐标的偏移值,宽高是相对于整张图的宽高进行归一化的,偏移的计算方式如下所示:
在这里插入图片描述
经过这样的表达后,xywh的值都经过归一化到了0-1之间,不会导致太难收敛。
注意这个yolo v1里面没有任何anchor的概念,所以训练的时候没有初始化anchor的东西,需要初始化的只有网络的权值,然后这个权值输出的7 * 7 * 30的结果,里面的值才是xywh的值。
2、输出的classes的解读:
在这里插入图片描述每个grid其实都会有两个bbox,但是每个grid只会预测一个类别,所以其实每个grid的bbox都是属于同一个类别的。

3、输出总结:
在这里插入图片描述

五、Loss的计算

在这个例子中7*7的grid cell中,每个cell预测2个bbox,所以一共有98个bbox。但是这个图中只有三个object(狗,自行车,小汽车)。
在这里插入图片描述
其中:I{i,j} obj表示的是第i个网格中第j个bbox是否负责这个object:负责这个object的意思是与object的GT的IoU最大的bbox负责这个object。
所以在上图中我们可以看出:
只有三个bbox是算:
在这里插入图片描述
其余的98-3=95个bbox都是算:
在这里插入图片描述
所以这个地方加的系数lambdanoobj是为了防止负例过多对loss产生不好的影响。
在这里放一段tensorflow对loss的计算的代码,可以很容易的看到其实现:
在这里插入图片描述

六、Testing阶段

现在我们已经可以获取98个预测的bbox,以及概率的confidence map了,如下:
在这里插入图片描述
那么预测是如何进行的呢?
在这里插入图片描述
在文章中对这个概率的说法如下:
在这里插入图片描述
既能说明这个bbox属于每个类的概率,也能说明这个bbox有多适配这个obj。

对于7*7的每一个grid cell,我们都可以得到一个20 * 1的向量,如下所示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
即:比如上图中一个cell预测的的car,得到的score分别是0.8和0.4,如果这两个的IoU大于0.5,则第二个将会被舍弃,如果IoU小于0.5,那么两个都会被保留(但是只会选择IoU最大的那个作为最后的结果),所以一个grid cell只可能出现属于同一个class的两个bbox。

七、 YOLO的缺点:

a、由于YOLO中采用了全联接层,所以需要在检测时,读入测试的图像的大小必须和训练集的图像尺寸相同;

b、对小物体检测不敏感。因为虽然每个cell都可以预测出B个bounding box,但是在最终只选择IOU最高的bounding box作为物体检测输出,即:每个cell只能预测出一个物体。当物体较小时,所占画面比例较小,比如图像中包含牲畜群的时候,每个格子kennel包含多个物体,但是最后只能检测出其中的一个。

c、YOLO方法模型训练依赖于物体识别标注数据,因此,对于非常规的物体形状或比例,YOLO的检测效果并不理想。

d、YOLO采用了多个下采样层,网络学到的物体特征并不精细,因此也会影响检测效果。

e、YOLO loss函数中,大物体IOU误差和小物体IOU误差对网络训练中loss贡献值接近(虽然采用求平方根方式,但没有根本解决问题)。因此,对于小物体,小的IOU误差也会对网络优化过程造成很大的影响,从而降低了物体检测的定位准确性。

1.3 Training过程

作者采用ImageNet上1000类作为预训练前20层的卷积层,然后接一个average-pooling层和全联接层。对于检测而言,我们希望图片更加的精细,所以我们也是将224224改成448448大小。

最后一层预测出类别的置信度和bounding box的左边,并且我们对bounding box的width 和height都根据图片的宽和高做了归一化。

激活函数方面:使用linear activation function作为最后一层的激活函数,对于其他层我们使用leaky rectified linear activation,即:

对于优化函数方面选择sum-squared error均方和误差,因为它比较容易优化。见原文:

网络输出的SS(B5 + C)维向量与真实图像的对应SS*(B*5 + C)维向量的均方和误差。如下式所示。其中,、iouError和classError分别代表预测数据与标定数据之间的坐标误差、IOU误差和分类误差。即:

但作者对上面的loss做了相应的优化,如下:

1、位置相关误差(坐标、IOU)与分类误差对网络loss的贡献值是不同的,因此YOLO在计算loss时,使用修正。

2、在计算IOU误差时,包含物体的格子与不包含物体的格子,二者的IOU误差对网络loss的贡献值是不同的。若采用相同的权值,那么不包含物体的格子的confidence值近似为0,变相放大了包含物体的格子的confidence误差在计算网络参数梯度时的影响。为解决这个问题,YOLO 使用修正。(注此处的‘包含’是指存在一个物体,它的中心坐标落入到格子内)。

3、对于相等的误差值,大物体误差对检测的影响应小于小物体误差对检测的影响。这是因为,相同的位置偏差占大物体的比例远小于同等偏差占小物体的比例。YOLO将物体大小的信息项(w和h)进行求平方根来改进这个问题。(注:这个方法并不能完全解决这个问题)。

综上,YOLO在训练过程中Loss计算如下式所示:

其中,为网络预测值,帽 为标注值。表示物体落入格子i中,和分别表示物体落入与未落入格子i的第j个bounding box内。

1、4 YOLO优点

a、快。YOLO将物体检测作为回归问题进行求解,整个检测网络pipeline简单。在titan x GPU上,在保证检测准确率的前提下(63.4% mAP,VOC 2007 test set),可以达到45fps的检测速度。
b、背景误检率低。YOLO在训练和推理过程中能‘看到’整张图像的整体信息,而基于region proposal的物体检测方法(如rcnn/fast rcnn),在检测过程中,只‘看到’候选框内的局部图像信息。因此,若当图像背景(非物体)中的部分数据被包含在候选框中送入检测网络进行检测时,容易被误检测成物体。测试证明,YOLO对于背景图像的误检率低于fast rcnn误检率的一半。
c、通用性强。YOLO对于艺术类作品中的物体检测同样适用。它对非自然图像物体的检测率远远高于DPM和RCNN系列检测方法。

但相比RCNN系列物体检测方法,YOLO具有以下缺点:

识别物体位置精准性差。
召回率低。
所以为提高物体定位精准性和召回率,YOLO作者提出了YOLO9000,提高训练图像的分辨率,引入了faster rcnn中anchor box的思想,对各网络结构及各层的设计进行了改进,输出层使用卷积层替代YOLO的全连接层,联合使用coco物体检测标注数据和imagenet物体分类标注数据训练物体检测模型。相比YOLO,YOLO9000在识别种类、精度、速度、和定位准确性等方面都有大大提升。

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值