YOLO算法,迟到N年的毕业设计

题图:Facebook Detectron本科时候我们专业叫信息工程,但是让我比较困惑的是:我们专业到底是干嘛的?最近研究深度学习。然后猛然发现,深度学习里的很多问题,比如语音识别,图像处理,视频分析,这些就是本科专业老师们研究的课题啊。哦,原来本科学的竟然是人工智能啊!这种感觉很像突然发现原来网吧就是共享经济。开个玩笑。记得毕业设计选题的时候,我兴冲冲的跑到老师的办公室。然后老师问我,你想选简单些的题目还是要有挑战的题目呢?我愣了一下,心想自己不能认怂,于是说,我要选有挑战的。然后老师就从厚厚的文件夹里抽出一本,上面赫然写着几个大字『视频对象提取』。后来我才明白,对象这个词是英文object直译过来的,其实译作物体应该更合适。题目的意思就是检测,提取视频里的物体。比如说一段猫的视频,人看了之后很容易就能识别视频里的是只猫。但是让计算机识别视频里是一只猫就是一件非常困难的事情。我拿着题目回去查资料,发现类似的题目有一堆硕士,博士都在做,并且没有什么好的结果!接下来我夜以继日的奋战,终于攻克了世界级的难题。这是小说里的情节。事实上我没有作出什么成果,老师也让我毕业了。当然,这个问题其实在深度学习出现之前都没有太好的解法。但是想不到若干年之后,我竟然再次遇到了当年毕设的问题,并学会了解法。物体检测(object detection)

物体的检测和识别一直都是计算机视觉、图像和视频处理领域的热门问题。有了快速、准确的物体检测算法,自动驾驶汽车就可以不依赖复杂、昂贵的传感器和激光雷达也能实时监测周围的车辆,行人,路标等等,从而达到安全的驾驶。最近几年,深度学习的出现给这一领域带来飞速的发展。这篇文章我们就介绍一种效率极高的物体检测算法:YOLO算法。在这之前,我们先要理解卷积神经网络,因为它是YOLO算法和其它几乎所有图像处理的深度学习算法的基础。

卷积神经网络(Convolutional Neural Network)

在前文秒懂深度学习中,我们已经了解了最基本的深度神经网络是什么样子的。卷积神经网络(CNN)是神经网络的一个变种。在基本的深度神经网络里,每一层跟下一层的连接都是全连接(Fully-Connected),也就是说每一层的每一个节点都要跟下一层的每一个节点相连。对于节点数少的问题这样做还能行得通。但是试想一下一张像素是2000*2000的图片,那么输入层的节点个数就是2000 * 2000 * 3,一千二百万。这个时候如果下一层来个规模相当的节点数,那全连接之后的参数个数就是天文数字。不仅没法训练,而且非常容易过拟合。这个时候卷积操作就登场了。卷积层与其说是全连接层的一种变种,不如说是一种优化。卷积的思想是:1. 每一个神经元学习的是一个特征,图像的单个特征并不需要看整张图片获得。2. 同样的特征会在图片的不同的区域出现,所以不同区域出现的类似特征可以共享参数。这样就大大减少了参数的数量。AlphaGo使用就是CNN或者它的变种。原因就是如果把围棋的每一个状态看做一副图的话,每个局部的布局特征并不需要通过全局来了解。而且类似的布局可以发生在棋盘的不同地方。所以可以使用卷积神经网络。卷积运算的操作过程就是用过滤器(filter)作为神经元,然后用它『扫描』整个图片。如下图所示:

这里的输入是一个5 * 5的矩阵,过滤器是3 * 3的矩阵,过滤器在扫描输入的过程中与重叠部分内积(相乘然后所有乘积相加),得到的结果放到输出层,这样就完成了卷积运算。这样一个过滤器所需要的参数个数就是过滤器的大小3 * 3 = 9,无论输入多大都不变。至于每一层需要多少过滤器这就是模型的超参(hyperparameter)了,需要调试。跟基本的深度神经网络相比,卷积神经网络最不同也最难理解的也就是这一部分了。了解了卷积运算,我们再来看整个卷积神经网络的结构。在一个卷积神经网络模型里的每一层有三种可能,分别是:卷积层(Convolutional Layer)池化层(Pooling Layer)全连接层(Fully-Connected Layer)

这里面全连接层我们已经了解了。池化层比较简单,它就是对输入进行抽样,让输入的规模变小。

以上就是一次最大池化(max pooling),将每个2 * 2的区域里的最大值提取出来就是输出。还有一种平均池化(average pooling)是取这些值的平均值。卷积层由N个过滤器组成,输出为每个过滤器跟输入层卷积的结果叠加起来。每次卷积运算的结果为一层,所以输出为N层,卷积之后的结果作为激励函数的输入,这是日常操作。最后,一个典型的卷积神经网络的结构就是把各种层叠加起来。往往都是先有若干个卷积层,池化层的循环,最后当参数规模比较小的时候用全连接层。

如何识别一只猫?

了解了卷积神经网络之后,我们看一个最经典的问题:如何识别一只猫。为什么总是猫呢?俺也不知道。

在定义好了卷积神经网络结构之后,我们需要的就是训练数据。这些图片被标注为是猫,或者不是猫。然后跟一般的神经网络的训练过程一样,通过正向传播,损失函数,反向传播,反复循环后得到模型的参数。然后训练出来的模型就可以用来判断一张图片是不是猫了。边缘检测能够识别是不是猫是第一步。人眼在看到图片的时候,不仅能够很快识别图片上的物体,还能知道物体在图片上的位置。相应的,物体检测除了检测有没有物体,是什么物体之外,还要能够定位物体的位置。下面我们就探讨一下如何能够对物体进行定位。

暴力破解

如果我们知道怎么去识别一个物体,那么怎样能够在一幅图里定位这个物体呢?暴力破解往往是打开思路的好办法。一个比较容易想到的方法就是:找到图像里的部分区域,一点一点的试。具体过程是:先设定一个固定大小的区域,从左上角开始,从图片里取出这个区域的子图片,然后检测这个子图片里面是不是我们要找的物体。然后滑动这个区域,从左到右,从上到下扫过整个图片,对每一个子图片进行检测。如果还没有找到或者不够精确,可以再调整区域的大小,然后重复扫描过程。显然,这个过程的计算量是巨大的。一种优化方案是把一个固定面积下的整个扫描过程放到一个卷积运算里,这样能够提高一些效率,但是还是免不了要调整面积并重复计算。还有一种算法是R-CNN,思路是先做一个筛选,把那些物体有可能的存在的区域选出来,然后在这些区域里做物体检测。这里就不赘述了。YOLO算法最后,我们来介绍YOLO算法。YOLO的全称是You Only Look Once,是由华盛顿大学的Joseph等人于2014年提出的。它的特点就一个字:快!前面我们提到的算法都要对图像或者图像的部分区域重复计算很多遍,但是YOLO的思想是:一步到位。首先YOLO算法的模型r仍然是基于卷积神经网络。为了同时实现物体的识别和定位,YOLO算法将图片分割为S*S的小格子,然后每个格子要同时预测5个值:(x, y, w, h, p)。(x, y)是物体中心的位置,w是宽度,h是高度,p是识别为某一物体的概率。有了中心,宽度和高度,就有了定位,加上物体识别的概率,就同时完成了识别和定位。不同的格子预测到的区域可能会有重叠,这个时候首先去掉p值在一定阈值以下的。然后对于每一个预测的物体类型,找出概率最高的预测区域,然后将周围重叠的区域去掉,剩下的就是图片里的所有的物体和它们的预测区域了。YOLO算法的第一个版本检测速度达到了45帧/秒,完全可以满足实时检测的要求。后来的改进版将速度提高到67帧/秒,并且准确率更高。下面来欣赏一段YOLO v2的demo视频。

最后,现在感觉自己可以安心的说我大学毕业了。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180304G0MMU300?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券