yolo系列阅读笔记(v1-v3)

只谈情不闲聊 提交于 2019-12-04 11:28:54

yolov1

模型输出的概率建模

图片首先被分割为S*S的网格(grid cell)。如果一个bbox的中心落在一个网格里,则该网格负责检测该物体。(对于pascal数据集,S定为7)

每个网格预测B个bbox及其confidence score,confidence定义为Pr(Object)∗IOU。 若该网格内没有物体,score应当是0;否则score被希望等于IOU(即如果网格不包含目标中心,则Pr(Object)=0,否则=1)。这个score反应了置信度,此处置信度是指模型预测的box是否真的包含目标(即第一项)以及模型自己认为box的准确度(即第二项)。

每个bbox包含5个预测值,分别为x,y,w,h和score。(x,y)坐标是box中心相对于网格边界(?),(w,h)是相对于整幅图像。score代预测box与真实值的iou。(iou不是能通过xywh直接算出来吗?)

每个cell同时还预测C个类别概率,即
\[ \begin{equation} \operatorname{Pr}\left(\text { Class }_{i} | \text { Object }\right) \end{equation} \]
根据条件概率公式,有:
\[ \operatorname{Pr}\left(\text { Class }_{i} \text { |Object }\right) * \operatorname{Pr}(\text { Object }) * \text { IOU }^{truth}_{pred}=\operatorname{Pr}\left(\text { Class }_{i}\right) * \text { IOU }^{truth}_{pred} \]
在原文中,对于PASCAL VOC数据集,有20类目标(C=20),采用S=7,B=2,最终预测为

\[ S \times S \times(B * 5+C) \]
即,7*7个网格,每个网格预测B个bbox,每个bbox有5个预测值,分别为xywh和score,以及20个类别概率值。

网络架构

基于用于图片分类的googleNet,有一定的调整。两个网络模型,正常(yolo)的和tiny的(fast yolo),正常的有24个卷积层+2个全连接层,tiny的有9个卷积层,滤波器也更少。使用了dropout在第一个全连接层之后(0.5)。

训练

imagenet上预训练分类,训练前20个卷积层,后面连了平均池化和一个全连接层。预训练使用的是224*224的输入,正式训练扩大了2倍长宽。使用了几何数据扩充。

输出xywh被归一化至0-1。激活函数使用leaky relu。

虽然每个网格预测两个bbox,但实际训练仅采用与真值IOU较高的那个bbox,即每个网格实际仅有一个参与训练的有效预测。

损失:使用sum-squared error。(和方差,其实和均方差没太大区别,只是没有除样本总数n)

具体包含三部分:

  1. Score置信度:标签为Pr(Object)∗IOU,若有物体中心落入该网格内,则Pr=1,否则Pr=0.
  2. xywh:xywh都被归一化,仅在物体中心落入该网格时才在损失函数中出现。
  3. 类别预测:对于一个网格,如果物体中心落入,则对应类别label为1,其余为0。同上,仅在物体中心落入该网格时才在损失函数中出现,即此项预测值为物体存在条件下的概率,Pr(class_i | Object)。

解决问题:大量不含目标的网格,即正负样本严重不均衡的问题:加权,含目标的加权至5,不含的至0.5。

解决问题:小box的小偏移误差比大box偏移误差更重要:预测wh的平方根而非值本身。

综上损失函数为:
\[ \lambda_{\text {cord }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{1}_{i j}^{\text {obj }}\left[\left(x_{i}-\hat{x}_{i}\right)^{2}+\left(y_{i}-\hat{y}_{i}\right)^{2}\right] \\+\lambda_{\text {coord }} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{1}_{i j}^{\text {obj }}\left[(\sqrt{w_{i}}-\sqrt{\hat{w}_{i}})^{2}+(\sqrt{h_{i}}-\sqrt{\hat{h}_{i}})^{2}\right] \\+\sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{1}_{i j}^{\mathrm{obj}}\left(C_{i}-\hat{C}_{i}\right)^{2} \\+\lambda_{\mathrm{noobj}} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} \mathbb{1}_{i j}^{\mathrm{noobj}}\left(C_{i}-\hat{C}_{i}\right)^{2} \\+\sum_{i=0}^{S^{2}} \mathbb{1}_{i}^{\mathrm{obj}} \sum_{c \in \text { classes }}\left(p_{i}(c)-\hat{p}_{i}(c)\right)^{2} \]
注意,1^obj_i代表物体中心落在网格i内,1^obj_ij代表网格i的第j个box负责预测该物体。因此该损失函数仅惩罚含有物体中心的网格分类,仅惩罚负责预测那个物体的bbox坐标。

预测

对大型物体,可能有多个cell同时给出较为准确的预测,可以理解,大型物体可能有好几个cell靠近中心点。使用nms筛选。

局限性

空间局限性:可预测的数量有限(98个,并且有空间独立)。对小的集群目标性能较差。对异形目标(长宽比)较差。对大小尺寸目标损失函数有问题。

对比

yolov1出的时候,faster r-cnn已经出了,但好像还没开源(?),而且这个时候精度还不如fast r-cnn,原文主要对比了fast r-cnn。此外原文还提到了Deformable parts models,Deep MultiBox,OverFeat,MultiGrasp等。

对比faster r-cnn,yolo在pascalvoc数据集上速度更快,但精度较低。

YOLO PASCAL2007+2012 mAP63.4 FPS45 输入448*448

yolov2

又叫yolo9000,号称可以实现识别9000类目标。基于yolo改进,超越基于resnet的faster r-cnn和ssd并且更快。可以预测没有标签的目标类别。

提出一种新的训练方法,可以实现同时利用检测数据集和分类数据集。

改进

引入BN

改进基于高分辨率的预训练方法

引入anchor boxes:优点:预测补偿(offsets)而非坐标本身,对网络来说更易于学习。移除原来的FC层,使用ancor boxes进行预测。

anchor dimension聚类:不同于R-CNN手动选取anchor box的数量和尺度,本文使用k-means聚类计算box dimensions的先验信息。根据训练集所有的boxes使用k-means聚类计算出的k个box尺度即定为anchor的尺度。综合性能和计算速度,取k等于5。

在k-means计算时,距离公式以IOU为标准。公式如下:
\[ d(\text { box }, \text { centroid })=1-\operatorname{IOU}(\text { box, centroid }) \]

注意:此时的IOU计算仅考虑形状,不考虑位置。

位置预测:为使模型更容易收敛,预测相对于cell偏移值,坐标预测值落于0-1范围内(使用sigmoid激活函数)。

模型对每个特征图像素点预测5个bbox,每个bbox预测5个值。
\[ \begin{aligned} b_{x} &=\sigma\left(t_{x}\right)+c_{x} \\ b_{y} &=\sigma\left(t_{y}\right)+c_{y} \\ b_{w} &=p_{w} e^{t_{w}} \\ b_{h} &=p_{h} e^{t_{h}} \end{aligned} \\\operatorname{Pr}(\text { object }) * I O U(b, \text { object })=\sigma\left(t_{o}\right) \]

注意:此处预测仍然是相对于网格。对于416×416的输入,特征图为13×13,即每个特征图像素点对应原图32×32,即一个网格。由于每个cell对应到特征图上为一个像素点,因此坐标预测范围理应在0-1之间。

细粒度特征:yolo在13*13的特征图上预测。加了一条passthrough layer带来前一层26*26的特征。通过一个神秘(?)的调整把 26×26×512 的特征图调整到了 13×13×2048 ,然后和原来的特征图进行concatenate。

多尺度训练:模型仅使用卷积和池化层,因此与输入尺度无关。训练模型使其适应多尺度输入。每10个batches随机换一个输入尺度: {320,352,...,608}.

性能:YOLOv2 416×416 2007+2012 mAP76.8 FPS67

特征提取器:大多检测系统基于VGG16,但这玩意很笨重。本文提出了Darknet-19分类模型,作为Yolov2的基底。

输出:先进行224*224分辨率的1000类分类训练,然后在448分辨率fine tune。然后溢出最后一个卷积层,加入一个新的卷积层,有1024个滤波器,每个跟着一个1*1卷积,层数由输出纬度决定。对VOC数据集,预测5个anchors,每个anchor对应4个坐标值、一个置信度、20个类别概率,因此输出为5×(1+4+20)=125层通道。

训练

识别与检测混合训练法:混合二者数据,若图片带有检测框标签,则进行完整的loss计算与反向传播,若图片仅有类别信息,则只根据分类损失进行反向传播。

问题:使用softmax分类损失的数学前提是所有类别是exclusive的,而一般分类数据集标签会有细分之类的问题,并不是exclusive的。针对这个问题,作者建立了层级类别标签树(wordTree),对每一个层级(是互斥的)进行softmax分类。对于预测概率,使用条件概率公式,并且假定每个图片包含object的概率为1。

在检测时,对每个box都预测一个概率树(对应类别树),自顶向下取最大分支直至绝对概率达到某个门限,即预测这个类别。

测试结果表明,这种方法使得模型对仅有类别训练没有位置训练的类型有一定的检测泛化能力。

损失函数

看完论文后总觉得缺点什么,原来是没有损失函数,这部分原文里没有提到。总的来说,损失函数包含了上述内容大多关键点,还是很有必要分析一下的。
\[ \begin{aligned} \operatorname{loss}_{t}=\sum_{i=0}^{W} \sum_{j=0}^{H} \sum_{k=0}^{A} 1_{\text {Max } IOU<Thresh} \lambda_{\text {noobj}} *\left(-b_{i j k}^{o}\right)^{2} \\+1_{t<12800} \lambda_{\text {prior}} * \sum_{r \epsilon(x, y, w, h)}\left(\text {prior}_{k}^{r}-b_{i j k}^{r}\right)^{2} \\+1_{k}^{\text {truth}}\left(\lambda_{\text {cord}} * \sum_{r \epsilon(x, y, w, h)}\left(t r u t h^{r}-b_{i j k}^{r}\right)^{2}\right.\\+\lambda_{o b j} *\left(\operatorname{IOU}_{\text {truth}}^{k}-b_{i j k}^{o}\right)^{2} \\\left.+\lambda_{\text {class}} *\left(\sum_{c=1}^{c}\left(\operatorname{truth}^{c}-b_{i j k}^{c}\right)^{2}\right)\right) \end{aligned} \]
W和H为最终特征图的分辨率(13×13),A为每个网格(特征图像素点)的anchor数目,原文取5。λ为各项权重。bo为置信度score,br为box的坐标和大小,bc为类别概率。

对特征图上所有anchors进行遍历:

第一项:若anchor与所有真值的最大IOU小于门限(原文门限取0.6),则计算该项,为no object的损失计算。此时给出的置信度越大则损失越大,即计算置信度与0的L2。

第二项:仅在训练初期(已训练样本数量小于12800时)计算。该项计算的是真值中心点不在对应网格内,但IOU大于门限的anchor,计算预测值与先验box的差距。即希望这种情况网络不进行任何预测。

第三项:真值Box中心落在对应网格内,仅匹配IOU最大的那个先验anchor进行计算,其余的anchors,除非IOU小于门限值被计入第一项,否则直接忽略(这一点类似于yolov1)。计算box与真值的损失,置信度损失(根据yolov1的条件概率公式,置信度与IOU进行L2计算),以及类别概率损失。

yolov3

改进

首先,IOU门限被改至0.5。

分类:使用多标签分类,移除softmax,因为作者发现这玩意对于提升性能并不是必要的。取而代之,使用independent logistic classifiers(逻辑回归),训练中使用二分类交叉熵损失。

多尺度特征:使用了3个不同尺度(类似于FPN)。输出仍然包括了bbox,置信度,类别概率。输出维度为N ×N ×[A∗(4+1+C)] ,N为特征图边长,A为每个点的box数量,原文对COCO数据集取3,4为box的4个坐标,1为置信度,C为类别概率向量。除了原框架的最后一层外,使用之前两层进行2倍上采样,并且与更之前的特征图进行融合,从而同时得到有意义的语义和细粒度信息。

Anchor尺度的先验聚类:仍然使用k-means聚类,只不过这次k取9。并且,根据结果的尺度,给三个尺度的特征图进行分配,每个特征图分配三个尺度的anchors。具体分配方式大致为,分辨率较高的特征图分配感受野较小的anchors,分辨率较低的特征图分配感受野较大的anchors,从结果上说这与retinanet基本一致。

更新主干网络:从darknet19更新至darknet53。

性能:从mAP上看,yolov3并没有比retinanet好,但有一说一,这玩意计算速度大约是retinanet的三倍。

特点:yolov3相比前两代在小目标检测上有大幅提升,但对于中型和大型目标有丶差。

作者有试过但没成功的idea:坐标预测,直接预测线性补偿;focal loss:作者认为可能是因为yolo本身有基于条件概率的置信度预测,因此不存在大量背景的负样本造成的不均衡问题;双门限:在faster r-cnn中,IOU大于0.7的被认为是正样本,小于0.3的被认为是负样本(背景),其余被忽略,而在yolo中,这样做并没有得到一个好结果。

损失函数

原文这次同样没有提到损失函数的具体公式,但根据上述内容不难看出,Yolov3相对于yolov2在损失函数上的变化主要为在分类中使用了逻辑回归和交叉熵损失。根据源码,公式应该如下:

\[ \begin{array}{l}{\text { loss (object) }=\lambda_{\text {coord }} \sum_{i=0}^{K \times K} \sum_{j=0}^{M} I_{ij}^{obj}\left[\left(x_{i}-\hat{x}_{i}\right)^{2}+\left(y_{i}-\hat{y}_{i}\right)^{2}\right]+} \\ {\quad \lambda_{\text {coord}} \sum_{i=0}^{K \times K} \sum_{j=0}^{M} I_{j}^{o b j}\left(2-w_{i} \times h_{i}\right)\left[\left(w_{i}-\hat{w}_{i}\right)^{2}+\left(h_{i}-\hat{h}_{i}\right)^{2}\right]-} \\ {\sum_{i=0}^{K \times K} \sum_{j=0}^{M} I_{i j}^{obj}\left[\hat{C}_{i} \log \left(C_{i}\right)+\left(1-\hat{C}_{i}\right) \log \left(1-C_{i}\right)\right]-} \\ {\quad \quad \lambda_{\text {noobj}} \sum_{i=0}^{K \times K} \sum_{j=0}^{M} I_{i j}^{\text {noobj}}\left[\hat{C}_{i} \log \left(C_{i}\right)+\left(1-\hat{C}_{i}\right) \log \left(1-C_{i}\right)\right]} \\ {\sum_{i=0}^{K \times K} I_{i j}^{o b j} \sum_{c \in \text { classes }}\left[\hat{p}_{i}(c) \log \left(p_{i}(c)\right)+\left(1-\hat{p}_{i}(c)\right) \log \left(1-p_{i}(c)\right)\right]}\end{array} \]
对于无obj的情况,仅计算置信度,不同于之前的L2,此处采用交叉熵作为置信度的损失函数。同理在有obj的情况,置信度和分类概率都采用交叉熵。对于有无obj的判断原理同之前,只是门限被改至0.5。同样,在每个网格仅有一个anchor即IOU最高的anchor被赋予真值,其余的不参与计算。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!