目录
- [第四门课 卷积神经网络(Convolutional Neural Networks)](#第四门课 卷积神经网络(Convolutional Neural Networks))
-
- [第三周 目标检测(Object detection)](#第三周 目标检测(Object detection))
-
- [3.9 YOLO 算法(Putting it together: YOLO algorithm)](#3.9 YOLO 算法(Putting it together: YOLO algorithm))
- [3.10 候选区域(选修)(Region proposals (Optional))](#3.10 候选区域(选修)(Region proposals (Optional)))
第四门课 卷积神经网络(Convolutional Neural Networks)
第三周 目标检测(Object detection)
3.9 YOLO 算法(Putting it together: YOLO algorithm)
你们已经学到对象检测算法的大部分组件了,在这个视频里,我们会把所有组件组装在一起构成 YOLO 对象检测算法。
我们先看看如何构造你的训练集,假设你要训练一个算法去检测三种对象,行人、汽车和摩托车,你还需要显式指定完整的背景类别。这里有 3 个类别标签,如果你要用两个 anchor box,那么输出 𝑦 就是 3×3×2×8,其中 3×3 表示 3×3 个网格,2 是 anchor box 的数量,8 是向量维度,8 实际上先是 5(𝑝𝑐, 𝑏𝑥, 𝑏𝑦, 𝑏ℎ, 𝑏𝑤)再加上类别的数量(𝑐1, 𝑐2, 𝑐3)。你可以将它看成是 3×3×2×8,或者 3×3×16。要构造训练集,你需要遍历 9 个格子,然后构成对应的目标向量𝑦。
所以先看看第一个格子(编号 1),里面没什么有价值的东西,行人、车子和摩托车,三个类别都没有出现在左上格子中,所以对应那个格子目标 𝑦 就是这样的,𝑦 = [ 0 ? ? ? ? ? ? ? 0 ? ? ? ? ? ? ? ] T \begin{bmatrix} 0&?&?&?&?&?&?&?&0&?&?&?&?&?&?&? \end{bmatrix}^T [0???????0???????]T,第一个 anchor box 的 𝑝𝑐 是 0,因为没什么和第一个 anchor box 有关的,第二个 anchor box 的 𝑝𝑐 也是 0,剩下这些值是 don'tcare-s。
现在网格中大多数格子都是空的,但那里的格子(编号 2)会有这个目标向量𝑦,𝑦 = [ 0 ? ? ? ? ? ? ? 1 b x b y b h b w 0 1 0 ] \begin{bmatrix}0&?&?&?&?&?&?&?&1&b_x&b_y&b_h&b_w&0&1&0 \end{bmatrix} [0???????1bxbybhbw010],所以假设你的训练集中,对于车子有这样一个边界框(编号 3),水平方向更长一点。所以如果这是你的 anchor box,这是 anchor box 1(编号 4),这是 anchor box 2(编号 5),然后红框和 anchor box 2 的交并比更高,那么车子就和向量的下半部分相关。要注意,这里和 anchor box 1 有关的 𝑝𝑐 是 0,剩下这些分量都是 don't care-s,然后你的第二个 𝑝𝑐 = 1,然后你要用这些(𝑏𝑥, 𝑏𝑦, 𝑏ℎ, 𝑏𝑤)来指定红边界框的位置,然后指定它的正确类别是 2(𝑐1 = 0, 𝑐2 = 1, 𝑐3 = 0),对吧,这是一辆汽车。
所以你这样遍历 9 个格子,遍历 3×3 网格的所有位置,你会得到这样一个向量,得到一个 16 维向量,所以最终输出尺寸就是 3×3×16。和之前一样,简单起见,我在这里用的是 3×3网格,实践中用的可能是 19×19×16,或者需要用到更多的 anchor box,可能是 19×19×5×8,
即 19×19×40,用了 5 个 anchor box。这就是训练集,然后你训练一个卷积网络,输入是图片,可能是 100×100×3,然后你的卷积网络最后输出尺寸是,在我们例子中是 3×3×16 或者3×3×2×8。
接下来我们看看你的算法是怎样做出预测的,输入图像,你的神经网络的输出尺寸是这个 3××3×2×8,对于 9 个格子,每个都有对应的向量。对于左上的格子(编号 1),那里没有任何对象,那么我们希望你的神经网络在那里(第一个𝑝𝑐)输出的是 0,这里(第二个𝑝𝑐)是 0,然后我们输出一些值,你的神经网络不能输出问号,不能输出 don't care-s,剩下的我输入一些数字,但这些数字基本上会被忽略,因为神经网络告诉你,那里没有任何东西,所以输出是不是对应一个类别的边界框无关紧要,所以基本上是一组数字,多多少少都是噪音(输出 𝑦 如编号 3 所示)。
和这里的边界框不大一样,希望𝑦的值,那个左下格子(编号 2)的输出𝑦(编号 4 所示),形式是,对于边界框 1 来说(𝑝𝑐)是 0,然后就是一组数字,就是噪音(anchor box 1对应行人,此格子中无行人,𝑝𝑐 = 0, 𝑏𝑥 =? , 𝑏𝑦 =? , 𝑏ℎ =? , 𝑏𝑤 =? , 𝑐1 =? 𝑐2 =? , 𝑐3 =?)。希望你的算法能输出一些数字,可以对车子指定一个相当准确的边界框(anchor box 2 对应汽车,此格子中有车,𝑝𝑐 = 1, 𝑏𝑥, 𝑏𝑦, 𝑏ℎ, 𝑏𝑤, 𝑐1 = 0, 𝑐2 = 1, 𝑐3 = 0),这就是神经网络做出预测的过程。
最后你要运行一下这个非极大值抑制,为了让内容更有趣一些,我们看看一张新的测试图像,这就是运行非极大值抑制的过程。如果你使用两个 anchor box,那么对于 9 个格子中任何一个都会有两个预测的边界框,其中一个的概率𝑝𝑐很低。但 9 个格子中,每个都有两个预测的边界框,比如说我们得到的边界框是是这样的,注意有一些边界框可以超出所在格子的高度和宽度(编号 1 所示)。接下来你抛弃概率很低的预测,去掉这些连神经网络都说,这里很可能什么都没有,所以你需要抛弃这些(编号 2 所示)。
最后,如果你有三个对象检测类别,你希望检测行人,汽车和摩托车,那么你要做的是,对于每个类别单独运行非极大值抑制,处理预测结果所属类别的边界框,用非极大值抑制来处理行人类别,用非极大值抑制处理车子类别,然后对摩托车类别进行非极大值抑制,运行三次来得到最终的预测结果。所以算法的输出最好能够检测出图像里所有的车子,还有所有的行人(编号 3 所示)。
这就是 YOLO 对象检测算法,这实际上是最有效的对象检测算法之一,包含了整个计算机视觉对象检测领域文献中很多最精妙的思路。你可以在本周的编程作业中尝试现实这个算法,所以我希望你喜欢本周的编程练习,这里还有一个可选的视频,你们可以看,也可以不看,总之,我们下周见。
3.10 候选区域(选修)(Region proposals (Optional))
如果你们阅读一下对象检测的文献,可能会看到一组概念,所谓的候选区域,这在计算机视觉领域是非常有影响力的概念。我把这个视频定为可选视频是因为我用到候选区域这一系列算法的频率没有那么高,但当然了,这些工作是很有影响力的,你们在工作中也可能会碰到,我们来看看。
你们还记得滑动窗法吧,你使用训练过的分类器,在这些窗口中全部运行一遍,然后运行一个检测器,看看里面是否有车辆,行人和摩托车。现在你也可以运行一下卷积算法,这个算法的其中一个缺点是,它在显然没有任何对象的区域浪费时间,对吧。
所以这里这个矩形区域(编号 1)基本是空的,显然没有什么需要分类的东西。也许算法会在这个矩形上(编号 2)运行,而你知道上面没有什么有趣的东西。
[Girshick R, Donahue J, Darrell T, et al. Rich feature hierarchies for accurate object detection and semantic segmentation[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2014: 580-587.]
所以 Ross Girshick,Jeff Donahue,Trevor Darrell,Jitendra Malik,在本幻灯片底部引用到的论文中提出一种叫做 R-CNN 的算法,意思是带区域的卷积网络,或者说带区域的 CNN。这个算法尝试选出一些区域,在这些区域上运行卷积网络分类器是有意义的,所以这里不再
针对每个滑动窗运行检测算法,而是只选择一些窗口,在少数窗口上运行卷积网络分类器。
选出候选区域的方法是运行图像分割算法,分割的结果是下边的图像,为了找出可能存在对象的区域。比如说,分割算法在这里得到一个色块,所以你可能会选择这样的边界框(编号 1),然后在这个色块上运行分类器,就像这个绿色的东西(编号 2),在这里找到一个色块,接下来我们还会在那个矩形上(编号 2)运行一次分类器,看看有没有东西。在这种情况下,如果在蓝色色块上(编号 3)运行分类器,希望你能检测出一个行人,如果你在青色色块(编号 4)上运行算法,也许你可以发现一辆车,我也不确定。
所以这个细节就是所谓的分割算法,你先找出可能 2000 多个色块,然后在这 2000 个色块上放置边界框,然后在这 2000 个色块上运行分类器,这样需要处理的位置可能要少的多,可以减少卷积网络分类器运行时间,比在图像所有位置运行一遍分类器要快。特别是这种情况,现在不仅是在方形区域(编号 5)中运行卷积网络,我们还会在高高瘦瘦(编号 6)的区域运行,尝试检测出行人,然后我们在很宽很胖的区域(编号 7)运行,尝试检测出车辆,同时在各种尺度运行分类器。
这就是 R-CNN 或者区域 CNN 的特色概念,现在看来 R-CNN 算法还是很慢的。所以有一系列的研究工作去改进这个算法,所以基本的 R-CNN 算法是使用某种算法求出候选区域,然后对每个候选区域运行一下分类器,每个区域会输出一个标签,有没有车子?有没有行人?有没有摩托车?并输出一个边界框,这样你就能在确实存在对象的区域得到一个精确的边界框。
澄清一下,R-CNN 算法不会直接信任输入的边界框,它也会输出一个边界框𝑏𝑥,𝑏𝑦,𝑏ℎ和𝑏𝑤,这样得到的边界框比较精确,比单纯使用图像分割算法给出的色块边界要好,所以它可以得到相当精确的边界框。
现在R-CNN算法的一个缺点是太慢了,所以这些年来有一些对R-CNN算法的改进工作,Ross Girshik 提出了 Fast R-CNN 算法,它基本上是 R-CNN 算法,不过用卷积实现了滑动窗法。最初的算法是逐一对区域分类的,所以 Fast R-CNN 用的是滑动窗法的一个卷积实现,这和
你在本周第四个视频(3.4 卷积的滑动窗口实现)中看到的大致相似,这显著提升了 R-CNN的速度。
事实证明,Fast R-CNN 算法的其中一个问题是得到候选区域的聚类步骤仍然非常缓慢,所以另一个研究组,任少卿(Shaoqing Ren)、何凯明(Kaiming He)、Ross Girshick 和孙剑(Jiangxi Sun)提出了更快的 R-CNN 算法(Faster R-CNN),使用的是卷积神经网络,而不是更传统的分割算法来获得候选区域色块,结果比 Fast R-CNN 算法快得多。不过我认为大多数Faster R-CNN 的算法实现还是比 YOLO 算法慢很多。
候选区域的概念在计算机视觉领域的影响力相当大,所以我希望你们能了解一下这些算法,因为你可以看到还有人在用这些概念。对我个人来说,这是我的个人看法而不是整个计算机视觉研究界的看法,我觉得候选区域是一个有趣的想法,但这个方法需要两步,首先得到候选区域,然后再分类,相比之下,能够一步做完,类似于 YOLO 或者你只看一次(You only look once)这个算法,在我看来,是长远而言更有希望的方向。但这是我的个人看法,而不是整个计算机视觉研究界的看法,所以你们最好批判接受。但我想这个 R-CNN 概念,你可能会想到,或者碰到其他人在用,所以这也是值得了解的,这样你可以更好地理解别人的算法。
现在我们就讲完这周对象检测的材料了,我希望你们喜欢本周的编程练习,我们下周见。