1、计算机视觉
1.1什么是计算机视觉
计算机视觉是一门研究如何使机器“看”的科学。更进一步说,就是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等视觉动作,并进一步做图像处理,使计算机处理后的图像更适合人眼观察或仪器检测。
作为一个科学学科,计算机视觉研究相关的理论和技术,试图建立能够从图像或者多维数据中获取“信息”的人工智能系统
1.2计算机视觉的应用
计算机视觉现在已经被应用于多种领域中,是人工智能目前最火的领域之一
> 无人驾驶
> 无人安防
> 人脸识别
> 文字识别
> 车牌识别
> 以图搜图
> VR/AR
> 3D重构
> 医学图像分析
> 无人机
> 其它
1.3图像和视频
> 图像
一张图片包含了:维数、高度、宽度、深度、通道数、颜色格式、数据首地址、结束地址、数据量等等
> 视频
原始视频=图片序列,视频中的每张有序图片称为“帧(frame)”。压缩后的视频会采取各种算法减少数据的容量
> 具体解释
图像的深度指的是存储每一个像素所用到的位数,当每个像素存储所需要的容量越大的话,则深度越深,颜色越丰富
图像使用的压缩格式以及编码决定了图像的大小
灰度图单通道、RGB是四通道、16位图两通道等等
对视频分析时,先要了解视频的结构和特点。如果码率和帧率很低,很多算法是不work的
IPB,一种视频压缩算法,即压缩后只存三种帧,I帧(关键帧,图片的完整保留,最重要)、P帧(这一帧与上一关键帧之间的差别)、B帧(双向差别帧,与上一个关键帧的差别和于下一帧的差别)
现在更多不是用硬盘读取了,而是用网络存储,所以现在都是用网络摄像头了
码率:单位时间的数据传输数;也就是采样率,单位时间的采样个数
帧率:每秒多少帧
分辨率:图像质量
1.4 计算机视觉与其它学科的关系
> 计算机视觉、机器视觉和图像处理的区别
> 三者都涉及了图像的处理
> 计算机视觉偏软件处理,一般和应用场景相关
> 机器视觉更多涉及硬件的结合,包括机器人、工业级的摄像机、工业检测
> 图像处理更多是对图进行转换、变形
2、硬件环境与软件环境
2.1 CPU versus GPU
> 性能(低延时性)、吞吐量:CPU是低延时性,低吞吐量;GPU是高吞吐量,高延时性
> GPU的Cache小,其是通过高并发多线程的方式来搞吞吐的处理简单计算,所以用来处理图片十分方便。因为处理图片是将图片分成很多小块,然后分别对每一块进行处理
> 由于计算机视觉涉及大量的矩阵运算,所以使用GPU,通过它高并发的特点能大大的提高运行速度
2.2 Open Source Frameworks
2.2.1计算机视觉开源算法库
> OpenCV
OpenCV作为计算机视觉的一个开源软件库已经存在了很多年了,其轻量且高效,是由一系列的C函数和少量C++类构成。OpenCV提供了Python、Ruby、MatLab等语言的接口,实现了图像处理以及计算机视觉方面的许多通用算法。
2.2.2深度学习开源框架
> TensorFlow (Google)
> PyTorch (Facebook)
> Caffe2 (Facebook)
> CNTK (Microsoft)
> MXNet (Amazon)
> Paddle (Baidu)
……
1)现状分析
计算机视觉领域的很多应用都是基于深度学习算法的,应该说深度学习算法在准确性方向已经全面超过了以前的经典机器学习算法,所以要想对CV有深度的理解,了解目前这些主流的深度学习开源框架就十分有必要了。
上边列举的是目前热度比较高的深度学习框架,而且在每个开源框架后边的括号中,我标示出了目前该框架主要是由哪些公司在负责运营。可以看出,每款框架其实都有着大厂在后边支撑着的。这第一保证了开源社区的活跃性,其次也确保了这些框架都是在实际业务场景中被使用着的。
下边我将对其中两款框架进行简单的介绍
2)TensorFlow介绍
TensorFlow是Google在2015年开源的一款深度学习框架,目前已经成为了最火的深度学习框架之一。
相比于其它的深度学习框架,TensorFlow构建的神经网络是静态的,这代表着用户必须在程序一开始就将神经网络构建好,而不能(或者说很麻烦)根据反馈动态调整网络。这是被很多开发者所诟病的地方,但是也有不少人认为这种方式的网络能更好的适应Google自家的TPU处理器。
因为有Google背书,哪怕TensorFlow有着令人诟病的静态网络结构,它也成为了最火的深度学习开源框架。这使得有很多的新的组件和功能包被开发者们不断的开发出来,比如Keras,TFLearn,TensorLayer等
3)PyTorch介绍
PyTorch的前身是Torch,而Torch主要是基于Lua这个小众编程语言编写的,这导致Torch常年问津人数稀少。在经过Facebook的AI研究团队的重新编写后,PyTorch因为其优雅的设计重新进入人们的视野,并成为最热门的深度学习开源框架之一。
相对于TensorFlow的静态网络结构,PyTorch构建的网络是动态的,这使得PyTorch能在RNN动态时间长度输出的问题上有更好的表现。
2.2.3图像识别开源框架
> OpenFace(人脸识别)
OpenFace是在深度学习开源框架torch上实现的基于python语言的人脸识别开源框架,其使用的算法是基于CVPR 2015的文章:FaceNet: A Unified Embeddingfor Face Recognition and Clustering
OpenFace还使用了Dlib模型库来实现了对人脸的检测,并使用了OpenCV库来对图像数据进行处理。
通过实际使用,发现对人脸的检测还是可以基本进行使用的
> DarkNet - YOLO(物体检测)
YOLO是一名叫做JosephChet Redmon的大神与他的几个小伙伴做的一个开源实时物体检测系统。Joseph的几个小伙伴来自于华盛顿大学以及伯克利大学等知名院校。
YOLO是基于他们开发的Darknet(基于c语言的神经网络开源框架)上的一个应用系统,不同于前置检测系统将一副图像的不同位置以及维度分别进行分类预测,YOLO将整幅图像输入进单一的神经网络进行分类预测。这使得YOLO相对于其它的物体检测网络更加的快速。
YOLO开源框架也使用了OpenCV库来对图像进行了处理,这也侧面说明了OpenCV在计算机视觉领域上的重要性。
笔者也实际进行了测试,发现在个别类别上,识别效果出众。
3、配套的深度神经网络类型
在介绍了计算机视觉的背景以及软硬件环境之后,我们在这一节好好的介绍一下计算机视觉领域用到的各种网络结构
3.1卷积神经网络(Convolutional Neural Networks)
1)卷积神经网络基本介绍
卷积神经网络,也称CNN,是图像识别、音频识别领域的一个重要的算法。
卷积神经网络的工作原理简单来说就是利用多个卷积核(过滤器filter)来对输入的矩阵(图像)进行抽象,最后输出抽象出来的分类的过程。
上图是一个简单的卷积神经网络计算过程,通过对输入的车辆图片进行不断的卷积、激活和池化操作,最终输出一个正确的分类。
2)常用的卷积神经网络模型
随着卷积神经网络的发明,各种各样的卷积神经网络模型被不断的提出,图像分类、预测的准确率也在不断的提升。下边,我将对在ImageNet竞赛中的历年冠军模型进行相应的介绍,帮助大家理解这些卷积神经网络的特点。
AlexNet
AlexNet是2012年ImageNet比赛的冠军,相对于前几年的网络,其准确率有了很大的提升。
通过上边AlexNet的具体网络架构,我们可以看出,相对于之前的浅层网络,AlexNet首先加深了网络的深度,并使用了多个卷积层来对图像数据进行了抽象,最终使用了三个全连接层输出了包含1000个类别的分类结果。
VGGNet
相对于AlexNet,VGGNet的网络架构更深,而且分类效果也更好。形成这样结果的原因在于,VGGNet使用了更小的filter来代替大的filter。具体的VGGNet网络结构请参见下图
在介绍VGGNet前,让我们先看看一个简单的数学公式:3x3x3 = 27 < 7x7 = 49
通过这个公式我们可以知道,三个3x3的卷积层的参数数目其实比一个单一的7x7的卷积层要少的多。那么使用多个更小的卷积核代替一个大的卷积核能使得网络架构更深,并且需要计算的参数更少。
这么做的背后逻辑在于一个这样的认知:神经网络的作用其实是对输入数据的抽象,这个抽象过程使得输入和期望的输出形成一种映射关系。
那么更深的网络结构就能形成更加非线性的映射关系,而这种非线性的映射往往能更好的对输入数据进行抽象。
GoogleNet
看过“盗梦空间”的人应该对梦境的嵌套概念不陌生吧,在越深层的梦境中,时间过的越慢、造梦师越难分清梦境与现实,但是造梦师却能越接近做梦者的真正的内心,并对做梦者的思维进行影响。
于此概念类似,Google的工程师们引入了Inception(盗梦空间电影的英文名)结构,即在神经网络中加入另一层的神经网络,并成功的构建了GoogleNet网络结构,这种嵌套的神经网络结构使得预测的效果得到了显著的提高。GoogleNet的网络结构请参见下图
GoogleNet网络结构背后的设计思路是这样的,通过每个Inception模型,神经网络对输入进行了不同粒度的特征转换(分别是1x1、3x3、5x5和3x3pooling)。这样子输出的特征数据更加完整,丢失的信息更少,这使得原始数据能传递到网络的更深层。
ResNet
在介绍ImageNet竞赛的冠军模型ResNet之前,我们先思考一个问题,那就是既然网络越深,分类预测效果越好,我们为什么不尽可能深的设计我们的网络架构呢?
实际上,已经有人做过这方面的测试了,得出的结果如下:
从图中可以看出,神经网络达到一定深度后,其深度越深,其错误率反而越大。这是因为神经网络是通过比较神经网络的输出与真实输出之间的差别(loss)来对网络中的各种参数进行调整的,可是当深度过深时,这些差别(loss)传递到网络前端时造成的变化就已经不足了。这就形成了一种称为“梯度消失”的现象,使得神经网络并不能通过不断训练提高精度了。
如何解决这个问题呢?一个直观的想法就是想办法让数据的传递尽可能的远。ResNet就是根据这种思想构建出来的
通过上边具体架构图我们可以看出,ResNet通过将输入引入一个个的ResidualBlock使得输入信息的衰减比例得到缓解,并形成了惊人的152层网络结构,获得了很好的结果。
3.2循环神经网络(Recurrent Neural Networks)
3.2.1循环神经网络基本介绍
不同于卷积神经网络每一层的神经元之间没有关联,循环神经网络引入了定向循环,能够处理那些输入之间前后关联的问题。即RNN隐藏层中的每个节点的输出不仅与输入有关,而且还与之前状态的输出有关。具体情况如下图所示:
3.2.2常用的循环神经网络模型
长短记忆神经网络-LSTM
RNN显著的魅力是将以前的信息连接到当前任务的这种思路,根据这种思路,在理论上,RNN绝对有能力处理“长依赖”问题。可在实践中,RNN似乎无法学习到这些特征。
幸运的是,LSTM没有这个问题。
长短记忆神经网络——通常称作LSTM,是一种特殊的RNN,能够学习长的依赖关系。他们由Hochreiter&Schmidhuber引入,并被许多人进行了改进和普及。他们在各种各样的问题上工作的非常好,现在被广泛使用。
由上图可以看到,相对于常规的RNN网络,LSTM的结构复杂了许多。这里边的关键是LSTM引入了细胞状态(上图中最上端的那条水平线即是细胞状态),细胞的状态类似于输送带,细胞的状态在整个链上运行,只有一些小的线性操作作用其上,信息很容易保持不变的流过整个链。
LSTM通过三个门:遗忘门(forgetgate)、输入门(input gate)、输出门(output gate)来对数据的抽象过程进行管理。其中遗忘门负责决定对前一细胞状态的遗忘程度;输入门决定将多少新的输入信息注入细胞状态中;输出门决定将多少新的输入信息注入到输出中。
LSTM独特的网络结构很好的帮助了深层神经网络对长距离的信息的理解和保存
GRU
GRU是另一个很有效的RNN神经网络,与LSTM不同的地方在于其将忘记门与输入门组合成一个单一的“更新门”,混合了细胞状态c和隐藏状态h,使得最终的模型比LSTM模型要简单
4、检测与分割
在介绍了计算机视觉的基本概念和深度学习的基本框架和算法之后,我们来看看在具体实践中都有哪些研究方向,在每个研究方向中我们又该如何进行解决和处理。
4.1语义分割(Semantic segmentation)
语义分割的目标是在像素级别上对图片进行分类,即输入一张图片,我们要输出一张同样大小的图片,然后在图片的每块位置都要标注出其所属的分类(具体理解请参照上图)
那么如何做呢?很简单,既然知道了输入和输出是什么,我们只需要在输入和输出之间填充上神经网络不就行了!
当然实际的设计过程中并不会简单的将不同深度的神经网络堆叠进黑盒中来盲目的进行计算。
回到语义分割的具体场景,一个直观的思路是通过设计一个卷积神经网络,对图片的每个像素进行预测。但是这种方式有个问题,那就是计算开销巨大,针对这个问题,我们可以通过降维操作将原始数据缩小,然后再进行卷积预测,并在最后将输出升维到原始尺寸。具体的网络结构如下所示:
4.2图像分类与定位(Classification + Localization)
图像分类与定位的目标是识别出图片中包含的物体,并将该物体在图片中框出来,即输入一张图片,我们要输出该图片所属的物体分类,并输出该物体在图片中的位置。
这个场景相对于4.1语义分割来说,输出要少了不少,仿照之前的思路,我们的目标应该是构造一个神经网络,输入为一个图片,输出为图片分类以及分类物体的坐标位置(四个值:x、y、方框宽度w、方框高度h),具体的网络结构如下:
于此类似,如果我们将模型目标改成“识别出图片中的人的位置,并将人的骨骼点标注出来”,我们该如何设计神经网络呢?
很简单,将输出的五元组(图片分类、x、y、w、h)改成15元组即可(是否有人标签、左手坐标、右手坐标、左手肘坐标、右手肘坐标、…、头坐标)
4.3物体检测(Object detection)
在4.2图像分类与定位中,模型的目标是对一个图片整体进行分类,输出只是一个物体的位置。而在本节物体检测中,模型的目标是输出图片中包含的所有物体类别以及每个物体的具体位置。
换句话说,物体检测模型的输入为一张图片A,输出为检测出的一系列物体以及定位:a(label, location), b(label, location), … , n(label, location)
这个场景的不同点在于我们需要设计出一个模型,使得我们能输出不定数量的输出。如何做呢?有以下两个思路
1)先通过一个选择算法,对每张图片分别进行预计算,确定每张图片的输出个数(可能的物体数量)
Region Proposal算法能快速的从一张图片中选取出可能包含物体的区域,在单一CPU上能在几秒内检测出1000个可能包含物体的区域
R-CNN算法在Region Proposal算法的基础上对每个识别出来的Regions of Interest(ROI)进行分类预测
Fast R-CNN:R-CNN有个问题就是要对每个ROI训练一个卷积神经网络分类器,这样子太耗资源了,fast-r-cnn在此基础上进行了改进,将卷积层前移先将图片抽象成特征矩阵,并在此矩阵上进行Region Proposal,极大的提高了效率
Faster R-CNN:在Fast R-CNN的基础上,Faster R-CNN又做了进一步的优化,其将Region Proposal算法进行了替换。使用一个专门的神经网络来负责对可能的Region区域进行筛选
2)用一种通用的规则,将每张图片的输出个数预先确定下来(定死每张图片的输出个数)
YOLO/SSD:与其用专门的算法将图片中可能的物体区域识别出来进行预测,不如将图片平均分割,然后对每个分割区域以不同的粒度来进行框选作为一个可疑包含物体的区域。这种方法能省去区域识别的资源开销,提高效率
4.4实体分割(Instance Segmentation)
实体分割是在4.3物体检测的基础上的进一步细化的场景,其不仅要把物体识别出来,而且要对物体的轮廓进行识别。其输入是一张图片,输出为可能的物体以及其像素级别的坐标点。
那么我们其实可以将该任务分成两步:1)物体检测;2)对检测出的物体进行轮廓识别
Mask R-CNN:该算法是在Faster R-CNN的基础上设计的实体分割算法,效果很好。2017年Kaiming He最新的Mask-R-CNN算法也被选为ICCV 2017最佳论文。Mask-RCNN大体框架还是Faster-RCNN的框架,可以说在基础特征网络之后又加入了全连接的分割子网,由原来的两个任务(分类+回归)变为了三个任务(分类+回归+分割)