微博上有个我挺喜欢的博主推荐过一本科幻小说,推荐微博写得很让人心动。最近学习计划也不很紧迫,我就趁休息把小说读了,整个阅读体验特别地棒。小说名为《造神年代》,主题讲的是奇点降临,但涉及有其他领域知识比如大脑智能原理与神经网络等,且作者说过这部分不属于科幻,属于科学范畴,而理论来源应该是《论智能》一书。但由于小说特有的通俗性,写得比原书吸引人多了。
因为这本小说,我专门初步学习了下神经网络的工作原理,但在最终进入神经网络的话题前,我认为有必要先回顾一下论智能一书中对大脑的剖析,以及由此产生的对学习中直觉与抽象思维的思考。
当然了,既然属于科学范畴,肯定是可证伪的嘛。
什么是智能
智能其实是一种很低级的特征,本质上就是一个记忆-预测模型。植物记住了水在重力方向并预测向下长会碰到水,所以植物有智能。蟑螂的祖先用死亡记住了空气扰动等于危险,于是预测空气扰动时马上跑一下,能够提高生存率,所以蟑螂也有智能。
然而我们很清楚,植物与蟑螂都没有意识。你在植物上空挂一个重力垫,它的根就会向上长,即使旱死也这样。你向蟑螂挥手它会跑,挥一百次跑一百次,即使你只是调戏它。因此植物和蟑螂其实都是生物版本的自动机,你可以百分百预测它们的行为,输入确定条件,得到确定结果。
但是到了狗这样的动物,情况就不一样了。我们可以大致调教狗的行为,但宇宙中最高等的智能,也没法百分百预测狗的一举一动。今天你打它一下,它会很委屈但是服从。明天你同样打它一下,它可能会咬你。所以狗是有意识的,很初级,但是存在。
我们现在的很多机器,论智能比人类厉害多了,它们能记住全世界的书籍,记住亿万行代码;能预测弹道,预测天气,甚至能预测地股市这么复杂的现象。要是真从这个智能定义出发,我觉得研究人工智能的专家们早就成功了。不过他们总是自我怀疑,无休止地争论这是不是智能。我认为他们应该是搞错了概念,他们真正追求的不是人工智能,而是人工意识。
意识这个玄学概念,其实有一个狭义但明确的定义:意识代表一个智能的行为可以偏离其他智能的预测。要做到这一点,首先还得知道什么是“其他”和与之相对的“自我”。因此,自我的概念同样也是意识之本。
但人工意识是一条绝路。考虑我们刚才的定义就会明白,意识是不能人工设计制造的,因为它的定义就是偏离设计!而真正的意识,只能从复杂网络中自发产生。人类制造的超级计算机,在智能方面算是聪明绝顶,但还是完全被人类编写的程序掌控,从这个角度看它们远不如狗脑复杂。
大脑的工作原理
谈起大脑之前,首先考虑一下我们的电脑。显然电脑的世界里数据结构异常复杂,各种各样的格式、标准、语言、协议、接口,纷乱繁复。而大脑呢?大脑只传输一种信号:神经电位冲动;只存储一种数据:组合序列。
我们的感官接受了很多信号:视觉接受电磁波,听觉接受声波,还有压力、惯性方向、热量转移速率、无数种化学分子、气溶和水溶分子接收体系还不一样……大脑可不像计算机,为每种信号规定一种格式。大脑在神经系统的边界层就把它们全都转换成神经电位冲动,在内部全都存储为组合序列。所谓冲动,就是一个神经元以电位形式兴奋起来,并把兴奋传给连着的另一个神经元。每个冲动本身都是一模一样的,区别只在于从谁传给谁;所谓组合,就是哪些神经元一起兴奋。所谓序列,就是不同组合兴奋的先后顺序。这就是大脑唯一的数据格式,大脑用它解决了所有问题。
我们每时每刻都在接受海量的感官信息,视网膜感光细胞就有几百万个,看电影时每秒激励10次左右。虽然大脑有上千亿个神经元,也不可能存下这么多组合序列。于是大脑使出第二招:模式抽象。
假设你在看书,印刷文字反射的光线投在你视网膜上,于是感光细胞开始一群群激励,向大脑中连着的神经元发送冲动。有些冲动的组合序列代表受激励的感光细胞直线排列,大脑把它抽象为“直线”,在上一层用一个或者几个细胞的组合代表。同样的方法也产生“弧线”这样的抽象概念。接着,几个“直线”和“弧线”的特定序列组合,在更上一层抽象为字母 h。几个不同字母的组合序列,在更上一层抽象为单词 horse。记录 horse 的组合序列,会跟另外一些早已存在的序列连接起来——比如你听见这个单词的读音产生的序列,那是耳朵接收音频转换生成的序列。
所谓连接,就是共同激励,你一兴奋我就兴奋。英国和美国口音 horse 的念法不同,男人和女人的声音频率也差得远,ma 的发音跟 horse 天差地远。但是这些都没关系,它们跟视觉产生的那个单词序列仍然连在一起。这几个序列彼此全部连通,那么就会再次向上层细胞抽象。在这一层,“马”已经甩掉了黑毛还是白毛、听觉还是视觉、文字还是图像、中文还是英文这些不必要信息,成为一个真正的概念,用一个特定神经元组合记下来,我们可以叫它马细胞。那么以后你不管通过哪种感官接收到关于“马”的信息,甚至闭上眼自己想一下,马细胞都会兴奋起来。
它还会跟大脑中许许多多其它概念连起来。比如另有一个“牛”的概念。这两个东西的组合序列会很相似,因为抽象出它们的下层概念很多都是重合的。比如四条腿,比如都能被人养。大脑会发觉这两个组合序列相似,虽然不清楚该叫什么,先连起来再说。以后你再听到“家畜”这个说法,更高一层的概念名字就取好了,新的存储组合也生成了,以后认识的猪和羊都连到这里。这就是大脑的第三招:分类。这种层层抽象还会向上延伸,比如生成“动物”的概念,还会跟其它概念产生横向连接。
正因如此,比喻才成为了我们的第一修辞手段,并且已经从底层的无意识上升为有意识。我们用类比思考,用隐喻扩展概念和语言,再倒过来用语言塑造大脑。我们对相似、类比、隐喻的依赖深入骨髓,统治我们每一种思维活动、每一种智力表现。我们不喜欢跟已知世界模型完全相同的信息,那叫重复,大脑的反应是厌倦、疲劳;我们也不喜欢完全找不到模板的信息,那叫陌生,大脑的反应是迷惑、恐惧。我们热爱的是相似:大部分相同,让大脑轻松理解;有一点区别,让连接再次延伸。这一点区别,就像DNA复制中的误差,就像生物每一代的变异,是我们智慧的根本、创造力的源泉、上升的原动力。
为什么我们都热爱音乐?音乐就是节奏序列大体相同,频率序列大体相似,但每一段、每一阶稍有变化。这就是大脑最享受的体操,全员起舞。不信你把八度音阶的频率稍微改一点,不是前一阶的正好两倍,听听有多难受。为什么我们觉得美人的脸美?以前统计的学者说是因为对称,只说对一半。不信你找张美人图,把任意半边脸对折过去合成,看它怪不怪。大脑认为在对称的基础上稍有变化最美。过分对称的美女,知道给自己插上一朵鬓边花,点上一颗美人痣!
总之,组合序列记录、模式抽象、分类。大脑就靠这三招,在内部建立了一个世界模型。如果这个模型是一座大厦,我刚才描述的局部就比一块砖还小。然而,整个大厦都是用这种机制建成的。这个世界模型的物理位置在大脑皮层,仅仅用了六层细胞,大概一千亿个。我们遇到的每一个需要智能解决的问题,大脑都在建好的世界模型中推演,就像棋手先推演下面几步,再落子。这叫预测。或者根据新的信息,先在世界模型中增添新组件,和旧组件建立连接再来推演。这就叫学习或者叫记忆加预测。
需要注意的是,大脑的世界模型不是从你出生开始构建的,实际上只有最顶层很少一部分跟出生后的学习有关。下面占多数的底层,组合序列早已建好,预测模型早已完美,数据庞大到不可思议,连接复杂到不可思议,都是你继承的遗产。这些部分很多跟你的身体有关,更多的与外部世界有关。随便挑出一个局部,都能让顶尖的概率学AI汗颜。
我们挑个简单的:皮肤上的压力感受器。你刚出生,它就对外部世界无师自通。给它个尖锐而快速的压力——痛觉,模型预测是荆棘或者爪牙,对策是不经过意识反应直接缩开,越快越好。给它个点状分散、轻微而移动的压力——痒觉,模型预测是昆虫或者腐蚀性物质,对策是没手的去树上蹭,有手就用手挠。给它个宽广、稳定而柔和的压力,模型预测是爱抚,对策是通知某个腺体分泌神经递质,神经递质促进一大片预先编好的组合序列兴奋起来,让你觉得舒服,还会启动一整套社交行为。比如四脚朝天亮出肚皮,或者睁开眼笑一下。
这么庞大复杂的底层模型,当然也是一点点学习外部世界学出来的。不是我们自己,是五亿年间每一个直系祖先。学习方法是世界让神经建模不行的早点去死,或者终身找不到对象,那些就不是我们的祖先。建模够快、够准确的才有资格做祖先。它们把整体建模的菜谱刻在基因组当中传给我们——菜谱,不是蓝图!也就是说,每个人头颅中的世界模型刚一出生,对世界的学习就已经持续五亿年,所以它才会长得那么复杂。
最终,在这些先天的基础和后天的学习下,人脑才成为了蓝星唯一一种通用智能。
直觉与抽象
之前我看过的一篇博客中提到:
按照现行的国际标准,线性代数是通过公理化来表述的,属于第二代数学模型,这就带来了教学上的困难。事实上,当我们开始学习线性代数的时候,不知不觉就进入了“第二代数学模型”的范畴当中,这意味着数学的表述方式和抽象性有了一次全面的进化,对于从小在“第一代数学模型”,即以直观具体为导向的数学模型中学习的我们来说,在没有并明确告知的情况下进行如此剧烈的转换,不感到困难才是奇怪的。
自从 1930 年代法国布尔巴基学派兴起以来,数学的公理化、系统性描述已经获得巨大的成功,这使得我们接受的数学教育在严谨性上大大提高。然而数学公理化的一个备受争议的副作用,就是一般数学教育中直觉性的丧失。数学家们似乎认为直觉性与抽象性是矛盾的,因此毫不犹豫地牺牲掉前者。然而包括我本人在内的很多人都对此表示怀疑,我们不认为直觉性与抽象性一定相互矛盾,特别是在数学教育中和数学教材中,帮助学生建立直觉,有助于它们理解那些抽象的概念,进而理解数学的本质。反之,如果一味注重形式上的严格性,学生就好像被迫进行钻火圈表演的小白鼠一样,变成枯燥的规则奴隶。
关于博主的观点,我在撰写理解线性代数一文时深有感触。我作为智力普通人群,还是很支持他在教育中引入直觉的观点的。但我想说的是,从《论智能》一书的理论看,也许直觉和抽象并不是对立的两个概念。
为什么这么讲呢?当时我刚看完小说,莫名就想到了上面引用的那段话,于是联系起来略一思考就意识到了答案:直觉其实就是曾经的抽象结果啊。我们觉得一个事物是直觉的、易于理解的,那是因为我们脑中的抽象巨树上有类似的节点。因此大脑可以轻松理解,并让概念再次延伸。而数学中的某些抽象概念,如果劈头盖脸直接给出,我们的大脑会非常无所适从,因为这棵树上完全找不到他的位置。
而一众科普作家,如开头提到的小说作者严曦本职;一众图形化数学教学博主,如理解线性代数一文中的 3Blue1Brown。他们的直觉性教学,本质上是在补上那些抽象事物与大脑已有抽象巨树之间的连接层,或者说,根本就是在还原这个抽象事物的诞生过程!
因此引文中提到说,数学家认为直觉性与抽象性是矛盾的,我认为不太恰当。确切地说,要是真有这么想的数学家,那他逻辑性还不如我呢。很多人,包括我在内,在内心都会或多或少地神化数学家,而过分的神化会使我们产生一种错觉,即:数学家们的脑子就是为了抽象事物而生的,他们天生擅长处理这些与已知世界模型毫无联系的事物。但其实不然,上文我们已经知道学习是抽象的过程,在学习中引入直觉性意味着还原这个抽象事物的诞生过程。而这句话还有一个弦外之音:创造其实就是一种抽象,只不过是步伐很大、从已知跃入未知的一种抽象。但不管步伐多大,其中必然会有脉络可循。因为没有脉络意味着与现实世界没有联系,而没有联系的创造毫无意义。
那么数学概念呢?我们有了数字,才会有四则运算的需求,有了四则运算,才会有函数映射的发展。每一个抽象概念的创造都有着对应的需要,就算是数学这座抽象高峰上最顶端的概念,也必然是一块土一块石头堆上去的。既然连概念的创造者都需要一段通向抽象峰顶的台阶,后来的学习者又怎能幻想不爬台阶直接坐缆车上山呢?
这就是我的观点——所有的学习过程中,“直觉性”都是必不可少的一环。只不过对我这种无力攀登峰顶之人而言,我希望至少我爬过的路得是连续的吧!这也是我写那篇理解线性代数的根本原因。
理解神经网络
考虑到大家脑袋里那个不到 100 瓦的东西现在依然是全地球仅有的通用智能机器,要想创造 AI 看来还是得向这位老前辈学习。万幸在上文中,我们已经为这个神奇的通用智能机器总结出一条简明的逻辑,因此我们很容易想到初步模仿计划。
神经网络创造计划 alpha 版:
- 确立一个小目标:识别方框中的字母:$\boxed{h}$。
- 将神经元设计为一个专门装数字的容器,数字代表像素灰度值(0~1;纯黑~纯白),我们可以称称之为神经元的激活值。可以这么理解,随激活值增大,神经元会被逐渐点亮。
- 假设每一个神经元对应方框中的一个像素,那么这些神经元就组成了神经网络的第一层。
- 接下来,假设第二层神经元的其中一个代表抽象后的“横”。于是我们的阶段性目标即:只要第一层在特定的关注区域(降低下难度…)中识别到“横”,第二层中的该细胞便会点亮。
- 实现方法:对每一个连线都赋予一个权重,关注区域赋正值,关注区域周围赋负值,其他区域赋零。于是第一层激活值与权重相乘后,会仅仅计算关注区域激活值。且因为关注区域周围为负值,若存在一条横线,那么横线处加权结果为正值,周围加权结果趋向零,总的加权结果最大:
- 上述实现方法补丁一:每一层的激活值都需要处于 0~1 之间,故应借助 Sigmoid 函数使加权结果映射进去,加权和越大,映射结果越接近 1,反之同理;
- 上述实现方法补丁二:容易想象,加权结果很容易出现正值,我们需要在加权后减去一个偏置值后,再用 Sigmoid 函数映射。也就是说,偏置值是一个阈值,决定了加权和多大时该神经元的激发才有意义。
- 之后每一层均同理。这样一来,每增加一层,初始数据就会像大脑一样向上抽象一层。
顺便说一下题外话,当看到这一大堆节点、一大堆连线和一长串加权与偏置,会不会觉得这个描述方式太过复杂,一点也不优雅?于是我之前写的那篇理解线性代数就派上用场了。我们可以将第一层所有激活值与第二层所有节点的偏置值分别记作一个向量,将该层与下层所有节点间的所有权重记作一个矩阵,矩阵第 n 行即终点为下层第 n 个神经元的所有权重:$$\begin{bmatrix}w_{00}&w_{01}&\cdots&w_{0n}\\w_{10}&w_{11}&\cdots&w_{1n}\\\vdots&\vdots&\ddots&\vdots\\w_{n0}&w_{n1}&\cdots&w_{nn}\end{bmatrix}\begin{bmatrix}a_{10}\\a_{11}\\\vdots\\a_{1n}\end{bmatrix}+\begin{bmatrix}b_{1}\\b_{2}\\\vdots\\b_{n}\end{bmatrix}=\begin{bmatrix}a_{20}\\a_{21}\\\vdots\\a_{2n}\end{bmatrix}$$则该向量矩阵乘法的结果即为第二层所有神经元的激活值。
但是 alpha 计划有一个明显的缺陷。我们从之前的章节知道,大脑这个模型绝大部分抽象机制早在出生时就已建设完毕,建设工作为五亿年间所有直系祖先共同完成——没完成的那些没资格做祖先。但是我们的 alpha 计划没有五亿年的建设时间,在 alpha 计划中,这些权重和偏置实际上都得手动设置。想想看,假设第一层 1000 个节点,第二层 100 个节点。仅就第二层而言,就需要设置 1000 × 100 个权重值与 100 个偏置值,那层数再多点呢?这一大坨参数本来应该是进化论干的活,要想手动设置也太气吞宇宙了。所以如何让机器自己设置这些参数,或者说如何让机器“学习”,就成了我们的目标。
神经网络创造计划 beta 版:
- 首先完全随机初始化所有权重和偏置,显然,刚初始化后的网络对数字或者字母的识别会是一团垃圾。
- 因此,我们需要一个代价函数告诉这个网络:“你是团垃圾你知道吗!”。具体做法是考虑最终层所有节点,求出 $\sum(每个垃圾激活值-期望得到值)^2$,我们称之为训练单个样本的代价。代价是对最终层更上一层的抽象,相当于用单个数字反映了网络中所有参数的好坏。显然,这个平方和越小,代表网络识别越准确:
- 仅仅让网络知道自己是团垃圾没有意义,我们需要告诉网络改进参数的办法。而这个网络本质上是一个函数,输入是网络中的参数,输出是代价。因此我们需要寻找一种方法,使得在任意输入下,都能找到对应最低输出的输入,即求出 $w_{min}$ 所在处坐标:
- 我们可以设计这样一个算法:令函数越平缓时坐标移动步伐越小,显然当坐标移动停止时即得到最小值坐标。但是问题接踵而至,如何用数学语言描述“平缓”呢?还有,二维坐标仅仅只有两个可移动方向,但是三维坐标就有无数个可移动方向了,遑论更高维度,如何确定坐标移动方向呢?
- 为此,我们引入梯度概念:梯度向量代表一个函数在某点的最陡增长方向,且梯度向量的长度代表了这个最陡的方向到底有多陡,例如 $\begin{bmatrix}d_{1}&d_{2}&d_3&d_4\end{bmatrix}^T$ 就可以是某四维空间函数中一点的最陡增长方向。因此,我们完全可以将网络中的所有层数参数视为一个巨大的 n 维坐标,将每个样本的训练过程视为输入 n 维坐标然后输出代价值。那么我们就可以利用梯度的特点,一步一步找到这个函数的最小值坐标。
- 具体步骤是:输入初始 n 维坐标并求出该点处梯度 $\longrightarrow$ 令坐标朝梯度反方向走一大步或挪一小步,具体大小取决于梯度向量长度 $\longrightarrow$ 再次求梯度 $\longrightarrow$ 循环直到梯度向量长度达到最小值 $\longrightarrow$ 输出 n 维坐标。即求梯度的过程指出了坐标如何改变才能使代价函数值下降的最快。
- 这个利用求梯度、改坐标、一步一步把几万个样本的平均代价挪向零的算法,即著名的反向传播算法。至此,这个上世纪八九十年代发明的东西,我们就大致仿造完成了。
一些补充
- 由前图易知,梯度下降算法很有可能只会求出一个局部最小解。
- 算法中的 n 维函数必须是平滑的,这样我们才能每次挪一点挪到最小值。这点带来了神经网络和人脑一个很大的不同:人脑的神经元信号只有高电位和低电位两种,而神经网络节点的激活值是连续的。
- 梯度向量的每一个值均可以理解为对应参数的相对重要性:
- 值得注意的是,每个 n 维坐标均为包含了一个网络中所有的权重与偏置,也就是说,每次向量的改变都是整个网络的同时改变,那么何来反向传播一说?从数学上看确实是向量是整体在变化,但是用之前的节点网络思考很容易发现:越靠后的节点层对代价函数影响越大,更细致的讲,就算是每一层中不同节点的影响大小也是不同的。 因此我们在计算过程中优先处理的总是后部节点。
- beta 计划实际上只对一个样本使用了梯度下降算法,但其实每个样本都对应了一个不同的代价函数,因此每次梯度下降都需要对所有样本分别计算梯度。如果用人类语言形容,单样本梯度下降算法就像一个和尚在找最快的下山化缘路径,而多个样本则像这些和尚同时在找泰山、富士山、阿尔卑斯山、喜马拉雅山的最快下山化缘路径——蛋疼的是,这些和尚每一步还都得步伐一致。因此,对于多个样本我们需要求平均梯度,该平均梯度应当保证:这一步走下去得让所有和尚共同富裕。
- 此外,如果每步下降求梯度时都把几万个样本全用上,那么开销就有点得不偿失了。所以实际操作时往往会把训练样本打乱并分组,把每一个小组当一个整体的单位计算下降的一步。虽然这样不如原方案精确,但是每个小组其实都会产出一个不错的近似。直观地讲,就像把慢悠悠的精准式下山变成飞快的醉汉式下山。
未完待续…