文章源于我的个人博客,地址:目标识别 YOLO 学习笔记(一), 尊重原创,转载请注明。
这个笔记,主要是学习 YOLO 入门教程《How to implement a YOLO (v3) object detector from scratch in PyTorch》的笔记,其中包含自己学习过程中遇到的不懂之处的记录,其中一些英文单词并没有翻译,考虑到因为语言的差异,中文很难表达地很形象。与大家分享,以交流共勉。
笔记也会分为5个部分,层层递进,使用 PyTorch实现 YOLO (v3)。 完整的内容可参考原教程,在这里对教程的作者表示感谢。
YOLO 全称为 You Only Look Once.
YOLO 是全卷积网络,一共有75个卷积层,其中包含 skip connections 和 unsampling 层。没有使用任何池化层,使用步长为2的卷积层对特征图进行下采样(downsample), 这就避免了由于池化所带来的低阶特征消失的问题。
虽然全卷积网络对图像的输入大小并不敏感,但我们仍希望输入图像的大小是固定了,以免在实现算法的过程中出现各种问题。
这些问题中最重要的一点是,如果我们想要批量处理图像(批量生成的图像可以由GPU并行处理,从而提高速度),我们需要拥有固定高度和宽度的图像。 这需要将多个图像连接成一个大批量(将许多PyTorch张量连接成一个)
在YOLO中,通过使用使用1×1卷积的卷积层来完成预测。
所以,在YOLO中,输出是一个feature map。 由于我们使用了1 x 1个卷积,因此预测map的大小正好是之前的feature map的大小。 在YOLO v3(及其后代)中,您解释此预测图的方式是每个单元格可以预测固定数量的边界框。
深度方面,我们在特征图中有$B \times (5 + C)) $个条目,其中B 代表每个cell 可以预测的边界框(bounding box)的数量,根据论文研究,每个边界框可以专门检测某种对象。每个边界框有 ( 5 + C ) (5+C) (5+C) 个属性,描述了每个边界框的中心坐标,尺寸,对象度分数和C类置信度(confidence)。YOLO v3 在每个cell中预测三个边界框。
如果对象的中心落在该cell 的感知区域中,您希望feature map的每个cell 通过其中一个边界框预测对象。
与YOLO的训练方式有关的是,只有一个边界框(bounding box)负责检测任何给定的对象,即我们要确定这个边界框属于哪个 cell。为此,我们将输入图像划分为尺寸等于最终feature map的网格。
举例来说,我们有一个 416×416 的输入图像,网络的stride 为 32, 那么我们就将图像划为 13×13 个网格,即将输入图像切割为 13×13 个 cell。
然后,选择包含对象的ground truth box的中心的单元(在输入图像上)作为负责预测对象的单元。在该例子中,红色的cell 就是包含 ground truth box (黄色框)中心的cell。
现在,红色单元格是网格中第7行第7列的单元格。我们现在将特征图上的第7行中的第7个单元(特征图上的相应单元)指定为负责检测狗的单元。
现在,这个 cell 可以预测3个 bounding box(YOLO v3 中每个cell预测3个bounding box),那么哪一个将作为狗的 ground truth label呢?
预测bounding box的宽度和高度可能是有意义的,但实际上,这会导致训练期间出现不稳定的梯度。 相反,大多数现代 object detectors 预测对数空间变换(log-space transforms),或简单地偏移到预定义的称为**锚(anchor)**的default bounding box。
然后,将这些reansforms 应用于 anchor 以获得预测。 YOLO v3有三个anchor,可以预测每个单元格的三个边界框
回到我们之前的问题,负责检测狗的bounding box将是其 anchor 具有最高IoU和ground truth box的那个。
下面的公式给出了 如何由神经网络的输出经过转换,获得 bounding box 的预测。
b x = σ ( t x ) + c x b y = σ ( t y ) + c y b w = p w e t w b h = p h e t h b_x = \sigma (t_x) + c_x \\ b_y = \sigma (t_y) + c_y \\ b_w = p_w e^{t_w} \\ b_h = p_h e^{t_h} bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pheth
这里的 b x , b y , b w , b h b_x, b_y, b_w, b_h bx,by,bw,bh 分别是预测的中心坐标,宽度和高度; t x , t y , t w , t h t_x, t_y, t_w, t_h tx,ty,tw,th 是神经网络的输出; c x , c y c_x, c_y cx,cy 是ground truth box 中的中心所在网格(grid)的左上角坐标; p w , p h p_w, p_h pw,ph 是 box 的 anchor 尺寸。 σ \sigma σ代表 sigmoid 函数
我们使用 sigmoid 函数来寻找我们的中心坐标的预测,这样的输出值范围为 0~1,我们为什么这么做呢?
通常,YOLO不会预测 bounding box中心的绝对坐标,它预测的是偏移量:
例如,考虑上面的狗的图像,如果对中心的预测是(0.4, 0.7),那么这意味着中心位于13 x 13特征图上的(6.4,6.7)。(因为红色 cell 的左上角坐标是(6,6))
但是,如果预测的x,y坐标大于1,会发生什么呢?比如(1.2, 0.7), 这意味着中心位于(7.2, 6.7)。 请注意,中心现在位于我们的红色 cell 右侧的cell中,或者位于第7行的第8个cell中。 这打破了YOLO背后的理论,因为如果我们假设红色框负责预测狗,那么狗的中心必须位于红色单元格中,而不是位于旁边的单元格中。 因此,为了解决这个问题,输出通过sigmoid函数,该函数将输出压缩在0到1的范围内,有效地将中心保持在预测的网格中。
通过对输出应用 对数空间变换(log-space transform),然后乘以anchor 来预测边界框的尺寸。
预测得到的 b w , b h b_w, b_h bw,bh 是经过图像的高度和宽度标准化的,因此,如果包含狗的bounding box 的预测bx和by是(0.3, 0.8),那么13 x 13特征图上的实际宽度和高度是(13 x 0.3,13 x 0.8)。
object score 表示对象包含在边界框内的概率。 对于红色和相邻的网格,它应该接近1,而对于角落处的网格,几乎为0。 对象性得分也通过sigmoid传递,因为它被解释为概率。
Class confidences (置信度)表示检测到的对象属于特定类(狗,猫,香蕉,汽车等)的概率。 在v3之前,YOLO使用 softmax的class score, 但是,该设计选择已在v3中删除,作者选择使用sigmoid。 原因是Softmaxing类得分假设类是互斥的。 简单来说,如果一个对象属于一个类,那么它就保证它不属于另一个类。 这对于我们将以检测器为基础的COCO数据库来说是正确的。 但是,当我们有像女人和人一样的课程时,这种假设可能不会成立。 这就是作者避免使用Softmax 的原因。
YOLO v3通过3种不同的尺度进行预测。 检测层用于在三种不同尺寸的特征图上进行检测,分别具有步幅32,16,8。 这意味着,在输入为416 x 416的情况下,我们在13 x 13,26 x 26和52 x 52尺寸上进行检测。
网络对输入图像进行下采样,直到第一个检测层为止,其中使用具有步幅32的layer的feature maps 进行检测。 此外,对层进行2倍上采样,并与具有相同feature map尺寸的先前层的feature map连接。在具有步幅16的层处进行另一检测。重复相同的上采样过程,并且在步幅8的层处进行最终检测。在每个比例下,每个单元使用3个anchor来预测3个bounding box,使得使用的 anthor总数为9.(不同尺度的anchor不同)
对于一个输入为 416×416 的图像,YOLO检测到 ( 52 × 52 + 26 × 26 + 13 × 13 ) × 3 = 10647 (52 \times 52 + 26 \times 26 + 13 \times 13) \times 3 = 10647 (52×52+26×26+13×13)×3=10647 个 bounding box, 但是对于我们的例子,图像中只有一个需要检测的对象,那么如何从 10467 得到 1 呢?
通过对象置信度进行阈值处理。
首先,我们根据 objectness score 过滤boxes,通常,忽略具有低于阈值分数的box。
NMS旨在解决同一图像的多次检测问题,这时可以使用 NMS 算法获取其中最好的一个 box。
1. 是什么
中文可以译为 “感受野”。(个人感觉译过来并不好,直接使用英文就好)
The receptive field is defined as the region in the input space that a particular CNN’s feature is looking at.
在卷积神经网络中,receptive map 的定义是:卷积神经网络每一层输出的特征图(feature map)上的像素点在原始图像上映射的区域大小。
在机器视觉领域的深度神经网络中的 receptive field,用来表示网络内部的不同位置的神经元对原图像的感受范围的大小。
所以,总结来看,receptive field 就是输入图像对某一层输出神经元的影响有多大。
2. Receptive Field 计算公式
从第一层卷积层,层层迭代,计算RF
R F N = ( R F N − 1 − 1 ) ∗ s t r i d e + k e r n e l RF_{N} = (RF_{N-1} - 1) * stride + kernel RFN=(RFN−1−1)∗stride+kernel
其中 R F N − 1 RF_{N-1} RFN−1 表示第(N-1)层神经网络的 RF, R F N RF_N RFN 表示第 N 层 的RF,stride 表示由 (N-1) 层到 (N) 层的卷积步长,kernel表示卷积核大小。
注意:卷积神经网络的第一个卷积层的 RF 就是卷积核大小,因为它的一个像素点,代表了上一层的 kernel 个像素点的特征,这就是RF 的含义。
3. 举例
举一个例子,原始图像为 5 × 5 5 \times 5 5×5,卷积核(Kernel Size)为 3 × 3 3 \times 3 3×3 ,padding 为 1 t i m e s 1 1 \ times 1 1 times1,stride为 2 × 2 2 \times 2 2×2,依照此卷积规则,连续做两次卷积,则第一次卷积结果是 3 × 3 3 \times 3 3×3的feature map,第二次卷积结果是 2 × 2 2 \times 2 2×2 大小的feature map。
则第一层卷积结束后,RF 为 3 × 3 3 \times 3 3×3; 第二层卷积结束后,RF 大小为 ( 3 − 1 ) ∗ 2 + 3 = 7 (3-1)*2+3 = 7 (3−1)∗2+3=7
4. 检验RF
下面这个网站提供了 RF 的一键计算功能。
FOMORO AI
三个高级工程师搞的网站,可以简单的输入网络参数,就直接把你的感受野计算出来。界面如下。
IoU 用来表征在目标检测中,预测的 bounding box 和 ground truth 的bounding box 的重合程度。