YOLO输出
假设我要训练一个 CNN 来识别三种类别:人、猫、狗。因此输出向量Y将只有三个元素C1、C2、C3,每个元素都是一个类别得分。如果有更多类别,这个向量将边长。对于上图,我们希望训练CNN识别图像中的人,并用一个边界框定位人。为此,向输出向量中添加边界框参数-x、y、w、h用于确定边界框的大小。x、y确定边框中心坐标;w、h确定边界框的宽和高。
滑动窗口
因为对象可以在给定图像的任何位置,你可以通过在整个图像上滑动一个小窗口,并检查创建的每个窗口中是否有对象 确保检测到所有这些对象。
滑动窗口:
- 选择窗口大小:希望窗口足够小 能够捕获图像中的任何小对象
- 然后将窗口放在图像的开始位置,并将窗口中的区域馈送到训练的 CNN 中
-
对于每个区域 这个 CNN 都会输出一个预测,即这个输出向量 y。pc 是介于 0 和 1 之间的概率,表示窗口中是否有对象。如果没有检测到对象,就不需要继续尝试分类该图像区域。
在此示例中 我们发现第一个窗口区域,不包含我们要查找的任何类别。此时 CNN 将输出一个 pc 等于 0 的向量。
滑动窗口方法效果不错,但是非常消耗计算资源。因为我们需要用不同大小的窗口扫描整个图像,并且需要将每个窗口馈送到 CNN 中。
eg.假设图片为16163
1.选择一个10*10像素的窗口:
如果使用2像素的步幅,则需要16个窗口才能覆盖整个图像:
在最初的Sliding Windows方法中,这16个窗口中的每一个都必须通过CNN单独传递。我们假设CNN具有以下架构:
CNN将10 x 10 x 3图像作为输入,然后它应用5,7 x 7 x 3过滤器。然后使用2 x 2 最大池化,然后是128 个2 x 2 x 5卷积核,然后是具有128个1 x 1 x 128卷积核。最后它具有8个1 x 1 x 128卷积核,代表softmax输出。
将上述CNN的输入从10 x 10 x 3改为16 x 16 x 3
可以看到,这个CNN架构与前面所示相同。如果第一个窗口通过CNN,可以看到结果是最后一个图层左上角。类似地,第二个窗口通过CNN,会在最后一层看到相应的结果:
同样,如果我们通过这个CNN跟随对应于第三个窗口的图像部分,我们会在最后一层看到相应的结果,如下图所示:
实际上,如果我们通过CNN跟踪所有的窗口,会看到所有16个窗口都包含在这个CNN的最后一层。因此,通过CNN单独传递16个窗口与通过CNN传递整个图像完全相同。
这种技术使整个过程更加高效。然而,这种技术有一个缺点:边界框的位置不会非常准确。原因是给定大小的窗口和步幅不可能完美地匹配图像中的对象。
为了提高边界框的准确性,YOLO使用网格而不是滑动窗口,并且使用交并比和非极大值抑制(Intersection Over Union and Non-Maximal Suppression)
上述技术的组合是YOLO算法运行良好的部分原因.
使用网格
滑动窗口实施起来非常慢,但是你选择的步长使每个窗口都能覆盖图像的一个新区域并且没有重叠的话,速度会更快。受到此方法的启发,YOLO使用网格而不是滑动窗口。
在此示例中 我们使用 7x10 网格
如何从网格中获得正确的边界框?如何解决这些网格单元不太可能与对象边界框匹配这一问题?
原理是:
向每个单元格分配输出量,使每个单元格都具有相关的向量。这个向量首先告诉我们该单元格中是否有对象;其次对象的类别是什么;最后是对象的预测边界框。
假设有一个具有标签和边界框的输入图像,可以训练CNN为每个网格单元生成正确的输出向量。
对于第一个单元格,这个网格单元中没有对象 。因此Pc = 0, 类别得分为0,方框坐标具有一些值但意义不大,因为如果pc值太低我们将丢弃方框坐标。
在网格上训练
- 要训练每个单元格的网络输出,需要一个用于比较的正确标注向量。对于每个训练图像:需要将其划分为网格,并手动为每个单元格分配一个正确标注向量。
-
设计一个可以使用这些向量进行训练的CNN。在示例中是 7x10 网格,每个网格单元具有相关的八维正确标记向量。因此输出层大小应该为7x10x8。可以将其看成7x10 图像,深度为8。
对于每个输入网格单元,在CNN的输出层都有一个8维输出向量
生成边界框
当YOLO看到一个网格划分的图像时,如何查找正确的边界框?
诀窍在于它将图像中一个对象的真实边界框仅分配给训练图像中的一个网格单元,因此只有一个网格单元会定位图像。
对于每张图片:找到图像中每个对象的中点,然后将真实边界框分配给包含该中点的网格单元。
举例说明:
如何确定x,y,wh:
x 和 y 确定的是边界框相对于网格单元的中心坐标;w 和 h 确定的是边界框相对于整个图像的宽和高。
网格单元的左上角坐标是 (0,0),右下角的坐标是 (1,1)。因此 在这个示例中,相对于网格单元坐标系的中心点:X 约等于 0.5 y约 等于 0.3。
预测边界框的宽度 w 是 0.1,因为它的宽度大约是整个图像宽度的 10%;高度 h 是 0.4,因为它的高度大约是整个图像高度的 40%。
Note:所有边界框坐标值都在 0 和 1 之间,边界框的的宽度和高度可以大于网格大小。
存在的问题
基于网格的目标检测方法存在一个问题:训练过的CNN遇到新的测试图像时,通常会生成多个网格单元向量,这些向量都尝试检测相同的对象,这意味着有很多输出向量全都包含同一对象的稍微不同的边界框。
为了解决这一问题,使用一种叫做非极大值抑制的算法,它会尝试查找一个最能匹配图像中的边界框。
Intersection over Union(IOU)
交并比用于在非极大值抑制中比较给定对象的两个不同边界框的效果。
交并比:定义为交集的面积除以并集的面积。
由此可知,IoU将始终介于0与1之间。
Non-Maximal Suppression(NMS)
1.删除所有Pc值小于或等于某个阈值的边界框
2.选择Pc值最大的边界框作为最佳边界框,Pc值越大,对象检测的置信度越高。
3.删除与刚刚所选的这个最佳边界框相比IoU值很高的边界框,这样的话,就可以删除与最佳边界框极为相似的边界框。
** 高IoU一般指大于或等于0.5
如果有三个类别,则需要应用非极大值抑制三次。
Anchor Boxes
YOLO非常适合处理有多个对象并且不同对象都与一个网格单元相关联的情况:一个网格单元实际包含两个不同对象的中心点。
这时候,可以使用锚点框(Anchor Boxes)使一个网格单元检测多个对象。
在上图中,看到有一个人和一辆车重叠,还可以看出车辆和人的边界框中心都位于相同的网格单元中。因为每个网格单元输出向量只能有一个类别,因此它必须选择车辆或者行人。
但是定义锚点框之后,我们可以创建一个更长的网格单元向量,使每个网格单元都可以与多个类别相关联。这里,我们定义两个具有初始宽和高的锚点框。在实际操作中,可以定义多个锚点框。我们希望定义的锚点框能够涵盖我们想检测的各种对象形状。锚点框具有固定的宽高比,它会检测具有该宽高比并且可以完全融入的对象。
例如:检测很宽的骑车和站着的行人,我们将定义一个形状大致是汽车的锚点框然后定义另一个站立行人的锚点框。修改每个网格单元的输出向量,包含这两个锚点框。现在输出向量包含16个元素,前 8 个元素对应锚点框 1,后 8 个元素对应锚点框 2。因为汽车周围的边界框相对于锚点框 1 来说 IoU 更高,输出向量的锚点 1 元素将包含汽车的类别和方框参数;同样 因为行人周围的边界框相对于锚点框 2 来说IoU。 更高,锚点 2 元素将包含行人的参数。
但是和很多对象检测方法一样具有局限性:
1.假设有两个重叠的人,此算法将检查哪个人与锚点框 1 相匹配,哪个人与锚点框 2 相匹配。它只能将每种锚点框与一个对象相关联,如果两个重叠对象的形状大致一样,该算法效果就不太好。
2.同样 如果你只定义了两个锚点框 但是有三个重叠对象,那么此算法将失败 因为它只能识别其中两个对象。
但是这些情况很少见。
Anchor Boxes and Vehicle Detection
网友评论