一、目标定位
这一小节视频主要介绍了我们在实现目标定位时标签该如何定义。
上图左下角给出了损失函数的计算公式(这里使用的是平方差)
如图示,加入我们需要定位出图像中是否有pedestrian,car,motorcycles。注意在这里我们假设图像中只肯呢个存在这三者中的一种或者都不存在,所以共有四种可能。
- \(P_c=1\)表示有三者中的一种
- \(C_1=1\)表示有pedestrian,反之没有
- \(C_2=1\)表示有car
- \(C_3=1\)表示有motorcycles
- \(b_*\)用于标识所识别食物的位置
- \(b_x,b_y\):表示识别物体的中心坐标
- \(b_w,b_h\):表示识别物体的宽和高
注意:\(P_c=0\)表示三者都没有,所以此时\(C_*,b_*\)的值我们并不在乎了。
二、特征点检测
这一节的内容和上一节感觉很类似,所有就没有记得很详细了
三、目标检测
目标检测常使用的是滑动窗口技术检测,即使用一定大小的窗口按照指定的步长对图像进行遍历
因为图像中车辆的大小我们是不知道的,所以可以更改窗口大小,从而识别并定位出车辆的位置。
四、卷积的滑动窗口实现
注意:该节视频的例子和上一节一样,都是识别图像中是否有pedestrian,car,motorcycles,background,所以最后输出y是4个节点
1.全连接层→卷积层
在介绍卷积滑动窗口之前我们首先要知道如何把神经网络的全连接层转化成卷积层,下面是使用了全连接层的网络结构
那么如何将全连接层转化成卷积层呢?如下图示
我们可以看到经过Max Pooling之后的数据大小是(5, 5, 16),第一个FC层是400个节点。我们可以使用400个5*5的过滤器进行卷积运算,随后我们就得到了(1, 1, 400)的矩阵。
第二个FC层也是400个节点,由之前的1*1过滤器的特点,我们可以使用400个1*1的过滤器,也可以得到(1,1,400)的矩阵。至此,我们已经成功将全连接层转化成了卷积层。
2.卷积滑动窗口实现
目标检测一节中介绍了滑动窗口。要实现窗口遍历,那么就需要很大的计算量,看起来似乎可操作性不强。But!这怎么可能难倒哪些newB的大神们呢,他们自然有办法。
首先我们先看下图,这个就是上面提到的将全连接层转化成卷积层的示意图,只不过画的看起来更正规一些了2333,但是有个需要提醒的是吴大大为了方便只花了平面图,就没有画出3D的效果了。
下面,假设我们的测试图大小是16*16,并令滑动窗口大小是14*14的(为了方便理解,下图用蓝色清楚地表明了14*14窗口的大小),步长是2,所以这个测试图可以被窗口划分成4个部分。随后和上面执行一样的操作,最后可以得到(2,2,4)的矩阵,此时我们不难看出测试图被滑动窗口选取的左上角部分对应的结果也是输出矩阵的左上角部分,其他3个部分同理。
所以这说明了什么?
说明我们没有必要用滑动窗口截取一部分,然后带入卷积网络运算。相反我们可以整体进行运算,这样速度就快很多了。
下图很清楚的展示了卷积滑动窗口的实现。我们可以看到图片被划分成了64块
五、Bounding Box预测
上面介绍的滑动窗口方法存在一个问题就是很多情况下滑动窗口并不能很好的切割出车体,如下图示:
为了解决这个问题,就有了YOLO(you only look once)算法,即只需要计算一次便可确定需要识别物体的位置的大小。
原理如下:
首先将图像划分成3*3(即9份),每一份最后由一个向量表示,这个向量在本文最前面介绍过,即\(y=[P_c,b_x,b_y,b_h,b_w,c_1,c_2,c_3]\)
因为有9份,所以最后输出矩阵大小是(3,3,8),如下图示:
那么如何构建卷积网络呢?
输入矩阵是(100,100,3),然后是Conv,Maxpool层,……,最后只要确保输出矩阵大小是(3,3,8)即可。
下图是以右边的车辆作为示例介绍该车辆所在框的输出矩阵
- 很显然\(P_c=1\),
- 然后\(b_x,b_y\)的值是右边车辆的中心点相对于该框的位置,所以它们的值是一定小于1的,我们可以很容易的得到近似值\(b_x=0.4,b_y=0.3\)。
- \(b_h,b_w\)的值同理也是车辆的宽高相对于其所在框的比例,但是要注意的是这两个值是可以大于1的,因为有可能部分车身在框外。但是也可以使用sigmoid函数将值控制在1以内。
六、交并比(Intersection over Union, IoU)
前面说到了实现目标定位时可能存在滑动窗口与真实边框存在出入,如下图示:
红色框是车身边界,紫色框是滑动窗口,那么此窗口返回的值是有车还是无车呢?
为了解决上面的问题引入了交并比(IoU),也就是两个框之间的交集与并集之比,依据这个值可以评价定位算法是否精准。
示意图如下,黄色区域表示紫色框和红色框的交集,绿色区域表示紫色框和红色框的并集,交并比(IoU)就等于黄色区域大小比上绿色区域大小。
如果\(IoU\geq0.5\),则表示紫色框中有车辆,反之没有。
当然0.5这个阈值是人为设定的,没有深入的科学探究,所以如果希望结果更加精确,也可以用0.6或0.7设为阈值,但是不建议用小于0.5的阈值。
七、非极大值抑制
1.算法大致思路
前面Bounding Box一节中介绍到将图片划分成若干等分,例如3*3,那么一共就有9块,如下图示,我们可以很清楚的看到第二行第一块和第三块都有车,所以可以标出一个中心点坐标(\(b_x,b_y\)),这样我们就能通过最终的输出结果知道这两个框中有车。
但是如果我们划分的数量变多之后呢?如下图示划分成了19*19,图中标出的3个黄框和3个绿框最终结果都会都会返回[\(P_x=1,b_x=,b_y=……\)],但是最后我们该信谁的呢?是这三个框真的有车,而且还不是同一辆车?还是只是同一辆车?所以就有了非极大值抑制来解决这个问题。
其思路大致如下(为了方便说明和理解,我们不使用19*19的方框):
首先每个框会对是否有目标返回一个\(P_c\)的概率值(也可以是\(P_c*C_1*C_2*C_3\)的概率之积),如下图示:
然后找到\(P_c\)最大的一个框,显然0.9的框有车的概率最大,所以该边框颜色高亮
然后算法遍历其他边框,找出与上一个边框的交并比大于0.5的边框,很显然右边的剩余两个边框符合条件,所以这两个边框变暗
左边的车同理,不加赘述
下面结合一个例子总结一下非极大值抑制算法的实现步骤:
注:在这里假设只需要识别定位车辆即可,所以输出格式为[\(P_c,b_x,b_y,b_h,b_w\)]
这个例子中将图像划分成19*19方格,假设每个方格都已经计算出\(P_c\)的概率值
1.去掉所有满足\(P_c\leq0.6\)的方格 (0.6也可以进行人为修改)
2.对剩下的方格进行如下循环操作:
- 从剩下的方格中选取\(P_c\)最大的一个作为预测值输出,假设这个方格为A
- 将与A方格交并比大于0.5的剔除
八、Anchor Boxes
前面介绍了那么多,都只是识别单个物体,如果要同时识别多个物体该怎么办呢?而且识别的不同物体的中心点在同一个框中又该怎么呢(如下图示,人和车的中心都在红点位置,处于同一个框中)?这时就需要使用Anchor Boxes了。
Anchor Boxes的思路是对于不同的物体事先采用不同的框,例如人相对于车属于瘦高的,所以使用下图中的Anchor Box 1,相反车辆就使用Anchor Box 2.
之前的输出值的格式都是\(y=[P_x,b_x,b_y,b_h,b_w,C_1,C_2,C_3]\),最后输出的矩阵大小(以该图为例)是(3,3,8),但是这样只能确定一个物体。
所以为了同时检测不同物体,很自然的我们可以重复输出这个上面的值即可,即\(y=[P_x,b_x,b_y,b_h,b_w,C_1,C_2,C_3,P_x,b_x,b_y,b_h,b_w,C_1,C_2,C_3]\),所以输出矩阵是(3,3,16),也可以是(3,3,2,8)。
要注意的是我们需要提前设定好输出值前面的值对应Anchor Box 1,后面的对应Anchor Box 2.
例如我们得到了图中人的边框信息值,然后经过计算发现其边框与Anchor Box 1更为接近,所以最后将人的边框信息对应在前面,同理车辆边框信息对应在后面。
总结起来Anchor Box算法和之前的算法区别如下:
- 之前的算法:
对于训练集图像中的每个对象,都根据那个对象的中点位置分配到对应的格子中,所以在上面的示例中输出y就是(3,3,8)
- Anchor Boxes算法
现在每个对象都和之前一样分配到同一个格子中,即对象中心所在的格子。不同的是也需要分配到和对象形状交并比最高的Anchor Box.
例如下图中的红色框不仅要分配到其中心所在的图像上的格子中,而且还需要分配到与其交并比最大的Anchor Box中,即竖条的紫色方格
回到本小节最开始的例子,最后的输出值如下图示:
图中人的对应Anchor Box 1, 输出值对应图中的黄色字体;车辆同理,对应绿色字体