前言
由于本文章介绍的YOLOV1过于简略,建议先对YOLOV1有一个基本的了解再来看,相信会有新的收获。
YOLOV1网络结构
一个并不怎么难的CNN网络,通过1×1卷积来减少参数量,最后通过两个全连接层输出一个7×7×30的张量。
除最后一层是线性激活,其他层的激活函数选择的是用带泄漏的ReLU。
YOLO预测全过程
输入一张图片,裁剪成448×448的大小,通过CNN网络,输出一个7×7×30的张量。
张量的含义:
我们将图片划分为S×S的网格,每个网格生成B个预测框,预测C个类别概率。
- 注意,虽然一个网格生成了B个预测框,但每个网格最多只能预测一个物体,因此并不需要B×C个类别概率,只需要C个类别概率即可。
一个预测框需要一个中心点(x,y)和长宽(w,h)来表示所处的位置和大小,最后需要一个置信度C来表示这个预测框正确的概率。所以每个预测框需要(x,y,w,h,C)5个参数。
一个网格B个预测框,加上C个类别的概率就是(5×B+C)个参数,共S×S个网格,则输出结果要是一个S×S×(5×B+C)大小的张量。
论文中取S=7,B=2,C=20,即输出7×7×30的张量,共预测了7×7×2=98个框。
但这98个框不可能全部使用,有些预测框内没有物体,有些预测框重复了,我们需要使用 置信度阈值 和 NMS(非极大抑制) 来进行框的筛选。
对输出的7×7×30的张量,进行如下处理:
- 将每个框的置信度(共7×7×2个框)和每个网格的类别概率相乘(同一个网格的框共用相同的类别概率),得到98个长度20的张量(可以看做98×20的矩阵),这些张量代表每个框预测不同类别的置信度。
- 从第一个类别开始,将低于置信度阈值的类别置信度全部置零,剩下的从大到小排列。此时预测该类别的框已经按置信度从大到小排好了。
- 从前往后进行非极大值抑制,即两两比较,若IOU高于阈值,将后面预测这个类别概率的框置零。
- 对所有类别都做一次NMS,最后得到一个稀疏矩阵。
- 根据稀疏矩阵中不为0的值寻找对应的框,即为最后的结果。
建议自己画矩阵重新推一遍,相信能更深入的理解。
YOLO训练
YOLO损失函数
损失函数只关心三种情况:
- 网格中包含预测物体
- 预测框中包含预测物体
- 预测框中不包含预测物体
我们知道一个网格有B个预测框,为什么有的关心网格,有的关心预测框呢?因为概率,我们知道每个网格虽然有多个框,但只有一组概率。
所以:当网格中包含物体时,网格预测的概率应该接近真实物体,这是第五项损失函数干的事情。
由于每个框都预测(x,y,w,h,C),所以置信度和框的定位大小通过框来区分。
所以:
- 当框负责预测该物体时,框的定位和大小应该和训练集中标注的框位置大小接近,框的置信度应该和该框和训练集中标注框的IOU相等。这是第一、二、三项损失函数干的事情。
- 当框不负责预测该物体时,框的定位和大小我们就不需要关心了,只需要保证框的置信度接近0即可,这是第四项损失函数干的事情。
训练过程
刚开始随机初始化参数,生成一个随机的7×7×30的张量,这个张量隐含了98个框以及置信度和条件概率。
通过损失函数来训练这个网络,使生成的张量具有以下特性:
- 若网格包含预测物体,那么网格预测的条件概率越准越好(对应物体类别的概率接近1,其他物体类别概率接近0)。
- 若网格不包含预测物体,那么条件概率随意。
- 能够预测物体的框,置信度越接近1越好,定位和大小与训练集中标注的越接近越好。
- 不预测物体的框,置信度越接近0越好,定位和大小随意。
至此训练完成。