拿车辆识别举例,首先我们把图片切割成很多正方型,为了保证不丢失信息,每个正方形都与上一个正方形有重叠.
然后把这些正方形分别用神经网络进行识别,留下那些识别到对象的正方形:
分类器有可能会有误报的情况,我们可以使用热力图查看哪些区域确信度最大:
用方框画出确信度最大的区域:
假设我们需要识别28x28x3的图片,我们需要分别以不同的尺寸对图片进行切割,假设以14x14进行切割可以切割出8x8张图片:
滑动窗口确实可以工作,但是它有个非常明显的缺点,滑窗需要切割出非常多的小图片,再加上需要以不同大小的窗口切割图片,所以我们需要非常多次数的分类.
我曾经用python实现的一个滑窗程序,识别一张图片近乎需要一分钟,它太慢了.之所以这么慢的原因是滑动窗口做的很多重复的计算,因为滑窗切割出的很多图片都有重叠的部分.
有什么办法能加快滑动窗口的速度呢?它是不是和卷积非常相似?卷积也是使用一个filter来滑动处理整张图片的,但是卷积缺非常快,因为卷积使用filter贡献了参数.实际将整张图片直接进行卷积与使用滑窗切割后的图片分别进行卷积得到的结果是一样的.
现在我们不对图片进行分割,而是设计一个输入尺寸与图片同样大小的神经网络:
使用卷积实现的滑窗虽然计算效率非常高,但是因为滑动窗口是依赖窗口的位置与大小确定对象的位置与边界的,所以有的时候滑动窗口有的时候会遇到无法准确确定对象边界的问题,比如说对象刚好在滑窗的边框上:
与其使用卷积滑窗来定位对象和确定对象的边界,为什么不直接训练神经网络直接输出对象的边界?我们可以这样设计神经网络的输出,使神经网络能够直接给出对象的位置及边框:
其中表示图片中是否有对象,,为对象的中心点,,为对象的宽和高相对图片宽高的比例,,,为对象的类别.
YOLO算法图像进行网格化分:
根据对象的中心,把对象分配到每个网格中,例如上图中将图片划分为3x3的网格,输出会是:
每个维度分别代表对应网格中是对象的数据.不难看出,这样就最多可以识别出网格数量个对象.
需要注意的是YOLO算法的输出,是对象的宽和高相对网格宽高的比例.
YOLO算法算法检测后,很有可能多个网格都识别到同一个对象,我们使用非极大值抑制去掉重复的识别结果.
非极大值抑制使用交并比来评估两个识别结果的重复程度:
可以看出交并比最大值为1,最小值为0,交并比越大说明两个识别结果重复的可能性越大.一般以0.5作为阀值,去掉交重复的识别结果.
另外交并比也可作为评估目标检测的方法.
上图中的人与车的中心几乎重叠,并且在一个网格中,目前每个网格只能识别一个对象,那么该如何解决这种情况呢?
目前的解决方案是定义几个Anchor Boxes,这里以两个为例:
参考:
https://www.coursera.org/learn/convolutional-neural-networks