目录
1.滑动窗口算法
2.滑动窗口的卷积实现
(1)1*1卷积的作用
(2)全连接层转化为卷积层
(3)在卷积层上实现滑动窗口
3.Bounding Box预测(YOLO算法)
1.滑动窗口算法
假如要构建一个汽车检测算法,首先创建一个标签训练集,也就是适当剪切的汽车图片样本,编号1是一个正样本,因为它是一辆汽车图片,编号2、3也有汽车,但编号4、5没有汽车。一开始我们可以使用适当剪切的图片,就是整张图片几乎都被汽车占据,有了这个标签训练集,就可以开始训练卷积网络了,输入这些适当剪切过的图片(编号6),卷积网络输出:0或1表示图片中有汽车或没有汽车。训练完这个卷积网络,就可以用它来实现滑动窗口目标检测,具体步骤如下:
假设下图是一张测试图片,首先选定一个特定大小的窗口,将这个红色小方块输入卷积神经网络,卷积网络开始进行预测,即判断红色方框内有没有汽车。
滑动窗口目标检测算法接下来会继续处理第二个图像,即红色方框稍向右滑动之后的区域(每次都固定步幅),并输入给卷积网络,因此输入给卷积网络的只有红色方框内的区域,再次运行卷积网络,然后处理第三个图像,依次重复操作,直到这个窗口滑过图像的每一个角落。
然后选择比上次大的红色方框,进行滑动窗口算法,遍历整张图片。第三次可以选择更大的方框,这样做的目的是:不论汽车在图片的什么位置,总有一个窗口可以检测到它。
但是这种算法也有明显的缺点:因为方框会将图片切割成多张小图片多次进行检测,所以引来巨大的计算成本。假如选择小步幅移动,就会增加计算成本;如果选择大步幅,就会减少切割的数量,从而影响检测性能(有汽车却因为切割部分的图片含有较少汽车部分,从而检测失败)。
2.滑动窗口的卷积实现
(1)1*1卷积的作用
1*1卷积听起来好像是为图片的每一个位置乘以一个数字,似乎没啥作用,但是如果在有对通道数改变的需求的场景,就会产生非凡的意义。
如上图所示,输入是6*6*32的维度,选择通道数相同的1*1卷积核,得到的结果是6*6*过滤器数量的输出。把1*1卷积核理解为权重,这就表示输入的图片依次与每个1*1卷积核做运算,这不就是全连接层吗。
所以1×1卷积可以从根本上理解为对这32个不同的位置都应用一个全连接层,全连接层的作用是输入32个数字(过滤器数量标记为,在这36个单元上重复此过程),输出结果是6*6*过滤器数量,以便在输入层上实施一个非平凡(non-trivial)计算。
那么,我们就可以应用1*1卷积核,来改造我们的网络,实现特殊的目的。
(2)全连接层转化为卷积层
如何把这些全连接层转化为卷积层?假设在上图第一行这样的卷积网络中,我们希望网络的输出为:汽车、行人、摩托车和背景等四类,那么softmax层就有4个单元分别输出4类的概率。
找到全连接层和前一层,用5*5的过滤器来实现卷积层的转化,数量是400个(编号1所示),输入图像大小为5*5*16,用5*5的过滤器对它进行卷积操作,过滤器实际上是5*5*16,因为在卷积过程中,过滤器会遍历这16个通道,所以这两处的通道数量必须保持一致,输出结果为1*1。假设应用400个这样的5*5*16过滤器,输出维度就是1*1*400,我们不再把它看作一个含有400个节点的集合,而是一个1*1*400的输出层。从数学角度看,它和全连接层的效果是一样的,因为这400个节点中每个节点都有一个5*5*16维度的过滤器,所以每个值都是上一层这些5*5*16激活值经过某个任意线性函数的输出结果(也就是全连接层中的线性组合)。
再添加另外一个卷积层(编号2所示),这里用的是1*1卷积,假设也有400个1*1的过滤器,在这400个过滤器的作用下,下一层的维度是1*1*400,这其实就是上个网络中的这一全连接层(400个神经元)。最后经4个1*1过滤器的处理,得到一个softmax激活值,通过卷积网络,我们最终得到这个1*1*4的输出层,而不是这4个数字(编号3所示)。
可以发现,我们在图片上实施一次预测,就会输出1*1*4的结果,这实际上是4个分类的概率,那么如果我们用一张更大的图片,运用滑动窗口算法(用一定大小的窗口分割图片),也实施一次预测,是否会得到多个预测结果?这样岂不是可以减少滑动窗口的运算量。答案是肯定的。
(3)在卷积层上实现滑动窗口
上图所示的是简化的网络结构,并不是3D版本的。现在有一张16*16*3的图片需要预测,它比输入给卷积网络的14*14*3的图片大。在传统的卷积网络运用滑动窗口算法,需要将图片用14*14的框进行分割,选择步长为2,分割为4张图片,因此需要运行4次网络(即4次向前传播过程)才可以得到4个预测结果。结果发现这其中有很多重复计算可以共享(比如第一次卷积过程中相同参数的卷积核在同一个区域工作了4次),因此我们可以直接输入一张16*16的图片。这样网络的计算就变为了上图第二行的过程,经过5*5*16的卷积核后,选择步长为1,输出变为12*12*16;再经过最大池化,选择2*2的过滤器,结果变为了6*6*16;此时改造后的全连接层用5*5*16的400个卷积核,得到2*2*400的结果;再经过1*1*400的400个卷积核,输出也是2*2*400;最后经过由1*1*400的4个卷积核改造的softmax层,得到2*2*4的结果。
这个结果可以解释为:左上角的部分(红色圈)是选择14*14方框进行滑动窗口的第一次分割的图片的预测结果,绿色箭头是第二次分割预测结果,黄色箭头是第三次分割预测结果,紫色箭头是第四次分割预测结果。
所以该卷积操作的原理是我们不需要把输入图像分割成四个子集,分别执行前向传播,而是把它们作为一张图片输入给卷积网络进行计算,其中的公共区域可以共享很多计算。
卷积层上的滑动窗口算法,提高了整个算法的效率。不过这种算法仍然存在缺点,比如边界框的位置可能不够准确,可能分割的时候无法完整的圈住对象。
3.Bounding Box预测(YOLO算法)
如下图所示,我们选择蓝色方框进行滑动窗口算法,可以发现蓝色的框始终没有完整的圈住汽车,合理的方框位置应该是红色的方框,滑动窗口算法似乎很难圈到,不能完整的圈到汽车,我们就难以训练网络给出汽车的位置。这就引出了YOLO算法:You Only Look Once(你只看一次)。这是由Joseph Redmon,Santosh Divvala,Ross Girshick和Ali Farhadi提出的算法。
从算法的名字可以看出,我们对于包含对象的方框只圈一次,当然肯定是要尽可能完整的圈住对象。算法的实施具体如下:
简单起见,可以将图片分为3*3的方阵(实际可以分割的更多),为每个方阵编号1—9。假设有汽车、行人、摩托车和背景四类对象,我们需要识别出背景外的对象,也就是汽车、摩托车和行人,因此需要在3*3的方阵中为对象找到他们所属的图片(一个对象只属于一个分割区域),比如黑色轿车应该属于4号图片,面包车应该属于6号图片,而实际上两车在5号图片也存在少量区域,但是YOLO算法要求我们只找对象的中点,将对象分配给包含中点的方格。因此从算法角度来说,5号不包含任何对象。
深度学习基础—目标定位与特征点检测https://blog.csdn.net/sniper_fandc/article/details/142707197?fromshare=blogdetail&sharetype=blogdetail&sharerId=142707197&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link 在《深度学习基础—目标定位与特征点检测》这篇博客中提到,对于目标定位问题,我们需要定义标签:
于是9个区域都有属于自己的标签向量,规定c1为行人类别,c2为汽车类别,c3为摩托车类别,比如:1号区域不包含对象,因此pc=0,那么其他数值就无意义了:
6号区域包含汽车对象,因此pc=1,c2=1,其余位置坐标根据对象的位置进行编码:
方框的位置的编码方式应根据小方格的比例进行编码比较合理(还有其他的方式也比较ok),假设把6号区域的左上角定为(0,0),右下角定为(1,1),则面包车的中点(黄点)的坐标大致在(0.4,0.3)的位置,而能包围面包车对象的方框的宽和高大概是6号区域宽和高的0.9和0.5倍,于是就可以进行如下的标签定义。
需要注意:在按照方格比例编码方式的对象的中点坐标范围是[0,1],因为如果不在这个区间,就说明对象不在这个方格内,那就不应该把对象分配给这个方格。而宽和高的范围应该是非负数,因为红色框的宽和高可以比区域大。
如果存在多个对象中点在一个区域内,可以进行更细致的划分,确保一个区域尽量只包含一个对象的中点。
对于这种区域划分的方式,网络的输出应该是3*3*8,3*3表示9个区域的输出,8表示每个区域会输出一个长度为8的向量,根据这个输出向量实施优化算法,训练出网络进行预测。
由于算法的卷积实现,不用跑9次算法,只需要在完整的图片运行一次算法,就可以得到输出,所以这个算法效率很高,同时卷积的效率可以保证实时识别。YOLO算法有很多改进,我们后续再来探讨。