在two stage中,比如R-CNN系列里,先找出region proposal然后再把目标检测问题变成分类问题来处理我明白。但是在One Stage目标检测演算法中,比如YOLO,可以直接得到目标的中心点坐标,和归一化的bounding box的宽度和长度是具体怎么得到的?看了一些教程都没有具体写,只是介绍了下YOLO的结构。NG的课也只是说让网路多输出四个数值就可以得到坐标,也没有说具体的过程。

比如就简单说,经过卷积后可以得到3*3*8维度的feature map,然后3*3是划分网格的大小,8就是3个分类+坐标(4)+置信度。可是没有解释为什么这些维度就代表了这些意义。


这个问题不是很明白你意思,只能照著我大概理解的回答下。

  1. 神经网路提取的特征为何可用来作坐标回归? 可参见这篇论文deep neural networks for object detection(这是最早证明神经网路可以用来回归目标坐标的一篇论文,这篇论文通过实验效果证明了neural networks learned features which are not only good for classification, but also capture strong geometric information)(tip: 它其实预测的是object binary mask(分为full, bottom, top, left, right),这篇论文应该不是最早使用神经网路来作目标回归,但是它解决了此类网路无法训练的问题,得到了一个不错的结果)
  2. DPM中也使用了bbox regression(这个我没细看), DPM首先推导出part location,在此location上计算geometric features ,用这个特征来做bbox regression
  3. yolo v1直接预测x, y, w, h,计算坐标loss使用平方差,yolo v1对w, h取了平方根,但是直接预测真实框的坐标值会导致定位不准确,原因是:假设这个loss为1,loss看起来很低,但是对于小框而言,轻微的坐标数值上的偏移,导致视觉上极大的预测偏差,假设这个loss为10,loss看起来很大,但是对于大框而言,很高的坐标数值上的偏移,导致视觉上很小的预测偏差,一句话总结:直接预测真实坐标所产生的loss并不能真正反映预测框的好坏(yolo v1对w, h取了平方根,可以有效缓解这个问题,但是并不能解决这个问题)
  4. RCNN进一步优化了论文1中的bbox regression,对x, y, w, h坐标进行log/exp变换防止出现负数,网路学习的其实是proposal box到gt box的变换系数(为何要学习变换系数,而不直接学习坐标差?比如学习Gx - Px, Gy - Py, 这是因为对于大物体和小物体,它们的差可能一样,但是效果却相差很多,比如大物体和预测大物体的框视觉上离的很近,但是它们的Gx - Px差可能很大),变换系数表示成tx, ty, tw, th,以G表示gt box, P表示proposal box,则tx = (Gx - Px) / Pw, ty = (Gy - Py) / Ph, tw = log(Gw/Pw), th = log(Gh/Ph),它的坐标回归损失函数是加入正则化的均方误差即岭回归
  5. 后续的faster RCNN, yolov2/v3, SSD中,将proposal box分别替换成了anchor box, prior box, default box, 同样回归的是坐标变换系数而非坐标,但是损失函数由加入正则的均方误差变成smooth l1 loss

补充:我没有正面回答你的问题,我补充了坐标回归的发展历史,你回顾下这些,应该对你的理解有帮助

第3点的直接预测坐标和第4点的预测坐标差会产生的问题是一样的

2019.10.17 update

yolo v2中坐标编码方式和上述有点区别:

yolo系列预测x_ctr, y_ctr都是相对于所处grid的归一化值, 使用上文中介绍的tx, ty公式, 不能保证解码出来的x_ctr处于当前gird, 可以偏移到任意grid, 这与yolo v1中设计grid初衷违背, 因此使用sigmoid函数处理偏移值:

bx = (sigmoid(tx) + cy) / W

by = (sigmoid(ty) + cy) / H

而bw, bh和上文中的tw, th公式一致


泻药,仅说我的理解。

这个没什么特别大的原理,只能说是数据驱动下训练的结果。但是这种网路搭建的方案还是符合motivation的。因为诸如RPN,回归结果是通过1x1 conv算出来的(yolo是通过FC),比如主干网路是VGG-16网路,这个1x1的结果对应感受野是原图92x92(没记错的话,vgg的感受野是这个值)的区域(yolo的感受野则是全图,理论上对大目标更好),所以你可以理解为通过看这92x92的区域,让神经网路学习生成一个框去框这92x92区域内/外的东西。

至于它学习的结果为什么能把框框住,我之前与实验室的同僚讨论过。做目标检测的同学可视化过feature maps给我看过,基本上是有目标的区域很亮,没有目标的区域很暗,所以神经网路基本上可以说是根据特征图的明亮程度生成一个框把目标框住。

另外你说的网路输出怎么知道那几个维度上的数是什么意义这件事,是因为训练就是这样训的。现在目标检测有很成熟的一套iou guided的训练策略,你可以看看yolo原文或者rcnn系列的论文进行更深入的研究。


说一下我的理解,欢迎指正。

目标检测演算法为什么能够直接获得目标的位置坐标?这是网路训练的结果,在训练的时候,图片上每个目标的位置坐标都是已知的,这是通过事先标注得到的,称之为真实框位置,网路最终的目标是要预测一个与真实框位置尽量接近的预测框位置,最理想的情况是,预测框位置跟真实框位置相等,这样准确率就是100%了,但实际情况下这是不可能发生的,预测框位置跟真实框位置不可能100%重合,肯定会存在一个误差,我们能够做的就是尽量减少这个误差,误差越小预测框位置就越准。

那么,如何减少误差?可以将这个误差值写成一个loss函数,接下来优化这个loss函数就行了。神经网路其实就是一个函数,如y=ax+b,x是输入,y是输出,a、b是需要确定的参数(即权重),神经网路的训练过程实质就是确定参数a、b的过程,一旦a、b确定了,那么通过函数y=ax+b,给定x就能计算得到y,具体到目标的位置检测,这里的x就是指图片中的某个目标,而y就是这个目标对应的位置信息。也就是说,我们希望能够找到一组足够好的参数a和b,这组参数a和b对于所有图片中的所有目标来说,都能通过y=ax+b计算出某个目标x对应的位置信息y。

那么如何找到这组牛逼哄哄的参数a和b呢?

刚开始时,参数a、b都是随机初始化的,此时当给定一个x,计算得到的位置预测值y跟真实位置肯定是相差十万八千里的,但是没关系,在loss函数的指挥下,通过反向传播,可以一点点地更新和修正参数a,b,经过无数次的训练和更新,参数a和b变得越来越牛逼,网路预测的位置信息y跟真实位置之间的误差越来越小,预测的位置信息越来越接近真实位置,于是当误差小到一定程度,我们就可以将这组a和b当成已知量直接拿来用,也就是说函数y=ax+b中,a,b都是已知的,那么在一张测试图片中(注意,这个时候测试图片中所有目标的位置信息都是未知的),将该图片中的某个目标x输入到函数中,通过一次前向计算就能得到或者预测出该目标的足够准确的位置信息。

说到这里,你可能还有疑问,上面只是解释了得到目标位置信息的过程,但好像并没有解释为什么能够到得到这个位置信息。

那就再解释一下。

首先,有一个前提就是,对于某一类目标来说,肯定会有某个独一无二的特征,猫之所以是猫而不是狗,其实质内涵就是猫必定有与狗或其他目标不同的内在特征,这个特征很难用一两个词语或一两句话描述出来,但是尽管如此,我们不得不承认,每类目标的这种内在特征肯定是客观存在的,而神经网路牛逼的地方,就是能够找到这种内在特征。理解了这一点,再回到目标的位置检测,其实网路训练的过程,就是根据训练图片种的一个个目标逐步更新参数a、b的过程,每一类目标都被被训练了无数次,而由于不同类别的目标之间具有各自独特的内在特征,因此每一类目标中各个独立目标的位置信息可以通过具有相同的参数a、b的函数y=ax+b计算或预测出来,一只猫虽然在不同的图片中可能处于不同的位置,但由于不论其处于哪个位置,猫始终是一只猫而不是一只狗,利用这一类别的确定性,就可以通过预先训练好的参数a、b和函数y=ax+b计算出猫的位置信息。


私以为说One-stage目标检测直接回归目标的坐标不太准确,不如说是回归边框的坐标。论文《CornerNet:Detecting Objects as Paired Keypoints》指出基于One-stage和Two-stage的目标检测框的标注并没有和目标特征产生直接的联系,而网路实际上回归的是检测框的坐标和尺寸。我心目中严格来说直接回归目标坐标的是CornerNet及其衍生的「端到端可训练」的网路。这是第一点。

然后回归到问题本身,YOLO的作者在论文《You Only Look Once: Unified,Real-Time Object Detection》中指出:卷积层的任务是从图像中提取特征,全连接层负责预测输出概率和坐标。YOLOv1中的例子的输出维度是7 * 7 *(5 * 2 + 20),以YOLOv1论文为例,题目中所说定义输出维度的意义分别是:

图像分割为了7 * 7个grid,每个grid预测两个bounding box,总预测分类为20类。其中每个bounding box包含的信息是边框的中心坐标(x, y),边框尺寸长宽(w, h)以及置信度C。YOLO9000和YOLOv3等其他one-stage detectors可以类似地分析,详见他们对应的论文。

最后暗自揣测一下题主究竟纠结的其实并不是以上定义,因为定义的问题题主的举例也说明是知道的,真正纠结的是「这些特征是如何来的」。这就涉及到了卷积网路的设计思路,在论文中也有所体现。仍然以YOLO v1为例,大致的流程为:

1. 系统将输入的图像切分成一个S*S的网路,如果一个目标的中心在这个网格中,那么这个网格就负责检测这个目标。

2. 每个单元格预测B个边界框和这些框的置信度的得分。这些置信度的得分反应了模型预测这个框包含目标的置信度,以及模型的预测这些框的准确度。单元格不存在目标时,置信度为0,即Pr(Object) = 0

3. 每一个边界框包含5个预测值,x,y,w,h以及置信度。(x,y)坐标表示相对于网格边界框的中心,高度h和宽度w是相对于整个图像而言。最后置信度的预测值代表预测框和真实框之间的交并比IOU。

4. 每一个网格预测还预测C条件类概率,Pr(Classi|Object)。这些概率取决于包含目标的网格单元,并且只是预测每个网格单元的一组类别概率,不管框的数量。这么做有一个好处就是,2、3和4得出的参数放在一起可以同时反映出目标属于某一类的可能性以及预测框对目标的拟合情况:

??5. 利用这些概率构建损失函数,进行训练损失函数。损失函数形式如下:

关于这种形式的损失函数设计,论文在2.2章节进行了描述,直接贴出一个我觉得对损失函数讲得比较清楚的博客:https://blog.csdn.net/u014381600/article/details/55505231

接下来的事情就很好理解了,就是通过反向传播修正网路参数,这样就完成了一个目标特征提取的过程了。

参考资料:

论文

《CornerNet:Detecting Objects as Paired Keypoints》

《You Only Look Once: Unified,Real-Time Object Detection》

博客

https://blog.csdn.net/u014381600/article/details/55505231

还有部分来自于个人在csdn博客上的学习笔记整理,文采学识都很有限,就不贴出来献丑了。


或许你的困惑就是一点:为什么接的8个维度可以代表 4coord 3classes 1conf?

我的理解是:

原因是:网路这么搭,才能通过参数不断的更新,学习,得到合适的值,以提取到「合适」的特征区分类别,拟合4个坐标点 的目的。


推荐阅读:
相关文章