CNN 怎么工作
上一课结尾留下了一个问题:像照片这样,很难由人一个个挑出哪些值是线索的数据,该怎么处理?一张照片由几万到几百万个小点组成。把这些点排成一长行塞进普通神经网络,要学的连接实在太多;而且同一只猫只要往旁边挪一点,就成了完全不同的输入。于是人们造出了一种网络,像人眼那样一小块一小块地扫看,寻找特征。它就是卷积神经网络,简称 CNN。
照片是一张数字格子
在我们眼里它是一幅画,可要把照片交给计算机,终究得把它变成数字。凑近看照片,会看到叫作像素的小点,像方格纸上的格子一样密密排着。黑白照片里,每个点用一个数字记下亮度:亮的点数字大,暗的点数字小。
彩色照片则给每个点记三个数字,分别是红、绿、蓝的强弱。不管哪种,一张照片都是每格装着数字的格子。
点放大按钮看看。看上去是一个手写数字的图,凑近一看每格都是亮度数字,照片原来是一张数字格子。
一放大,每格都露出了数字。人一眼就认出是哪个数字,可计算机拿到的只有一张挤满数字的表。要从这堆数字里找出边缘、曲线这样的特征,该怎么办?
一下子全看太多了,所以从小块开始,一块一块地查。
用小滤波器找特征
找特征的工具叫滤波器。滤波器是一块比图像小得多的数字小板,用它就像把放大镜按在一个地方。比如找竖直边缘的滤波器,对左暗右亮的花样有反应。
把滤波器叠在图像的一个位置上,算出那里的数字和滤波器的花样有多像,这就是分数。在这个小工具里,分数等于右边两格的亮度之和减去左边两格之和。花样对得上,分数就高;对不上,分数就低。
在格子上选一个位置,按上滤波器。像滤波器那样左暗右亮的位置分数高,说明有一条竖直边缘从那里经过。
每个位置的分数都不一样。暗格和亮格相接的地方分数最高,那里正是竖直边缘。亮度均匀的地方,分数停在零附近。
这里有一点很要紧:同一个滤波器不管放在哪里,找的都是同一种特征。边缘在画面左边也好,右边也好,它都能同样抓到。既然这样,就不必只看一处,让滤波器扫过整张格子就行。
滑动滤波器,做出特征图
现在让滤波器一格一格地移动。从左上角开始往右走,走到一行的尽头就下移一行,再从左边扫起。把每个位置的分数记在对应的位置上,这些分数就聚成一张新的小格子。
这张格子叫特征图。看一眼特征图,就知道那个特征在哪里强。
点“滑一格”按钮移动滤波器。每个位置的分数填进特征图的对应位置,扫完以后,竖直边缘强的地方会亮亮地显出来。
滤波器扫完整张格子,特征图就做好了。五乘五的格子得出四乘四的特征图,比原来小了一点,可竖直边缘经过的那一列清清楚楚地亮了起来。一个滤波器只找一种特征。
所以真正的 CNN 会同时用几十、几百个花样各不相同的滤波器,有找竖直边缘的,有找水平边缘的,也有找曲线的。而且滤波器里的数字不是人定的。网络用前面学过的梯度下降和反向传播,朝误差变小的方向一点点修改它们。原来要人来挑特征,现在网络自己就能做。
层越高,特征越大
在特征图上再用滤波器扫一遍,小特征就会汇成更大的特征。第一层抓短边缘这样的小碎片,上一层把边缘组合成眼睛、鼻子这样的部分,再上一层把各部分拼成整张脸。
这和把神经元一层层叠起来的神经网络是同一个思路,只是 CNN 每一层都用滤波器扫看。层越往上,一格代表原照片里越大的范围,抓到的特征也就越抽象。
点“升一层”按钮,一层一层往上走。看到的东西从边缘碎片变成眼睛、鼻子这样的部分,再变成整张脸,越来越大。
每升一层,看到的东西就更大。低层看小而简单的碎片,高层把这些碎片编成有意义的形状。先看线条,再认出部分,最后把握整体,这和人认东西的过程也很像。
研究者打开训练好的 CNN 来看,常常发现低层的滤波器对边缘和颜色交界有反应,高层的滤波器对眼睛、车轮这样的部分有反应。小工具里的脸,就是把这个过程画得简单一些。
小结
归纳起来是这样:照片是每格装着亮度数字的格子。CNN 把小滤波器放在一个位置上,给那里有没有要找的特征打分。用同一个滤波器扫过整张格子,就得到一张不管特征在哪都能找到的特征图。
把这样的层叠上好几层,特征就从边缘到眼鼻,再到脸,越来越抽象。滤波器里的数字是从数据里学来的。
依次点要点回顾一下。(照片是亮度数字格子 → 小滤波器给特征打分 → 扫过去做出特征图 → 层越高特征越抽象)
现在你知道计算机是怎么看图的了。它把照片变成数字格子,用小滤波器扫看找特征,再叠起层来抓越来越大的特征。因为同一个滤波器扫过整张照片,猫挪到旁边也照样找得到。
不过,单词和句子不像照片那样一开始就是数字格子。下一课讲怎样把单词变成数字,也就是嵌入。