YOLOv1原理

从论文到代码实现需要知道的具体处理~

一、论文简要解读

1、优点:

  • fast,原因:将检测视作回归问题,没有复杂的网络传输过程(如R-CNN分为四个阶段:特征提取、候选框提取、分类、回归)。
    【神经网络回归问题与分类问题在损失函数上的区别:回归问题可用平方损失函数,分类问题一般用softmax损失函数
    (可以理解为,要做回归问题则用平方损失,分类问题则用softmax损失,网络其他方面均一致?)
  • 背景分类准,原因:对整张图片进行卷积等操作,可以推理图片全局而不是局部。
  • 可迁移到其他领域,原因:学习目标的一般化表示?

2、单元检测:

  • 将输入图片分成 SSS * S的cell,如果目标中心落入某个cell,该cell负责检测该目标 ?
  • 每个cell预测 BB 个bounding boxes,每个bounding box有一个置信度 confidenceconfidence,如果某bounding box中没有目标,则 confidence=0confidence = 0,反之,confidence=IOUpredtruthconfidence = IOU_{pred}^{truth}
  • 每个bounding box包含5个预测值,x,y,w,h,confidencex, y, w, h, confidence
  • 每个cell预测一个类别,即输出 Pr(ClassiObject)Pr(Class_i | Object)
  • 假设一共C类,则网络输出:SS(B5+C)S * S * ( B * 5 + C )
  • 预测时,预测概率 = confidence * Pr(Class_i | Object)

二、训练

准备训练数据:图片和标签

1、原始图片和标签

  • 输入图片:
    YOLOv1原理详解---训练 & 测试
    【原始图片大小:width:960, height:530】
  • xml文件信息
    YOLOv1原理详解---训练 & 测试
  • 目标类别:[‘airplane’,‘ship’,‘storage tank’,‘baseball diamond’,‘tennis court’,
    ‘basketball court’,‘ground track field’,‘harbor’,‘bridge’,‘vehicle’]

2、转化为训练用的图片和标签

图片转换:

  • 原始图片resize到指定尺寸imageSizeimageSize,如 448*448,通道数默认为3。
  • 像素值归一化到 (-1,1),方法:设某个像素点的值为 xx ,归一化后的值为 x25521\frac{x}{255}*2-1

标签转换:

  • 首先需将该张图片中的每一个bounding box转化成 [confidence,x1,y1,x2,y2,Pr(ClassiObject,i=1,...,C)][confidence, x_1, y_1, x_2, y_2, Pr(Class_i | Object, i=1,...,C)]的格式。
    如上述图片有两个bounding box,标签转化后分别为:
    [1,xcenter,ycenter,w,h,0,0,0,1,0,0,0,0,0,0][1, x_{center}, y_{center}, w, h,0,0,0,1,0,0,0,0,0,0]
    [1,xcenter,ycenter,w,h,0,0,0,0,0,1,0,0,0,0][1, x_{center}, y_{center}, w, h,0,0,0,0,0,1,0,0,0,0]
    (baseball diamond在目标类别的第4个,ground track field在第6个)
  • 上述xcenter,ycenter,w,hx_{center}, y_{center}, w, h的计算(以第一个box为例):
    首先,由于图片尺寸已经发生了变化,由原尺寸resize到(448,448,3),所以xml文件中bounding box的坐标也应相应地改变。
    wratio=imageSize/weightw_{ratio}=imageSize / weight, hratio=imageSize/heighth_{ratio}=imageSize/height
    则,x1=max(min((xmin1)wratio,imageSize1),0)x_1=max(min((x_{min}-1)*w_{ratio}, imageSize-1),0)
    (解析:python中数组位置是从0开始的,所以xminx_{min}imageSizeimageSize需要减1,imageSizeimageSize大于weightweight时,(x_{min}-1)*w_{ratio}可能会大于imageSize-1,但由于图片已经resize到imageSize尺寸,所以需取小;与0取最大是为了防止出现小于0的情况,一般不会出现。)
    同样地,
    y1=max(min((ymin1)hratio,imageSize1),0)y_1=max(min((y_{min}-1)*h_{ratio}, imageSize-1),0)
    x2=max(min((xmax1)wratio,imageSize1),0)x_2=max(min((x_{max}-1)*w_{ratio}, imageSize-1),0)
    y2=max(min((ymax1)hratio,imageSize1),0)y_2=max(min((y_{max}-1)*h_{ratio}, imageSize-1),0)
    将坐标转化为目标中心坐标和宽高:
    xcenter=(x1+x2)/2x_{center}=(x_1+x_2)/2
    ycenter=(y1+y2)/2y_{center}=(y_1+y_2)/2
    w=x2x1w=x_2-x_1
    h=y2y1h=y_2-y_1
  • 根据目标中心落入的cell,将标签赋值给对应cell
    计算目标中新落在SSS*S的哪个cell中:
    i=ceil(xcenterS/imageSize)i = ceil(x_{center} * S / imageSize)
    j=ceil(ycenterS/imageSize)j = ceil(y_{center} * S / imageSize)
    ceil表示向下取整。算得落在第(i,j)个cell。
    将每张图片标签转化为 SS(B5+C)S*S*(B*5+C)这种形式,算得的第(i,j)个位置的cell,赋值 [1,xcenter,ycenter,w,h,0,0,0,1,0,0,0,0,0,0][1, x_{center}, y_{center}, w, h,0,0,0,1,0,0,0,0,0,0]
    至此训练数据的标签转换完成。

计算损失函数

一张图片传入yolo网络中,经过卷积、池化、全连接等操作,最终输出 (SS(B5+C))1(S*S*(B*5+C)) * 1 的向量,重排成 SS(B5+C)S*S*(B*5+C)维度的向量。

  • 首先根据输出的 SSBS*S*B个框的bounding box坐标和宽高四个值计算iou,判断bounding box中是否有目标。
    需要注意的是:
    a. 经过网络预测的每个cell共有 BB 个bounding box,而真实的标签每个cell只有一个bounding box的值,需要用预测的 BB 个bounding box 分别与真实的对应cell中的一个 bounding box计算IOU。
    b. 预测出的bounding box坐标是没有网格位置概念的,相当于预测出的bounding box 是基于一个网格的,而真实的标签box中心坐标是基于整张图片的,所以需要将二者转换成一致的概念才能进行计算,可以对预测出的bounding box依照 SSS*S个网格的位置关系加上相应的偏移量。
    c. 由于损失函数中是对bounding box的宽和高的开平方进行计算的,所以计算出的预测的bounding box中实际是宽和高的开平方,与真实bounding box计算IOU时需对这两个位置的数值进行平方,才是实际的宽和高。

  • 在同一个cell中的 BB个bounding box中选取IOU最大的一个bounding box,标记为有目标,其他标记为无目标,根据损失函数表达式计算损失值。
    (有一个地方还没想明白:bounding box中有目标时,置信度的损失函数计算,为什么是减去 IOUpredtruthIOU_{pred}^{truth},而不是直接减去1?)

  • 对损失函数进行优化,使其达到最小,最终可算出权重。

三、测试

图片准备

将输入图片做与训练图片一样的resize和归一化

输出bounding box

将处理后的图片输入到网络中,得到 SS(B5+C)S*S*(B*5+C) 的输出,

计算满足IOU阈值条件的bounding box

对于每个cell,计算该cell中每个bounding box的置信度分别与该cell中每个类别的类别概率相乘的结果,最终算得一个 SSBCS*S*B*C维的向量,计算 SSBCS*S*B*C个值中大于IOU阈值的值的位置,其余位置的值全部记为0,若 CC个值中只要有一个大于0,说明该bounding box中含有目标。根据计算 SSBCS*S*B*C个值中大于IOU阈值的值的位置,提取出所有的bounding box,以及对应的置信度和类别。
注意:输出的bounding box同样需要加上偏移量

非极大值抑制(NMS)

上面选出的bounding box中存在一些bounding box的IOU大于给定阈值,即认为两个bounding box内的目标是同一个目标,这时选取IOU最大的那个作为输出的bounding box。最终直到没有任何两个bounding box的IOU大于给定阈值。
yolov1算法做NMS时,没有考虑两个bounding box中的目标类别是否一致,直接根据IOU做NMS。这种做法是存在缺陷的,对于重叠区域较高的不同目标无法全部检测出来。


可能会有理解有出入的地方,欢迎交流~

相关文章: