4.3 目标检测
目标定位
图片分类已经很熟悉了,判断输入的图片是否是一只猫。目标检测还涉及到一个定位的事,它需要检测到图片中汽车的位置并标一个方框出来。目前现研究分类定位问题,通常只有一个较大的对象位于图片中间的位置,我们需要对它进行识别和定位。而在对象检测问题中,图片可以包含多个对象。图片分类→分类定位→目标检测 难度加大,层层递进关系。
对于图片分类我们是将图片输入到神经网络,然后在最后的softmax层进行分类输出,如果想定位,其实就是让softmax再多输出四个数字,这四个参数可以表示一个bouding box边界框。然后用有监督学习法,学习这个边界框的位置。
下面约定本章内容的符号:图片的左上角标记为(0,0),右下角标记为(1,1),边界框的中心点为(bx,by),高度为bh宽度为bw。
目标标签Y的定义如下,它是一个向量,第一个元素Pc表示该图中是否含有我们需要的元素,例如行人汽车或摩托车,只要包含其中之一则Pc=1。然后是四个边界框参数bx,by,bh,bw。然后是具体哪一个对象c1,c2,c3,例如如果是汽车那么c2=1,此时必有Pc=1。另外,一旦Pc=0,其他参数都变得毫无意义。最后,损失函数等于Y中每个元素相应差值的平方和。注意,如果Pc=1,那么损失函数中就有所有的Y共8个元素,如果Pc=0,那么损失函数中就只有y1一个元素,也就是说只训练y1就可以了,其他不用考虑。
图中标红的部分,说的啥我没看懂。
特征点检测
假如你正在构建一个人脸识别系统,你希望算法可以给出人眼角的具体位置,那么就可以在网络的输出层多输出两个数字lx和ly作为眼角的坐标值(两只眼睛的四个眼角以此类推即可)。加入你在脸部加入了许多的特征点,那么你就可以提取各个器官的位置、轮廓甚至是判断表情。这个时候你就可以完成例如美颜、加一个眼镜帽子之类的事。
目标检测 (滑动窗口)
假如你想构建一个汽车检测算法,首先你得创建一个带标签的训练集。一开始你可以使用适当剪切过的图片,也就是这张图片被一辆汽车几乎占据,然后就可以开始训练这个网络,训练完成后就可以用它来实现滑动窗口目标检测。
具体如下,首先选定一个特定大小的窗口,例如图片下面那个红方框,每一次只将方框大小的图片输入进卷积网络判断是否有汽车,然后以固定的步幅遍历整个图片,再将所有结果按有无汽车进行分类。完成后再将窗口不断扩大,继续遍历,如此一来,不管汽车在图片的哪个角落都会被检测到。
但这种方法的缺点也很明显,就是计算成本过高。
卷积的滑动窗口
构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转化成卷积层。
首先如图第一行所示一个卷积网络的最后几层是全连接层,要将其转化成卷积层,只需在第一个全连接层的位置添加一个5x5x16的过滤器,这样的过滤器共有400个,如此输出的就是1x1x400。后面两层也是同理处理,这实际上等同于全连接层的计算。
如图第一行所示(这一页的图没有画出信道的厚度来),是一个正常的卷积,也是我们规定的14x14窗口大小。在计算第二行的比这个窗口稍大一些的图片时,假设以2为步长,那么这个16x16的图片就需要分为四个部分进行滑动窗口卷积,也就是需要进行四次前向传播,但是我们发现这四个窗口的重合部分非常多,那么就会进行大量的重复计算。那么我们就不进行四次前向传播,前三步都按照正常的卷积运算处理,注意到全连接层的地方,还是用和第一行一样的5x5过滤器,这样的话就会是2x2的输出。这个输出的四个角分别代表原先四次窗口分别计算的预测结果。这就相当于整张图片尽量不要重复计算,在前面几层只算一次,将各种特征提取出来,共享这个结果。只在最后做预测的几个全连接层再划分窗口。
Bounding box 预测
前面讲过的方法因为步长过大或者窗口选择(窗口过大或过小,甚至很多时候汽车的边界框不是方的)的问题,极有可能无法完美匹配图片中的目标。一个更精准的方法是YOLO(you only look once你只看一次)算法,基本思路是将输入图片分成网格,然后在每个格子上用分类定位算法。上图中将图片分成9个格子,那么9个格子各有一个8维向量,内容是第一节目标定为里讲过的那样判断是否有对象并输出格子中对象的边界框。这张大图中很明显有两辆汽车,YOLO算法的做法是将对象分配到它的中点所在的格子上,所以这时即使这9个格子中最中间的那个包含两辆车的一部分但也假装他什么也没有。 所以这里总共有9个格子,每个格子输出一个8维向量,这个图的总输出就是3x3x8。最后用上面介绍过的卷积的方法,前半个网络共享一部分运算,最终输出一个3x3x8的结果。
这个方法我有很多疑惑,在一个小格子上没有整个的汽车能确定中心点和边界框吗?如果格子分的很细那一个格子可能只是汽车很小的一部分啊,上面的方法介绍的是每个格子都进行一次分类定位算法。 另外,难道不是先进行每个格子的识别才能确定中心点吗,以上方法是先有中心点再确定中心点落在哪个格子里,到底是怎么回事? 最后,吴恩达说有关YOLO 的论文十分难懂,他自己也没看懂,所以如果要看论文,看不懂不要慌。
交并比IoU(Intersection over union)
计算真实边界框和你预测的边界框的交集和并集之比,用来判断我们的结果的优良情况。一般结果大于等于0.5我们就认为结果是可以接收的(这只是一个人为定义的阈值,你可以定义自己的标准)。
非极大值抑制
和我上面所担心的一样,这个算法由于要分许多许多个格子,每个格子进行单独检测,那么同一辆汽车会被很多格子检测到并声称我这里有一辆汽车。所以就对比它们Pc值的概率,将图中最大概率(图中为0.9)预测的边界框保留,然后将和这个格子IoU很大的其他格子抑制掉(这一步是为了一个汽车只预测一次,但也不能把其他位置的汽车抑制),然后再选取图中剩下的所有格子中最大的(0.8),再重复步骤,这样就成功预测出了两辆汽车,并清除了重复的预测。
Anchor box
如果出现一个格子中包含两个对象,就需要使用到该方法。这时需要手动设置两个anchor box,一个纵向的一个横向的,然后将Y输出从8维变成16维,前8维对应纵向的ancor box检测人,后8维输出对应横向的anchor box检测汽车,这样各干各的。(翻译问题比较大,没太看明白,这个理解可能有较大出入,如果需要再重学)
这个anchor box的理解完全错误
YOLO
综合以上