认识YOLO-V1
- 优势及创新点
- 经典的 one-stage方法,开山之作
- 将整张图作为网络的输入,仅使用一个卷积神经网络端到端地实现检测物体的目的
- 可以对视频进行实时检测,检测速度快
算法整体解读
核心思想
- 将输入的图片划分为网格(把输入数据分成很多个小格子),然后每个小格子要产生两种候选框(v1版本只产生两种,当然实际中那么多物体,两种肯定不够用),接着每个格子产生的候选框都要去跟实际的物体框进行比较,看匹配的怎么样(计算IOU呀),当然还要预测一个置信度,置信度表示当前的回归框是一个物体的概率,所以,每一个小格子预测的内容为(x,y,w,h,confidence),坐标 x 和 y 代表了预测bbox的中心与栅格边界的相对值,w 和 h 代表了预测 bbox 的宽高相对于整幅图宽高的比例。最终,我们把置信度做一个过滤,得到一个实际的检测框!
- 如果一个物体落在某一个格子上,并且这个格子是物体的中心,那么这个格子就负责预测这个物体。
网络架构解读
-
full network: 24 convolutional layers followed by 2 fully connected layers. Alternating 1 × 1 convolutional layers reduce the features space from preceding layers.
-
整体工作流程
-
使用1x1卷积核作用: 实现升维和降维;增加非线性(需后接非线性激活函数);跨通道信息交互
-
每一个网格的预测
-
FC层全连接层:将7x7x1024的特征图reshape成4096x1,再reshape成1470x1,再reshape成7x7x30,然后进行预测
-
7x7x30含义:7x7表示把输入图片分成的7x7的网格,30表示每一个格子预测30个值(回归框1的5个值,回归框2的5个值,20个类别的概率值)
-
FC层使用线性激活函数,其他层使用 leaky RELU
- 这里有一个有趣的问题:我们设计的7x7x30进行预测,计算机怎么知道呢?我们通过设置损失函数,对网络进行训练,计算机就慢慢的学会了,这就是深度学习的魅力!很神奇!
训练
- 制作正样本
参考 - 损失函数定义
- 损失函数解读
-
位置误差
(1)在w、h的误差计算中,对于平方差,同样很小的数值,对于大框影响相对于小框的影响小一些。由于同样的值,加在大框上,可能几乎没有变化,而小框的变化会很大,因此加入根号,这样影响会相对一致一些。
(2)λcoord:8维的localization error和20维的classification error同等重要显然是不合理的,更重视8维的坐标预测,给这些损失前面赋予更大的loss weight, 记为 λcoord ,在pascal VOC训练中取为5。同时为了平衡“非物体” bbox 过多的影响。 -
置信度误差
(1)置信度误差分为两种,含有object的和不含有object的误差;
(2)λnoobj = 0.5,为了平衡过多的“非物体”,如果不加的话,由于图片中,肯定是背景比较多的,那么网络学习就会偏向于非物体;
(3)这个 confidence score 代表了所预测的box中含有object的置信度和这个box预测的有多准两重信息,c^i是如下计算的:(ci为网络生成的 confidence score),其中如果有object落在一个grid cell里,第一项取1,否则取0。 第二项是预测的 bounding box 和实际的 groundtruth之间的IoU值。
(4)那么为什么需要学习背景(不含有物体)呢?提高泛化能力,如果不学习的话,那么很有可能学得不好。 -
分类误差
(1)做法十分粗鲁,直接相减!
(2)一般情况下,对于分类问题,至少都用softmax激活函数和交叉熵损失函数。 -
注意:
(1)只有当某个网格中 有object 的时候才对 classification error 进行惩罚;
(2)只有当某个 box predictor 对某个 ground truth box 负责的时候,才会对 box 的 coordinate error 进行惩罚,而对哪个 ground truth box 负责就看其预测值和 ground truth box 的 IoU 是不是在那个 cell 的所有 box 中最大。
-
检测
- 每个 bbox 的 confidence 和每个类别的 score 相乘,得到每个 bbox 属于哪一类的 confidence score,即 class-specific confidence scores
- 测试流程: 输入一张图像,到网络的末端得到 7x7x30 的三维矩阵,这里虽然没有计算IOU,但是由训练好的权重已经直接计算出了bounding box 的 confidence。然后再跟预测的类别概率相乘就得到每个 bounding box 属于哪一类的概率。对于上图(里面有dog\bike\car),产生了98个bbox,如何找到最后包含目标的3个bbox呢?(横向是20个类别,纵向是98个bbox)
-
先一行一行的遍历(遍历20次),删除(此处是设置为0)98个bbox里confidence少于指定阈值的框;
-
降序排序,通过NMS,删除多余的框(分类别地对置信度值采用NMS,这里NMS处理结果不是剔除,而是将其置信度值归为0);
-
一列一列的遍历(遍历98次),选出confidence最高的所代表的那个类,然后画框。
-
具体过程:
①假设第一个类是狗,我们设一个阈值0.2,所有小于0.2的全设为0;
②将所有权概率按狗的权概率重新按大到小进行排序,并进行非极大值抑制将多余的bounding box也设为0。
------最左边的最大的bounding box和后面的bounding box分别计算ioU,设ioU阈值为0.5,如果ioU>0.5就将小的bounding box设为0。
-----上一轮结束后,将第二大的bounding box分别和后面的计算,以此类推。狗这一类结束后,重复操作猫类,飞机类等等,以上为NMS。
③经过处理后,98个bounding box中有很多概率为0的类,分别对每个bounding box取最大值,如果最大值也是0就跳过这个bounding box,如果最大值大于0就记下这个概率以及对应的类,然后将这个bounding box中的(x,y,w,h)进行绘框,在框上写上刚刚记下的概率和类,对98个bounding box重复以上操作,至此前向推断完成。
算法缺陷
- 本质性缺陷:重合在一起的物体,拥挤的物体检测效果不好,有可能多个物体的中心落在同一个cell,而每个cell只预测一个类别
- 小物体检测效果不好:网络到后面感受野较大,小特征无法体现;目标小,可能会出现一个grid cell里面有多个物体,但v1只能预测一个
不懂就问
- yolo理论上在训练的时候将图像分成SxS的格子,在代码里面真的有去分吗?
- 如何判断一个grid cell中是否包含object呢?
- object通常是不规则的物体,那么object的中心怎么计算呢?
- 损失函数中为什么要开根号?
- bbox的位置是如何预测出来的?
- 小目标检测效果不好的原因是?
- 参考:yolo问题