让神经网络看懂图像
视觉的重要性毋庸置疑, 你可以想象,我们平时的生活, 从识图辨物, 到读书看电脑, 哪一个离不开视觉。 所谓的互联网信息大爆炸, 你看看我们手机空间里的大部分图片是什么, 一定是照片。 所以, 我们说视觉占领了我们信息的主体。这背后深层的原因是视觉相对听觉或触觉对真实世界的信息效率大的多, 一个图片可能包含很长一段文字的信息, 这点是其它渠道所不能比拟的。生物进化出视觉而有了寒武纪大爆发, 那么让机器拥有视觉能力, 一定是让它变得更聪明的第一步。
人脑对图像的认知:
电脑记录下来的图像是由一个个像素构成的,每个像素又分为r,g,b三个通道(可以理解为垂直排列的三个像素),这三个通道起到复现整个光场的作用。而事实上物理里的真实的图象, 是一个由无数光子组成的电磁场, 这个电磁场在我们的视网膜上振动, 从而形成了我们对图象的感知。 因此, 归根到底 ,我们是用大脑, 而不是用双眼来感知图象的, 也许我们永远无法知道真实世界是什么样, 但是是我们的大脑赋予了它形象, 一个很好的例子就是你分不清猪的美丑, 但我想猪是可以的, 这正说明了所谓的相由心生, 你不关心, 就看不到。
那么什么是我们大脑处理图象的神经基础呢? 多少代的科学家研究这个问题, 最终有了一个比较完备的答案。 一个眼睛正常的人不一定能够产生对视觉的知觉, 有一种叫视觉认知症的人: visual agnosia, 它们虽然可以看见物体, 却无法区分一个物体时什么, 课件, 看到, 不等于知道。 事实上, 大脑对视觉的感知主要时通过视觉回路实现的, 这个视觉回路的概念 , 主要是通过视皮层V1-V4完成的。
这个v1到v4的视觉回路, 本质起到的作用是一级一级的筛选视觉特征。 我们之前讲过, 每个细胞都相当于一个小的特征检测器, 而我们事实上发现, 这些小的特征选择器所检测的目标是不同的, 有的对简单的特征敏感, 比如桌子的轮廓边角, 有些对复杂的特征敏感, 比如桌子的腿或边角, 一个重要的假设是复杂细胞形成的基础正是简单细胞的组合, 很多简单细胞的输入构成了复杂细胞。 而最“复杂”的一些细胞, 居然会对那些抽象的人名,物体概念敏感。 为了表达这种极端的特性, 我们把这类极为复杂的细胞称为“祖母细胞”就好像每个人的脑子里都有那么一个细胞对自己的祖母是反应的, 它就是祖母的代言。
这种表面的“简单”, “复杂”其实可以被一个称为为层级编码假设的理论解释, 说的是比较底层的细胞先得到从视网膜传来的视觉信号(类似数码相机的图象)进行处理, 然后所谓的“复杂”细胞, 无非是把最底层的特征拼接组合起来, 得到比较了比较复杂的特征。而最终当我们得到的祖母的头, 鼻子, 或眼睛这些特征的时候, 在最后进行一次综合就得到了“祖母细胞”这种复杂概念的对应物。当然, 这只是粗浅版本的视觉编码机制。 很多人认为除了层级特征, 视觉编码还需要具有集群编码的特性, 也不一定存在那么一个特定的祖母细胞, 而是概念被一个细胞发放的集体模式所表达。 这些我们就不一一详述了。
模拟人脑的CNN
如何把图象让机算计处理呢? 我们可以在深度学习兴起以前, 这是一个超级超级难的问题。 我们就拿机器视觉最简单的例子: 图象分类来说。我们前两节课讲过应鸢尾花的识别, 在这个例子里, 我们看到的实际状况是花的照片来了, 然后我们的植物学家告诉我们花瓣的长度和宽度是重要的特征, 它可与把鸢尾花分为三类, 这样,我们的计算机就可以用前面讲过的KNN把花分成三类。这个方法里, 计算机事实上接受的一个表格数据, 也就是花的特征总结, 而得到一个分类的结论。 非常可惜的是, 这和真正的图象识别相差甚远。 因为真正的图象识别,意味着我们直接把图象,也就是我们看到的原始数据给计算机处理。 或者说, 计算机需要自己找出像花的长度和宽度这样的特征。
刚刚说了, 计算机眼里的图象是一个巨大的矩阵, 首先图象由像素组成, 每个像素就是一个数字, 它代表我们对信息的采样。 像素组成的图象是黑白的, 然后我们需要对不同波段的光波分别形成这样一个黑白图, 然后把它们拼接在一起,得到我们最后的彩色照片,比如我们拿一个日常的3x256x256的图像看, 那个像素就是256x256个,然后有三个色彩通道。 如此组成了一张图片。最终这个图象这样的信息维度是巨大的。 远非机器学习的常见问题可以比拟。
让机器来直接看图,这个在过去看似不可能的技术,被一个叫卷积网络的东西给解决掉了,在2012 ,它超过了所有的视觉算法, 并在随后几年在很大的数据集上赶超人类。这个卷积网络正是对刚说的生物神经网络的直接模拟。
什么是卷积
你要理解卷积, 只需要理解一个东西叫滤镜, 人类在处理图像问题的时候, 最有名的发明莫属photoshop了, 在ps里你可以把图片调整各种各样的色调,模糊,锐化, 这些东西统统是一个叫做滤镜的东西做出的。
滤镜这个玩应, 你可能想到镜头前的镜片,事实上,它所做的事情是把图像转化为 一个另一个图片。 它是怎么做到的呢? 数学上的操作,正是今天讲的卷积。数学上, 这些操作对应的运算都有一个特点, 就是对局部的信息进行综合 ,得到一个新的信息。
看看卷积的数学操作,卷积,顾名思义, “卷”有席卷的意思,“积“ 有乘积的意思。 卷积实质上是用一个叫kernel的矩阵,从图像的小块上一一贴过去,一次和图像块的每一个像素乘积得到一个output值, 扫过之后就得到了一个新的图像。我们用一个3*3的卷积卷过一个4*4的图像。
卷积网络的基础正是这样的卷积, 我们说通过一个滤镜我们可以提取一个图象的特征, 那么为什么我们要采取看起来这么笨拙的一个方法呢?
图像识别与降维
其实要让神经网络告诉某两个照片是香蕉还是苹果, 并不是那么难, 但是图像识别的根本目标是你要识别整个世界的香蕉或苹果, 这个问题背后的核心是我们之前讲的泛化。 也就是让它理解苹果这个概念。当然你可能会想到苹果是红色, 圆形这种具体的特征,这些特征变化了,它就不是苹果了。 但是我今天要说的是, 你要让计算机来学到这个东西, 你要想的是反过来, 那就是, 什么特征变化了, 它还是一个苹果?
首先,我们想到的是, 一张图象是跟苹果还是香蕉, 首先一定不取决于它所处在图象中的位置。 这个东西叫位置不变性, 或者叫平移不变性。我们把这个特性直接写到神经网络里, 就是卷积。 什么意思, 卷积就是拿着一个恒定不变的小型矩阵, 一行行的扫过整个图像, 这样得到一个特征图。 你的苹果无论出现在什么位置, 对应我的卷积扫描这个行为, 事实上得到的结果都是一样的, 数学上说, 就是你的图像如果移动了5个格, 它在特征图上也做同样的一个移动, 别的什么都不变。 能够满足这种条件的运算-就是卷积。
卷积被当成先验信息写入,每次卷积都对应一个神经元对图像的一个小块进行信息提取, 而每个神经元与输入的连接系数均是一致的,这个特性叫做权值共享。不要小瞧这样一个简化,有了这样一个简化,我们的神经网络得到正确的解就好了很多。用一个术语就是, 我们把问题的维度减少了。 抓住一个不变性, 你就可以把需要解决问题的维度指数级别的减少。
激活函数:
事实上完成局部特征检测这一步,我们还需要一个东西,就是激活函数, 这个我摸嗯上节课已经讲过了,一般这里用的激活函数是relu,它的作用是把一个信号里为负的部分变成0,你可以把这看成特征提取的实现,更本质的说,如果没有激活函数,我们的神经网络将是一个巨大的线性回归而已。
ReLU函数是小于0是为0,大于0时为自身
什么是通道:
我们以一个手写数字的历程为例,讲讲我们还需要什么,首先我们说, 一层卷积对应一个特征, 但是,显然一个特征是不够识别的。 就以识别数字为例子降价给你这个问题, 比如你要识别10个数字,仅以1和7为例子。显然识别它们的核心方法就是条纹走向。横线是一个特征,竖线是一个特征。如果一个卷积对应一个特征,那么我们其实需要两个卷积,让一个卷积核可以识别横向条纹, 另一个卷积核识别纵向条纹, 这个操作就可以。
这样的操作,使用如下的3x3卷积就可以了: -1,1, -1 , 这样的算子具有和之前提取梯度的运算差不多的样子。只要两种卷积核可以做到这点, 然后,如果我们把这两个卷积核组成一个小组扫描一个特征, 那么我们就会知道每个图像小块上的横竖情况。
比如这时候我们得到每个图像小块的一个特征编码,一共有四种情况 (0,0),(0,1),(1,0)(1,1),横线对应(1,0)竖线对应(0,1), 你是不是可以把整个数表看成一个新的图像 ? 而这个新的图像里的变化从(1,0)到(0,1)是否相当于一个角度呢? 这就是比条纹走向更高级的一个特征。 怎么提取它?如果你的答案是再放入一层卷积, 恭喜你答对了。
回顾整个过程,我们要做的无非是在第一卷积层的位置上, 放两个并行的卷积核, 一个核处理横向条纹,一个处理纵条纹, 得到两组不同的特征, 最终我们在前面的两个特征之上读取这组新生成的特征图之上的特征。 下一层卷积寻找的上一组卷积的特征组合。这个操作对应的是在两张并列的图层之上,在它们的同一位置识别信息, 如果两个警报器均响了,说明夹角存在, 我们依然可以用一个3x3卷积网络来完成这个操作,这个新的卷积建立在之前的纵横两组卷积之上,对原先的横纹和纵纹组成的特征空间进行操作(因为这里的维度是2x3x3,最单纯的情况我们也可以用一个2x1x1的一个矩阵综合两个特征)。 因为这个时候, 对之前平行卷积的结果做一个综合, 以及形成一个特征之特征, 即横向和竖线交叉的特征。
这样的方法无论手写数字出现在什么位置, 我都给你找出来。
从两层到多层:
我们刚刚说 kernel就是通过计算小区域内像素的关系来提取局部特征,而最常用的卷积核大小是3x3, 那么这里的一个问题是, 为什么要这么小, 为什么要提取一个局部信息?我们说因为图像这个东西里包含的信息具有以下特点: 最底层的信息,比如边角轮廓, 都存在于局部之中, 只有更上层的信息,比如物体的概念, 才会用到更多部分的信息, 而这种跨度又是逐步发生的。那么,如果实现这种跨度呢? 答案: 多层。局部特征,在更高层上被组合, 会变成整体特征。
首先,我们把每个神经特征所提取的特征区域, 叫感受野,如果我们始终只能用的其实都是3x3这样的小卷积核, 我们能不能让感受野扩大呢? 答案是, 可以。 这里的关键是一个叫池化的造作。
最大池化所做的是事情,是把每四个相邻神经元得到的数值取一个最大的, 其它全部扔掉。每次卷积后如果经过这样一个操作,那么图像就会缩小到原先的四分之一,而再次之上的相邻四个像素, 对应了原始的16个像素, 从而使得感受野迅速扩大。
Pooling的本质依然是降维,或者过滤冗余信息,这个就是pooling。背后能够这样做的理由是,局域特征特征是大量冗余的 ,经过条纹提取的数字一定在大量临近区域里的数值都一样。 冗余踢去后, 经过pooling, 上层细胞得到更大的感受野,也就抽取了更高层次的特征。
卷积层 ,激活函数,pooling帮我完整的特征提取到剔除冗余的过程 , 这可以称为卷积网络的三明治, 把这个结构不停迭代,我们可以构建一个很深的网络。
深度意味着什么? 我们想一下, 要正确的识别一个图像,你不可能只看边,也不可能只看角, 你要对图像的整体有认识才知道张三李四。 也就是说我们要从局部关联进化到全局关联, 真实的图像一定是有一个全局的,比如手我的脸, 只有我的眼镜,鼻子耳朵都被一起观察时候才称得上我的脸,一个只要局部,就什么都不是了。如何提取全局特征? 从一个层次到另一个层次的递进, 通常是对上一层次做横向以及纵向的整合(图层间的组合或图层之内的组合或两者)。
我们刚刚讲了CNN如何找到边角的过程, 但是它的下一层会是什么?再下一层会是什么? 我们头脑中的想象力已经不够了。我们只能做让学习得到结构,然后去观测。我们可以把每组卷积网络看做一组基,我们在这组基上重构我们的信息, 就和线性代数里坐标变换相似,只不过非线性更复杂。 每一级别的网络都是一组新的基底,我们把刚刚的全局换一个词叫抽象。深度卷积赋予了神经网络以抽象能力。 这样的一级级向上卷积做基变换的过程,有人说叫搞基(深度学习就是搞基),深一点想叫表征, 和人的思维做个比喻就是抽象。 抽象是我在很深的层次把不同的东西联系起来,CNN教会了我们实现抽象的一种物理方法, 他也体现了在一个空间尺度上我们所能够达到的特征工程。
最终分类:
这里我们还差最后一步没讲, 整个CNN网络如同一个等级社会里,最上层的,就是君王。 而这个君王,与直接其下的一层(议会)的关系,事实上往往是全连接网络。为什么,因为这时候君王要做的是最终决策, 它不在“搞基”提取特征了。一个非常复杂的问题,已经在此时变成了线性可分的简单问题。 决策 – 就是做一个线性分类, 得到我最想要的结果。 我们要做的是返回一组最终可能结果的概率。如果得到可能结果的一组概率? 我们搬出基于最大熵模型的softmax gate ,这也是正是CNN网络做分类的最后一层。 至此,我们可以得到众多识别物体的抽象信息。 那个概率最大的,即使我想要的结果。
总结:
更多阅读
作者简介:微信号:ironcruiser 法国巴黎高师物理硕士 ,以色列理工大学计算神经科学博士,巡洋舰科技有限公司创始人, 《机器学习与复杂系统》纸质书作者。
薛晽2019-03-02 20:23:18
吉祥物龙猫2019-03-22 15:40:01
许博士,以前我毕业设计用matlab完成的,十几年不用了。如果当时有人工智能方向正好用上。搞算法才像个工程师的工作,搞编程像蓝领。
吉祥物龙猫2019-03-22 15:36:44
语言识别比图像识别难搞懂。非线性问题比线性问题复杂
吉祥物龙猫2019-03-13 08:25:18
我刚买了许铁的书。语言浅显,非常通俗易懂,内容循序渐进。
作者
谢谢!
wert2019-03-08 20:12:44
最近也在做这个花鄂训练,我有个问题,目前卷积网络有很好的识别效果,但是,它能产生怀疑或者认为自己错了这种函数吗?
作者
目前还不能的
施飞2019-03-03 09:14:28
铁哥的书买买买