为什么要用anchor box?
到目前为止,对象检测中存在一个问题就是每个格子只能预测一个对象,如果想让一个格子检测出多个对象,你可以这么做,就是使用anchor box这个概念,我们从一个例子开始讲吧。
假设我们有这样一张图片,对于这个例子,我们使用3x3的网格,可以观察到,行人和汽车的中心几乎在同一个网格,然而我们以前的方法一个格子只能预测一个对象,而且对于y输出的的向量量𝑦 = [𝑝𝑐 𝑏𝑥 𝑏𝑦 𝑏ℎ 𝑏𝑤 𝑐1 𝑐2 𝑐3 ],你可以检测这三个类别,行人、汽车和摩托车,它将无法输出检测结果,所以我必须从两个检测结果中选一个,这便影响了模型性能,导致一些对象被丢弃无法检测出来。
anchor box 引入
而 anchor box 的思路是,这样子,预先定义两个不同形状的 anchor box,或者 anchor box 形状,你要做的是把预测结果和这两个 anchor box 关联起来。一般来说,你可能会用更多的 anchor box,可能要 5 个甚至更多,我们就用两个 anchor box,这样介绍起来简单一些。
你要做的是定义类别标签,用的向量不再是下面这个:
[𝑝𝑐 𝑏𝑥 𝑏𝑦 𝑏ℎ 𝑏𝑤 𝑐1 𝑐2 𝑐3]𝑇
而是重复两次:
𝑦 = [𝑝𝑐 𝑏𝑥 𝑏𝑦 𝑏ℎ 𝑏𝑤 𝑐1 𝑐2 𝑐3 𝑝𝑐 𝑏𝑥 𝑏𝑦 𝑏ℎ 𝑏𝑤 𝑐1 𝑐2 𝑐3]𝑇
前面8个是和anchor box1相关联,后面8个是和anchor box2相关联。行人一般符合anchor box1形状,所以用anchor box1来预测行人回达到很好的效果,这么编码𝑝𝑐 = 1,代表有个行人,用𝑏𝑥,𝑏𝑦,𝑏ℎ和𝑏𝑤来编码包住行人的边界框,然后用𝑐1,𝑐2,𝑐3(𝑐1 = 1,𝑐2 = 0,𝑐3 = 0)来说明这个对象是个行人。 汽车一般符合anchor box2形状,所以用anchor box2来预测汽车会有很好的效果,你就可以这么编码,这里第二个对象是汽车,然后有这样的边界框等等,这里所有参数都和检测汽车
相关(𝑝𝑐 = 1,𝑏𝑥,𝑏𝑦,𝑏ℎ,𝑏𝑤,𝑐1 = 0,𝑐2 = 1,𝑐3 = 0)。
总结
所以,总的来说,anchor box是这么来做的,现在每个对象和以前一样根据中心点分配到一个格子中,然后看和每个anchor box的IoU(交并比),选择IoU最高的那个,用这个anchor box来进行预测。输出y的维度是nxnxmxc(n为图片分成nxn份,m为anchor box数量,c为class类别数)
缺陷或不足
现在还有一些额外的细节,如果你有两个 anchor box,但在同一个格子中有三个对象,这种情况算法处理不好,你希望这种情况不会发生,但如果真的发生了,这个算法并没有很好的处理办法,对于这种情况,我们就引入一些打破僵局的默认手段。还有这种情况,两个对象都分配到一个格子中,而且它们的 anchor box 形状也一样,这是算法处理不好的另一种情况,你需要引入一些打破僵局的默认手段,专门处理这种情况,希望你的数据集里不会出现这种情况,其实出现的情况不多,所以对性能的影响应该不会很大。 我们建立 anchor box 这个概念,是为了处理两个对象出现在同一个格子的情况,实践中这种情况很少发生,特别是如果你用的是 19×19 网格而不是3×3 的网格,两个对象中点处于 361 个格子中同一个格子的概率很低,确实会出现,但出现频率不高。也许设立 anchor box 的好处在于 anchor box 能让你的学习算法能够更有征对性,特别是如果你的数据集有一些很高很瘦的对象,比如说行人,还有像汽车这样很宽的对象,这样你的算法就能更有针对性的处理,这样有一些输出单元可以针对检测很宽很胖的对象,比如说车子,然后输出一些单元,可以针对检测很高很瘦的对象,比如说行人。
怎么选择anchor box?
1.一般手工指定anchor box形状,根据要检测的对象,指定有针对性地anchor box,可选择5-10个anchor box,使其尽可能覆盖到不同形状。
2.使用K-means聚类算法获得anchor box。
,