神经网络可以通过输出图片上特征点的(x,y)坐标来实现对目标特征的识别。
假设你正在构建一个人脸识别应用,出于某种原因,你希望算法可以给出眼角的具体位置。眼角坐标为(x,y),你可以让神经网络的最后一层多输出两个数字lx和ly,作为眼角的坐标值。如果你想知道两只眼睛的四个眼角的具体位置,那么从左到右,依次用四个特征点来表示这四个眼角。对神经网络稍作一些修改,输出第一个特征点(l1x,l1y),第二个特征点(l2x,l2y)依此类推,这四个脸部特征的位置就可以通过神经网络输出。还可以通过嘴的坐标来确定嘴的形状从而判断人物是在微笑还是皱眉。我们以此来引申出如何通过卷积网络进行对象目标检测(基于滑动窗口的目标检测算法)。
假如你想构建一个汽车检测算法。首先创建一个标签训练集,也就是X和Y表示适当剪切的汽车图片样本。这张图片X是一个正样本,因为它是一辆汽车。由于我们对这个训练集的期望,你一开始可以使用适当剪切的图片,就是整张图片X几乎都被汽车占据,有了这个训练集,你就可以开始训练卷积网络了。输入这些剪切的图片然后卷积网络输出y,0或1表示图片中有无汽车。
训练完这个网络,就可以用它来实现滑动窗口目标检测。具体步骤如下,假设这是一张测试图。
首先选定一个特定大小的窗口,比如左边的红色窗口,将这个红色小方块输入卷积网络,卷积网络开始进行预测即判断红色方框内有没有汽车。接下来继续处理第二个图像即红色方框稍向右滑动之后的区域。
依次重复操作,直到这个窗口滑过图像的每一个角落。主要思路就是将这些滑过的窗口输入卷积网络,对每个位置按0或1进行分类,这就是所谓的图像滑动窗口操作。
再将这些滑动窗口放大,这样总有一个窗口可以检测到它,这个方法有明显的缺点,计算成本。为了降低成本,我们需要在卷积层上应用这个算法。首先要知道如何把神经网络的全连接层转化成卷积层。
假设对象检测算法输入一个14✖14✖3的图像,过滤器大小为5✖5,数量是16,图像映射为10✖10✖16,然后池化为5✖5✖16,添加两个连接400个单元的全连接层,最终通过softmax输出Y。
下面演示如何将全连接层转化为卷积层,画一个这样的卷积网络,我们将全连接层用5✖5的过滤器实现,数量是400,过滤器实际上是5✖5✖16,输出维度就是1✖1✖400,我们不再把它看作一个含有400个节点的集合,而是一个1✖1✖400的输出层,从数学角度看,它和全连接层是一样的。
我们再添加另外一个1✖1卷积层,假设有400个1✖1的过滤器,下一层的维度就是1✖1✖400,其实就是上个网络中的全连接层,最后经过1✖1过滤器的处理,得到一个softmax**值,通过卷积网络,我们最终得到1✖1✖4的输出层。
假设向滑动窗口卷积网络输入14✖14✖3的图片,形成这样一个网络。
测试集图片是16✖16✖3,在最初的滑动窗口算法中,你会将蓝色部分输入卷积网络,接着滑动窗口步幅为2个像素,依次重复得到输出。这个过程中我们会有很多重复运算。
使用相同的5✖5✖16过滤器进行卷积,然后池化,照旧用400个5✖5的过滤器得到2✖2✖400的输出层,现在输出层为2✖2✖400,而不是1✖1✖400,应用1✖1过滤器得到另一个2✖2✖400的输出,再接一个全连接最终得到2✖2✖4的输出。最终再输出层这4个方块中,蓝色的是图像左上方14✖14的输出。
我们不需要把输入图片分割成4个子集分别执行前向传播,而是把它们作为一张图片输入给卷积网络进行计算,这提高了运算效率,不过仍存在一个缺点就是边界框的位置不够准确。