机器学习到底在学啥?一些最小模型实践
胖车库
2024-08-30 00:44
订阅此专栏
收藏此文章

摘要

这是一篇关于机器学习的有趣长文,翻译自 Stephen Wolfram 的《What’s Really Going On in Machine Learning? Some Minimal Models》,阅读原文可以看英文原版。下面是对文章的两则摘要:

From GPT 👾

沃尔夫勒姆解释说,虽然机器学习(尤其是通过神经网络)取得了令人印象深刻的成果,但我们仍然不完全了解 how and why it works。

此篇的核心见解是,机器学习不一定会创建有组织的系统来解决问题;相反,它利用简单计算规则中固有的复杂性,而这些规则通常表现得不可预测。这种随机性和复杂性使得机器学习模型能够以类似于自然进化的方式找到解决方案——通过探索多种可能性并坚持有效的方法,而不是遵循清晰的、合乎逻辑的路径。

这种理解可以通过关注计算的简单性和自然丰富性来更有效的构建和改进机器学习系统,而不是试图设计高度结构化的解决方案。

From Jessie 👀

机器学习科学从生物进化中获得什么启发呢?

和生物进化一样,机器学习的根本目的在于找到可行的方法,不受人类在一步步明确设计事物时强加给我们的“可理解性”约束。

沃尔夫勒姆说,我们基本上只能研究一些计算不可约的过程,并观察到它“恰好起作用”——而且我们不会对“为什么”做出高层次的解释。

机器学习的力量来自于利用计算不可约性的“自然资源”,想象一下一个人在建一堵墙。一种可能性是制作出一种特定形状的砖块,这些砖块知道它们可以拼在一起。但另一种可能性是只看一眼周围散落的石头,然后尽可能将它们拼合在一起来建造这堵墙。

如果有人问“为什么墙上会有这样或那样的图案?”,答案基本上是“因为那是从碰巧散落在周围的石头上得到的”。它本身并没有总体理论;它只是对现有资源的反映。

我之前读过他介绍 GPT 是如何工作的书《GPT 在干啥,为什么它有效?》1,他解释说 GPT 的“任务”就是对文本进行合理的延续,这本身是一个理解问题。而理解是一个非常困难的任务,在文字交流和沟通中,你很难让对方明白你在说什么 -- 你想表达什么,你不明白的是什么,而这有时候也是我们最想知道的。


正文

机器学习的奥秘

关键词

computational neural nets #visualization #computational irreducibility #minimal models

令人惊讶的是,人们对机器学习的基础了解甚少。是的,从工程的角度来看,人们已经弄清楚了大量如何构建神经网络的方法,这些神经网络可以完成各种令人印象深刻甚至几乎神奇的事情。但从根本上讲,我们仍然不知道神经网络为什么“work”——我们对神经网络内部发生的事情没有任何“科学全景”。

神经网络的基本结构相当简单。但当它们训练完成并确定所有权重等后,很难知道发生了什么,甚至无法很好地将其可视化。事实上,甚至连整个设置中哪些方面真正必不可少,哪些方面只是“细节”,可能自 20 世纪 40 年代计算神经网络首次发明以来就一直“沿用”至今,都远未明朗。

好吧,我在这里要做的就是“深入”这个问题,并尽可能地“简化问题”。我将探索一些非常小的模型,除其他外,这些模型更易于可视化。一开始,我完全不确定这些最小模型是否能够重现我们在机器学习中看到的任何事物。但令人惊讶的是,它们似乎可以。

At the outset, I wasn’t at all sure that these minimal models would be able to reproduce any of the kinds of things we see in machine learning. But, rather surprisingly, it seems they can. 一开始,我完全不确定这些最小模型是否能够重现我们在机器学习中看到的任何事物。但令人惊讶的是,它们似乎可以。

而且,它们构造简单,因此更容易“看清内部”——也更容易了解机器学习背后的本质现象。人们可能认为,尽管机器学习系统的训练可能是迂回曲折的,但最终系统还是会通过某种可识别和“可解释”的机制完成它的工作。但我们会发现,事实上通常情况并非如此。

相反,它看起来更像是训练设法集中于一些相当疯狂的计算,而这些计算“恰好取得了正确的结果”。机器学习似乎并没有建立结构化的机制;相反,它基本上只是从计算宇宙中看到的典型复杂性中进行采样,挑选出行为与所需行为重叠的部分。因此,从某种意义上说,机器学习的可能性最终是计算不可约性现象的另一个结果。

这是为什么呢?嗯,正是因为计算不可约性,计算宇宙才如此丰富。更重要的是,正是因为计算不可约性,事物最终才变得足够随机,以至于训练机器学习系统的自适应过程可以取得成功而不会陷入困境。

但是计算不可约性的存在还有另一个重要含义:即使我们可以期望找到有限的计算可约性,我们也不能指望对机器学习系统的功能有一个“一般叙述性解释”。换句话说,机器学习不会有传统的(比如说数学的)“一般科学”(或者,就此而言,也可能有神经科学)。相反,这个故事将更接近我长期以来探索的从根本上计算的“新科学”,它为我们带来了物理项目和规则。

从很多方面来看,机器学习的问题都是自适应进化的一般问题的一种,例如在生物学中遇到的。在生物学中,我们通常想象我们想要自适应地优化系统的整体“适应性”;在机器学习中,我们通常尝试自适应地“训练”系统,使其与某些目标或行为保持一致,这些目标或行为通常由示例定义。(是的,在实践中,这通常是通过尝试最小化通常称为“损失”的数量来实现的。)

In many ways, the problem of machine learning is a version of the general problem of adaptive evolution, as encountered for example in biology. 从很多方面来看,机器学习的问题都是自适应进化的一般问题的一种。

虽然生物学中普遍认为“万物源于进化”,但其具体原理却一直是一个谜。但(令我惊讶的是)我最近发现了一个非常简单的模型,它似乎能够很好地捕捉到生物进化的一些最基本的特征。虽然该模型与我们将在这里探讨的机器学习模型不同,但它们确实有一些相似之处。最后我们会发现,机器学习和生物进化的核心现象似乎非常一致——并且都与计算不可约性现象有着根本的联系。

And in the end we’ll find that the core phenomena of machine learning and of biological evolution appear to be remarkably aligned—and both fundamentally connected to the phenomenon of computational irreducibility. 机器学习和生物进化的核心现象似乎非常一致——并且都与计算不可约性现象有着根本的联系。

我在这里所做的大部分工作都集中在基础理论问题上。但是,通过更多地了解机器学习的真正情况(以及什么是必要的,什么不是必要的),我们还将能够开始看到在实践中机器学习可以如何以不同的方式进行,可能具有更高的效率和更多的通用性。

传统神经网络

关键词

multilayer perceptron #weights #bias #activation function #the loss #randomness

为了开始理解机器学习的本质,让我们从一个非常传统且熟悉的例子开始:一个完全连接的(“多层感知器”)神经网络,它经过训练可以计算某个函数 f [ x ]:

如果在顶部给出一个值 x 作为输入,那么在“经过网络各层”之后,我们会在底部得到一个值,该值(几乎完全)对应于我们的函数 f [ x ]:

扫描不同的输入 x,我们会看到网络内部中间值的不同模式:

以下是(以线性和对数尺度)每个中间值随 x 的变化情况。最终值(此处突出显示)的出现方式看起来非常复杂:

那么神经网络最终是如何组成的呢?我们绘制的这些值是如何确定的?我们使用完全连接的多层网络的标准设置。每一层上的每个节点(“神经元”)都连接到上一层的所有节点 - 并且值从一层“流”到下一层,乘以与它们流经的连接相关的(正或负)“权重”(在图片中用颜色表示)。给定神经元的值是通过将前一层的所有(加权)输入加起来,为该神经元添加一个“偏差”值,然后将结果应用于某个(非线性)“激活函数”(此处为 ReLU 或 Ramp [ z ],即 If [ z < 0, 0, z ])来找到的。

给定神经网络将计算的整体函数由神经网络中出现的权重和偏差集合(以及其整体连接架构和所使用的激活函数)决定。机器学习的理念是通过自适应地从该函数的示例中“学习”来找到产生特定函数的权重和偏差。通常,我们可能从一组随机权重开始,然后连续调整权重和偏差以“训练”神经网络以重现该函数:

The idea of machine learning is to find weights and biases that produce a particular function by adaptively “learning” from examples of that function. 机器学习的理念是通过自适应地从该函数的示例中“学习”来找到产生特定函数的权重和偏差。

通过绘制训练过程中各个权重的连续变化,我们可以了解这一过程是如何进展的(是的,这很复杂)(接近尾声的峰值来自不影响整体行为的“中性变化”):

训练的总体目标是逐步减少“损失” ——f [ x ]的真实值与神经网络生成的值之间的平均(平方)差。损失的演变定义了神经网络的“学习曲线”,向下的故障对应于神经网络实际上“取得突破”的点,能够更好地表示函数:

值得注意的是,神经网络训练通常会注入随机性。因此,如果多次进行训练,每次都会得到不同的网络和不同的学习曲线:

但神经网络训练到底发生了什么?实际上,我们正在寻找一种方法来将一个函数(至少在某种程度上近似)“编译”成具有一定数量(实值)参数的神经网络。在这里的例子中,我们恰好使用了大约 100 个参数。

But what’s really going on in neural net training? Effectively we’re finding a way to “compile” a function (at least to some approximation) into a neural net with a certain number of (real-valued) parameters. 但神经网络训练到底发生了什么?实际上,我们正在寻找一种方法来将一个函数(至少在某种程度上近似)“编译”成具有一定数量(实值)参数的神经网络。

但是如果我们使用不同数量的参数,或者以不同的方式设置神经网络架构,会发生什么情况呢?以下是几个例子,表明对于我们试图生成的函数,我们迄今为止使用的网络几乎是可以工作的最小网络:

顺便说一下,如果我们将激活函数从 ReLU 更改

为更平滑的 ELU ,会发生什么情况

稍后我们将讨论使用离散系统进行机器学习时会发生什么。为此,有趣的是,如果我们采用我们在这里讨论的神经网络,并在离散级别“量化”其权重(和偏差),看看会发生什么:

结果是(正如最近的大规模神经网络的经验所表明的那样),神经网络的基本“操作”不需要精确的实数,但即使数字至少有些离散,它也能继续存在——正如这个作为离散度 δ 函数的 3D 渲染也表明的那样:

简化拓扑:网格神经网络

关键词

mesh neural net

到目前为止,我们一直在讨论非常传统的神经网络。但是要进行机器学习,我们真的需要具有所有这些细节的系统吗?例如,我们真的需要每一层上的每个神经元都从前一层的每个神经元获取输入吗?如果每个神经元最多只从其他两个神经元获取输入,会发生什么情况 - 比如说,神经元有效地布置在一个简单的网格中?令人惊讶的是,事实证明,这样的网络仍然能够完美地生成像我们一直用作示例的函数:

Do we really need systems that have all those details? For example, do we really need every neuron on each layer to get an input from every neuron on the previous layer?我们真的需要每一层上的每个神经元都从前一层的每个神经元获取输入吗?如果每个神经元最多只从其他两个神经元获取输入,会发生什么?

这种“网格神经网络”的一个优点是——就像细胞自动机一样——它的“内部行为”可以很容易地以相当直接的方式可视化。例如,以下是“网格网络如何生成其输出”的可视化,逐步显示不同的输入值 x:

是的,即使我们可以将其可视化,我们仍然很难理解“内部发生了什么”。将网络中每个节点的中间值视为 x 函数并没有多大帮助,尽管我们可以在函数 f [ x ] 发生跳跃的地方“看到一些事情发生” :

那么我们如何训练网格神经网络呢?基本上,我们可以使用与上面看到的全连接网络相同的程序(ReLU 激活函数似乎不适用于网格网络,因此我们在这里使用 ELU):

以下是训练过程中每个权重差异的演变情况:

以下是不同随机种子的结果:

在我们所使用的(网格神经网络)规模下,我们的网格神经网络具有与上述全连接网络主要示例大致相同的连接数(因此权重也相同)。我们发现,如果我们尝试减小网格神经网络的规模,它就无法很好地重现我们的函数:

让一切离散化:生物进化的模拟

关键词

discrete #single-point mutation #model of adaptive evolution

网格神经网络简化了神经网络连接的拓扑结构。但一开始有些令人惊讶的是,我们似乎可以更进一步简化我们正在使用的系统,并且仍然可以成功进行机器学习。特别是,我们会发现我们可以使我们的系统完全离散。

神经网络训练的典型方法涉及逐步调整实值参数,通常使用基于微积分的方法,并求导。人们可以想象,任何成功的自适应过程最终都必须依赖于能够进行任意微小的更改,这种更改是使用实值参数可以实现的。

但在研究生物进化的简单理想化时,我最近发现了一些惊人的例子,事实并非如此——完全离散的系统似乎能够捕捉到正在发生的事情的本质。

where completely discrete systems seemed able to capture the essence of what’s going on. 完全离散的系统似乎能够捕捉到正在发生的事情的本质。

以 (3 色 ) 细胞自动机为例。规则显示在左侧,通过重复应用该规则 ( 从单细胞初始条件开始 ) 生成的行为显示在右侧:

该规则具有以下特性:它生成的模式(从单细胞初始条件)可以存活 40 步,然后消失(即每个细胞都变成白色)。而重点是,可以通过离散自适应过程找到此规则。其想法是从一个空规则开始,然后在每一步随机更改规则中 27 个结果中的一个结果(即在规则中进行“单点突变”)。大多数此类更改将导致模式的“寿命”远离我们的目标 40 — — 我们会丢弃这些更改。但我们可以逐渐积累“有益突变”

通过“逐步适应”,最终实现我们最初的 40 岁寿命规则:

我们可以绘制一张图,记录我们所做的所有尝试,这些尝试最终让我们活到了 40 岁——我们可以将这条渐进的“适应度”曲线看作是我们之前看到的机器学习中的损失曲线:

如果我们做出不同的随机突变序列,我们将得到不同的适应性进化路径,以及生命周期为 40 的规则的不同“解决方案”:

有两点立即引人注目。首先,它们基本上似乎都在“使用不同的想法”来实现目标(可能类似于生命之树中不同分支的现象)。其次,它们似乎都没有使用明确的“机械程序”(我们可以通过传统工程构建的那种)来实现目标。相反,它们似乎正在寻找“自然的”复杂行为,这些行为恰好“恰好”实现了目标。

First, that they essentially all seem to be “using different ideas” to reach their goal (presumably analogous to the phenomenon of different branches in the tree of life). And second, that none of them seem to be using a clear “mechanical procedure” (of the kind we might construct through traditional engineering) to reach their goal. 首先,它们基本上似乎都在“使用不同的想法”来实现目标(可能类似于生命之树中不同分支的现象)。其次,它们似乎都没有使用明确的“机械程序”(我们可以通过传统工程构建的那种)来实现目标。

当然,这种行为能够实现我们在此设定的目标,并且基于随机点突变的简单选择能够成功实现必要的行为,这并非易事。但正如我在生物进化中讨论的那样,这最终是一个计算不可约性的故事——特别是在行为和实现行为所需路径的多样性方面。

How does this model of adaptive evolution relate to systems like neural nets?这种自适应进化模型与神经网络等系统有何关系呢?... But it turns out that—essentially as a consequence of computational irreducibility—the very simple method of successive random mutation can be successful. 但事实证明,本质上由于计算不可约性,非常简单的连续随机突变方法可以成功。

但是,那么,这种自适应进化模型与神经网络等系统有何关系呢?在神经网络的标准语言中,我们的模型就像循环卷积网络的离散模拟。它之所以是“卷积的”,是因为在任何给定步骤中,相同的规则都会在元素数组的局部范围内应用。它之所以是“循环的”,是因为实际上数据会反复“通过”相同的规则。通常用于训练传统神经网络的程序(如“反向传播”)无法训练这样的系统。但事实证明,本质上由于计算不可约性,非常简单的连续随机突变方法可以成功。

离散规则阵列中的机器学习

关键词

rule array #single-point mutation #model of adaptive evolution #random mutations #basin of attraction

假设我们想要建立一个类似神经网络的系统,或者至少是一个网格神经网络,但我们希望它是完全离散的。(我的意思是“天生离散”,而不仅仅是从现有的连续系统中离散化。)我们该怎么做呢?一种方法(碰巧,我在 20 世纪 80 年代中期首次考虑过,但从未认真探索过)是制作我们所谓的“规则阵列”。就像在细胞自动机中有一个细胞阵列。但这些细胞并非总是根据相同的规则进行更新,在细胞自动机模拟的“时空”中,每个位置的每个细胞都可以选择不同的规则。(尽管这是一个相当极端的理想化,但我们可以想象这些不同的规则代表了网格神经网络中不同局部权重选择的离散模拟。)

作为第一个例子,让我们考虑一个规则数组,其中有两种可能的规则选择:k = 2,r = 1 元 胞自动机规则 4 和 146(分别是类 2 和类 3):

特定规则数组由这些规则中的哪一个将用于数组中的每个(“时空”)位置来定义。以下是几个示例。在所有情况下,我们都从相同的单细胞初始条件开始。但在每种情况下,规则数组都有不同的规则选择排列——“运行”规则 4 的细胞被赋予背景,而运行规则 146 的细胞被赋予背景:

我们可以看到,不同的规则数组选择会产生非常不同的行为。但是(本着机器学习的精神)我们能否有效地“反转这一点”,并找到一个可以产生我们想要的某些特定行为的规则数组?

一种简单的方法是直接模拟我们在生物进化的最小模型中所做的事情:逐步进行随机的“单点突变” - 这里“翻转”规则数组中仅一个规则的身份 - 然后只保留那些不会使情况变得更糟的突变。

作为我们的示例目标,我们要求找到一个规则数组,使使用该规则数组从单个单元格生成的模式“存活”恰好 50 步。起初,我们可能不太清楚我们能够找到这样的规则数组。但事实上,我们的简单自适应程序很容易做到这一点:

正如这里的点所示,许多突变并不会导致更长的寿命。但偶尔,适应性过程会有一个“突破”,延长寿命——最终达到 50 岁:

正如我们的生物进化模型一样,不同的随机突变序列会导致不同的“解决方案”,这里的问题是“活出恰好 50 ”:

其中一些实际上是“简单的解决方案”,只需要一些突变。但大多数——就像我们在生物进化中看到的大多数例子一样——似乎只是“碰巧奏效”,通过利用恰当的、相当复杂的行为来有效地发挥作用。

这些情况之间有明显的区别吗?看看上面例子的“适应度”(又称“学习”)曲线集合,似乎没有:

不难看出如何“构建一个简单的解决方案”,只需在规则数组中策略性地放置第二条规则的单个实例即可:

但关键在于,通过重复突变实现的适应性进化通常不会“发现”这种简单的解决方案。而重要的是,适应性进化仍然可以成功找到某种解决方案——即使它不是这种“可理解”的解决方案。

到目前为止,我们使用的细胞自动机规则需要 3 个输入。但事实证明,我们可以通过将普通的 2 输入布尔函数放入规则数组中来使事情变得更简单。例如,我们可以从 And 和 Xor 函数(r = 1/2 规则 8 和 6 )创建一个规则数组:

不同的 And + Xor ( + ) 规则数组表现出不同的行为:

但是,是否存在例如 And + Xor 规则数组,可以计算 16 个可能的(2 输入)函数中的任何一个?我们无法使用 — 获得 Not 或任何其他 8 个函数,但事实证明,我们可以使用 — 获得所有 8 个函数(此处假设其他输入为):

事实上,我们还可以为所有其他“偶数”布尔函数设置 And + Xor 规则数组。例如,以下是 3 输入规则 30 和规则 110 布尔函数的规则数组:

值得一提的是,设置此类规则数组的能力与我们正在使用的底层规则的功能完整性有关 - 尽管它们并不完全相同。功能完整性是关于设置任意公式,实际上可以允许中间结果之间的长距离连接。在这里,所有信息都必须明确地流经数组。但是例如 Nand ( r = 1/2 规则 7,)的功能完整性允许它在与 First(r = 1/2 规则 12,)结合时生成所有布尔函数,尽管有时所需的规则数组非常大:

好的,但是如果我们尝试使用自适应进化过程,比如解决寻找一个可以存活 30 步的模式的问题,会发生什么?以下是 And + Xor 规则数组的结果:

这里还有其他“解决方案”的例子(在这种情况下,没有一个看起来特别“机械”或“构造”):

但是如何学习原始的 f [ x ] =函数呢?首先,我们必须决定如何在离散规则数组系统中表示数字 x 和 f [ x ]。一种方法是简单地根据黑色单元格的位置(“独热编码”)来表示。例如,在这种情况下,在对应于大约 x = –1.1 的位置处有一个初始黑色单元格。然后,经过规则数组后,结果就是在对应于 f [ x ] = 1.0 的位置处有一个黑色单元格:

所以现在的问题是,我们能否找到一个规则数组,根据我们想要的映射 x f [ x ] 成功地将初始单元格位置映射到最终单元格位置。好吧,这里有一个至少接近这样做的例子(请注意,数组被视为循环的):

那么我们是如何发现这一点的呢?我们只是使用了一个简单的自适应进化过程。与机器学习中通常的做法直接类似,我们设置了“训练示例”,形式如下:

然后,我们反复在规则数组中进行单点突变,保留那些与所有训练示例的总差异没有增加的突变。经过 50,000 次突变后,这得到了上述最终结果。

通过展示我们接近目标的中间结果序列(而不是仅仅远离目标),我们可以了解“我们是如何到达那里的”:

以下是相应的规则数组,在每种情况下都突出显示了已更改的元素(并显示数组中 f [0]的计算):

不同的随机突变序列将导致不同的规则数组。但使用此处定义的设置,生成的规则数组几乎总能成功准确计算 f [ x ]。以下是几个示例 - 我们特别展示了 f [0 ] 的计算:

再次强调,一个重要的结论是,我们没有在发生的事情中看到“可识别的机制”。相反,看起来更像是我们得到的规则数组“恰好”做了我们想要的计算。它们的行为很复杂,但不知何故,我们可以设法“利用它”来计算我们的 f [ x ]。

但这种计算有多可靠?典型机器学习的一个关键特征是它可以从给出的具体示例中“概括”。如何描述这种概括一直不清楚(什么时候猫穿着狗装的图像开始被识别为狗的图像?)。但是——至少当我们谈论分类任务时——我们可以从吸引域的角度来思考正在发生的事情,这些吸引域会引导我们找到与我们的类别相对应的吸引子。

A key feature of typical machine learning is that it can “generalize” away from the specific examples it’s been given. It’s never been clear just how to characterize that generalization (when does an image of a cat in a dog suit start being identified as an image of a dog?). 典型机器学习的一个关键特征是它可以从给出的具体示例中“概括”。如何描述这种概括一直不清楚(什么时候猫穿着狗装的图像开始被识别为狗的图像?)

不过,在我们这里探索的这种离散系统中,分析起来要容易得多。例如,我们可以轻松地枚举所有训练输入(即所有包含单个黑色细胞的初始状态),然后查看这些输入导致任何给定细胞变黑的频率:

顺便说一下,以下是在训练过程中连续“突破”时该图发生的情况:

但是,如果输入中包括不只包含一个黑色单元格的输入,该怎么办呢?好吧,我们可以枚举所有输入,并计算数组中每个单元格为黑色的总体频率:

正如我们所料,结果比我们仅使用训练输入得到的结果“模糊”得多。但训练数据中出现的 f [ x ] 离散值仍然很明显。如果我们绘制给定最终单元格为黑色的总体概率,我们会看到 f [ x ]取值为 0 和 1 的位置出现峰值:

但由于我们的系统是离散的,我们可以明确地看到会发生什么结果:

总体而言,最常见的是“毫无意义”的全白状态——这基本上发生在从输入到输出的计算“永远无法完成”时。但第二常见的结果恰好对应于 f [ x ] = 0 和 f [ x ] = 1。再接下来是“叠加”结果,其中 f [ x ] 实际上是“0 和 1”。

但是,好吧,那么这里的各种结果“处于吸引盆地中”(即会演化成)的初始状态是什么呢?上面最后一栏中相当平坦的图表明,黑色细胞的整体密度几乎不能说明某个特定初始状态会演化成什么吸引子。

因此,这意味着我们必须研究初始条件下细胞的具体配置。例如,从初始条件开始

演变为:

现在我们可以问一下,如果我们观察一系列略有不同的初始条件,会发生什么。这里我们用黑白两色表示初始条件仍然会演变为原始的“吸引子”状态,用粉色表示演变为某种不同状态:

这里面到底发生了什么?下面是几个例子,突出显示了由于初始条件改变而值发生变化的单元格:

正如机器学习中的典型情况一样,似乎没有任何简单的特征来描述吸引盆(basin of attraction)的形式。但现在我们知道了原因是什么:这是计算不可约性的另一个结果。计算不可约性为我们提供了有效的随机性,使我们能够通过自适应进化找到有用的结果,但它也会导致变化产生看似随机和不可预测的影响。(顺便说一句,值得注意的是,我们可以通过专门包括注入了“噪音”的训练数据示例来显著提高吸引盆的稳健性。)

多路变异图

关键词

multiway graph #single-point mutation

在实践中进行机器学习时,目标通常是找到一些权重集合等,以成功解决特定问题。但一般会有许多这样的权重集合等。对于典型的连续权重和随机训练步骤,很难看出可能性的整个“集合”。但在我们的离散规则阵列系统中,这变得更加可行。

考虑一个只有两条可能规则的 2×2 规则数组。我们可以制作一个图,其边表示此规则数组中可能发生的所有可能的“点突变”:

在我们的自适应进化过程中,我们总是围绕这样的图表移动。但通常大多数“移动”最终都会进入被拒绝的状态,因为它们会增加我们定义的损失。

考虑生成 And + Xor 规则数组的问题,其中我们以生命周期为 4 的模式结束。将损失定义为我们距离这个生命周期有多远,我们可以绘制一个图表,显示所有可能的自适应进化路径,这些路径总是逐步减少损失:

其结果是一种多向图,我们现在已经在许多情况下看到了这种类型的图——尤其是我们最近对生物进化的研究。

尽管这个特定示例非常简单,但总体思路是,这种图的不同部分代表解决问题的“不同策略”。与我们的物理项目和游戏图等研究直接类似,我们可以想象这些策略被布置在由多路图中配置的共同祖先定义的“分支空间”中。

可以预料的是,在某些情况下,分支图会相当统一,但在其他情况下,分支图会有很多分离的部分,代表完全不同的策略。当然,底层策略可能不同并不意味着系统的整体行为或性能会有明显差异。事实上,在大多数情况下,计算不可约性将导致足够的有效随机性,以至于不会出现可辨别的差异。

但无论如何,这里有一个从包含 And 和 Xor 的规则数组开始的示例 - 我们观察到自适应进化的不同分支,这些分支导致找到生命周期恰好为 4 的配置的问题的不同解决方案:

优化学习过程

关键词

plateaus #path of steepest descent

机器学习中应该如何进行学习?在传统神经网络的实际工作中,学习通常使用反向传播等系统算法方法进行。但到目前为止,我们所做的一切都是简单得多的事情:我们通过连续进行随机点突变并仅保留那些不会让我们远离目标的突变来“学习”。是的,有趣的是,这样的程序可以起作用 - 而且(正如我们在其他地方讨论过的)这可能与理解生物进化等现象非常相关。但是,正如我们将看到的,即使对于我们正在研究的离散系统,也有更有效(可能更有效)的机器学习方法。

How should one actually do the learning in machine learning? In practical work with traditional neural nets, learning is normally done using systematic algorithmic methods like backpropagation. But so far, all we’ve done here is something much simpler: we’ve “learned” by successively making random point mutations, and keeping only ones that don’t lead us further from our goal. 机器学习中应该如何进行学习?在传统神经网络的实际工作中,学习通常使用反向传播等系统算法方法进行。但到目前为止,我们所做的一切都是简单得多的事情:我们通过连续进行随机点突变并仅保留那些不会让我们远离目标的突变来“学习”。

让我们先回顾一下之前的例子,即找到一个 And + Xor 规则数组,该数组的“生命周期”正好是 30。在我们的自适应(“学习”)过程的每一步,我们都会进行单点突变(更改规则数组中的单个规则),如果它不会让我们离目标更远,就保留该突变。突变逐渐积累——每隔一段时间就会达到一个规则数组,使生命周期更接近 30。就像上面一样,这是通过连续突变实现的生命周期的图——其中“内部”红点对应于被拒绝的突变:

我们看到一系列“平台期”,突变在这些平台期不断积累,但不会改变整体寿命。在这些平台期之间,我们偶尔会看到“突破”,寿命会突然增加。以下是这些突破的实际规则数组配置,其中突出显示了自上次突破以来的突变:

但最终,这里的过程是相当浪费的;在这个例子中,我们总共进行了 1705 次变异,但其中只有 780 次真正有助于生成最终的规则数组;所有其他的都被丢弃了。

那么我们如何才能做得更好呢?一种策略是尝试在每一步中找出哪种突变“最有可能产生影响”。而实现此目的的一种方法是依次在每一步中尝试每种可能的突变(如多向进化)——并查看每种突变对最终寿命的影响。由此我们可以构建一个“变化图”,其中我们给出与每个特定细胞的突变相关的寿命变化。对于规则数组的每种配置,即在自适应进化的每一步,结果都会不同。但例如,对于上面显示的特定“突破”配置,结果如下(灰色区域中的元素如果发生变化,不会影响结果;红色区域将产生积极影响(红色越深表示越积极),蓝色区域将产生消极影响):

假设我们从随机规则数组开始,然后反复构建变化图并应用它所暗示的突变,从而产生最积极的变化——实际上,每一步都遵循“最陡下降路径”以达到我们想要的寿命(即减少损失)。那么我们得到的“突破”配置序列是:

实际上,这比我们的纯单点突变序列对应于稍微更直接的“解决方案路径”。

顺便说一句,达到一定寿命的特定问题具有足够简单的结构,以至于这种“最速下降”方法 - 从一个简单的统一规则数组开始时 - 找到一条非常“机械”(如果很慢)的解决方案路径:

那么学习 f [ x ] =的问题呢?我们再次可以根据我们定义的损失绘制变化图。以下是一系列“突破性”配置的结果。灰色区域是变化“中性”的区域,因此仍然可以进行探索而不会影响损失。红色区域实际上是“锁定”的区域,任何变化都会对损失产生不利影响:

那么,如果我们遵循“最陡下降路径”,始终根据变化图做出最佳更改,会发生什么情况?结果实际上非常不令人满意。从几乎任何初始条件开始,系统都会很快陷入困境,并且永远找不到任何令人满意的解决方案。实际上,似乎确定地遵循最陡下降路径会将我们引向无法逃脱的“局部最小值”。那么,如果只看变化图,我们会错过什么?我们构建的变化图有一个局限性,即它会分别评估每个可能的个体突变的影响。它不能同时处理多个突变——如果要找到“最快的成功路径”并避免陷入困境,这通常是必需的。

但即使在构建变化图时也已经存在问题。因为至少直接计算它的方式扩展性很差。在 n × n 规则数组中,我们必须检查翻转约 n2 个值的效果,并且对于每个值,我们必须运行整个系统——总共需要约 n4 次操作。并且必须对学习过程的每个步骤分别执行此操作。

那么传统神经网络如何避免这种低效率呢?答案在某种意义上涉及数学技巧。至少在通常情况下,它完全基于神经网络中权重和值的连续性——这使我们能够使用微积分方法。

假设我们有一个这样的神经网络

计算某个特定函数 f [ x ]:

我们可以问一下,当我们改变网络中的每个权重时,这个函数如何变化:

实际上,这给了我们类似上面的“变化图”的东西。但有一个重要的区别。因为权重是连续的,我们可以考虑对它们进行无穷小的改变。然后我们可以问这样的问题:“当我们对某个权重 w i 进行无穷小的改变时, f [ x ] 如何变化?”——或者等价地,“在点 x 处, f 对 w i 的偏导数是多少?”但现在我们可以使用无穷小变化的一个关键特征:它们总是可以被认为是“线性相加”(本质上是因为 ε 2 总是可以忽略不计)。或者换句话说,我们可以通过给出权重空间中的“方向”来总结任何无穷小的变化,即一个向量,表示每个权重应该(无穷小)改变多少。所以如果我们想尽快改变 f [ x ](无穷小),我们应该沿着由 f 对权重的所有导数定义的最陡下降方向前进。

在机器学习中,我们通常会尝试设置权重,以便我们生成的 f [ x ]的形式能够成功最小化我们定义的损失。我们通过逐步“在权重空间中移动”来实现这一点——每一步都计算最陡下降的方向以了解下一步该去哪里。(在实践中,有各种各样的技巧,如“ADAM”,试图优化实现这一目标的方式。)

但是,我们如何高效地计算 f 对每个权重的偏导数呢?是的,我们可以对每个权重分别生成类似上述的。但事实证明,微积分的一个标准结果为我们提供了一个效率高得多的程序,实际上可以“最大限度地重复使用”已经完成的计算部分。

一切都始于嵌套(即组合)函数导数的教科书链式法则:

这基本上表明,“整个链” d [ c [ b [ a [ x ]]]] 的值的(无穷小)变化可以计算为与链中每个“环节”相关的(无穷小)变化的乘积。但关键的观察是,当我们计算链中某个点的变化时,我们已经必须进行大量所需的计算 - 只要我们存储了这些结果,我们就始终只需执行增量计算。

那么这如何应用于神经网络呢?神经网络中的每一层实际上都在进行函数组合。例如,我们的 d [ c [ b [ a [ x ]]]] 就像一个简单的神经网络:

但是权重呢?毕竟,我们想要找到改变权重的效果。好吧,我们可以将它们明确地包含在我们正在计算的函数中:

然后我们原则上可以符号式地计算这些权重的导数:

对于我们上面的网络

相应的表达式(忽略偏差)是

其中 φ 表示我们的激活函数。我们再次处理嵌套函数,并且再次——尽管在这种情况下它有点复杂——可以通过逐步评估链式法则中的项来计算导数,实际上使用标准的神经网络方法“反向传播”。

那么离散情况呢?我们可以使用类似的方法吗?我们不会在这里详细讨论这个问题,但我们会给出一些可能涉及的内容的提示。

作为一个可能更简单的案例,我们来考虑普通的细胞自动机。我们的变化图的类似物询问特定“输出”细胞的值如何受到其他细胞变化的影响——或者实际上是输出值的“偏导数”相对于其他细胞值的变化是多少。

例如,考虑此细胞自动机演化中突出显示的“输出”细胞:


现在我们可以查看此数组中的每个单元格,并根据翻转该单元格的值(然后从该点向前运行细胞自动机)是否会改变输出单元格的值来制作更改图:

如果我们查看不同的“输出单元”,变化图的形式会有所不同:

顺便说一下,这里有一些更大的变化图,以及其他一些细胞自动机规则:

但有没有办法逐步构建这样的变化图?有人可能会认为,至少对于细胞自动机来说,(与这里的情况不同)基本上是可逆的。但实际上这种可逆性似乎没有多大帮助——因为虽然它允许我们“回溯”细胞自动机的整个状态,但它不允许我们追踪单个细胞的单独影响。

那么如何使用离散的导数模拟和链式法则呢?例如,我们将规则 30 中一步计算出的函数称为细胞自动机演化 w [ x , y , z ]。我们可以将此函数在点 x 处关于 x 的“偏导数”视为表示当 x 从给定值开始翻转时, w 的输出是否发生变化:

(请注意,“没有变化”表示为 False 或,而变化表示为 True 或。是的,可以在这里明确计算规则结果,然后从中推导出函数形式,或者可以使用符号规则直接推导出函数形式。)

可以计算任意布尔函数的导数的离散模拟。例如,我们有

我们可以将其写成:

我们还有:

下面是所有 2 输入布尔函数的“布尔导数”表:

事实上,有一整套“布尔微积分”可以用于计算这些类型的导数。特别是,有一个直接类似于链式法则的公式:

其中 Xnor [x,y]实际上是相等性测试 x == y:

但是,好吧,我们如何使用它来创建变化图?在我们简单的细胞自动机案例中,我们可以将变化图视为表示输出单元的变化如何“传播回”到先前的单元。但是,如果我们只是尝试应用离散微积分规则,我们会遇到一个问题:不同的“链式规则链”可能意味着同一单元值的不同变化。在连续情况下,由于无穷小的工作方式,这种路径依赖不会发生。但在离散情况下确实如此。最终,我们正在进行一种回溯,它只能作为多路系统才能真正忠实地表示出来。(尽管如果我们只想要概率,例如,我们可以考虑对多路系统的分支取平均值——我们上面展示的变化图实际上是对多路系统进行阈值处理的结果。)

但是,尽管在“简单”细胞自动机情况下出现了这样的困难,但这些方法在我们最初更复杂的规则数组情况下似乎效果更好。我们不仅要根据规则数组中的值来寻找导数,还要根据规则的选择(这类似于连续情况下的权重)来寻找导数,这其中有很多微妙之处。

让我们考虑一下 And + Xor 规则数组:

我们的损失是其值与底部显示的行不一致的单元格的数量。现在,我们可以使用离散导数方法以直接“向前”和“向后”的方式为该规则数组构建一个变化图(我们通过始终选择“多数”值来有效地解决少量“多向行为”):

虽然结果并不完全相同,但结果类似。以下是其他几个示例:

是的,从细节上看,前向方法和后向方法的结果本质上总是存在局部差异。但后向方法(如普通神经网络中的反向传播)可以更有效地实现。对于实际的机器学习而言,它实际上可能完全令人满意——尤其是考虑到前向方法本身只是为哪种突变最好这个问题提供了近似值。

举个例子,对于上面展示的“突破性”配置,以下是学习函数 f [ x ]=问题的前向和后向方法的结果:

我们能学到什么?

关键词

piecewise linear function

我们已经展示了不少机器学习的应用实例。但我们尚未解决的一个基本问题是,机器学习究竟能学到什么。在讨论这个问题之前,还有一个问题:给定一个特定的底层系统,它能表示哪些类型的函数?

作为第一个例子,考虑以下形式的最小神经网络(本质上是单层感知器):

以 ReLU (又称 Ramp)作为激活函数,且第一组权重均取 1,此类神经网络计算出的函数形式如下:

有了足够的权重和偏差,这种形式可以表示任何分段线性函数——本质上只是通过使用偏差移动斜坡,并使用权重缩放它们。例如考虑以下函数:

这是由上述神经网络计算出的函数——它是如何通过添加与各个中间节点(神经元)相关的连续斜坡来构建的:

(同样可以从 ELU 等激活函数中获取所有平滑函数。)

如果我们尝试用多个参数来表示函数,事情会变得稍微复杂一些。使用单个中间层,我们只能获得“分段(超)平面”函数(即仅在线性“断层线”处改变方向的函数):

但是,由于已经有了总共两个中间层,并且每个层中都有足够多的节点,我们可以生成任意数量参数的分段函数。

如果我们限制节点的数量,那么我们粗略地限制了函数值中不同线性区域之间的边界数量。但是,随着我们增加具有给定节点数量的层数,我们基本上增加了函数值内多边形区域可以具有的边数:

那么我们之前讨论的网格网络会发生什么情况呢?以下是一些随机示例,结果与具有可比节点总数的浅层全连接网络非常相似:

好的,那么我们的完全离散规则数组怎么样?它们可以表示什么函数?当我们生成规则数组来表示各种布尔函数时,我们已经看到了部分答案。事实证明,有一个基于布尔可满足性的相当有效的程序可以明确找到可以表示给定函数的规则数组 - 或者确定没有规则数组(例如给定大小的规则数组)可以做到这一点。

使用此过程,我们可以找到代表所有(“偶数”)3 输入布尔函数(即 r = 1 细胞自动机规则)的最小 And + Xor 规则数组:

总是可以通过 2n 位的数组指定任何 n 输入布尔函数,如下所示:

但是从上图我们可以看出,当我们将布尔函数“编译”成 And + Xor 规则数组时,它们可以采用不同的位数(即规则数组中元素的数量不同)。(实际上,函数的“算法信息内容”因我们用来表示它们的“语言”而异。)例如,在此处显示的 n = 3 的情况下,最小规则数组大小的分布为:

有些函数很难用 And + Xor 规则数组来表示(似乎需要 15 个规则元素),而有些函数则比较容易。这类似于我们将布尔函数表示为布尔表达式(例如以合取范式)并计算所使用的(一元和二元)运算总数时发生的情况:

好的,所以我们知道原则上存在一个 And + Xor 规则数组,它可以计算任何(偶数)布尔函数。但现在我们可以问,自适应进化过程是否真的可以找到这样的规则数组——比如说,通过一系列单点突变。好吧,如果我们进行这样的自适应进化——损失计算规则 254 的“错误输出”数量——那么可以产生一系列连续的突破配置:

结果不如上述最小解决方案那么紧凑。但似乎总是有可能找到至少一些 And + Xor 规则阵列来“解决问题”,只需使用单点突变的自适应进化即可。

以下是一些其他布尔函数的结果:

因此,是的,不仅所有(偶数)布尔函数都可以用 And + Xor 规则数组来表示,而且它们还可以通过这种形式进行学习,只需通过单点突变的自适应进化即可。

在上面我们所做的工作中,我们研究了机器学习在特定情况下(例如函数)如何使用规则数组。但现在我们有一个案例,我们可以明确列举所有可能的函数,至少是给定类的函数。从某种意义上说,我们看到的证据表明,机器学习往往非常广泛——并且至少在原则上能够学习几乎任何函数。

当然,可能会有特定的限制。例如,我们在这里使用的 And + Xor 规则数组不能表示 的(“奇数”)函数。(我们上面讨论的 Nand + First 规则数组却可以。)但总的来说,这似乎反映了计算等价原理,即几乎任何设置都能够表示任何函数,并且还可以自适应地“学习”它。

顺便说一句,当处理离散(可数)函数时,讨论表示或学习“任何函数”的问题要容易得多——因为人们可以期望能够“精确地得到”给定的函数,或者不能。但对于连续函数,情况会更复杂,因为人们几乎不可避免地要处理近似值(除非可以使用符号形式,而符号形式基本上是离散的)。因此,例如,虽然我们可以说(如上所述)(ReLU) 神经网络可以表示任何分段线性函数,但一般来说,我们只能想象连续接近任意函数,就像在简单的傅里叶级数中逐步添加更多项一样:

回顾离散规则数组的结果,一个值得注意的观察是,虽然我们可以成功重现所有这些不同的布尔函数,但实现这一点的实际规则数组配置往往看起来相当混乱。事实上,它与我们在整个过程中看到的非常相似:机器学习可以找到解决方案,但它们不是“结构化解决方案”;它们实际上只是“碰巧有效”的解决方案。

是否有更结构化的方式用规则数组来表示布尔函数?以下是代表规则 30 的两个可能的最小大小 And + Xor 规则数组:

在下一个更大的尺寸下,规则 30 的可能性更多:

另外还有可以表示规则 110 的规则数组:

但在所有这些情况下,都没有明显的结构让我们立即看到这些计算是如何进行的,或者正在计算什么函数。但是,如果我们尝试通过标准工程方法显式地构建一个计算特定函数的规则数组,会怎么样呢?我们可以从获取规则 30 的函数开始,并用 And 和 Xor 的形式(即 ANF 或“代数范式”)编写它:

我们可以想象使用“评估图”来实现这一点:

但是现在很容易将其转变为规则数组(是的,我们还没有完全完成并安排复制输入等):

针对不同的输入“评估”此规则数组,我们可以看到它确实给出了规则 30:

对规则 110 执行同样操作,And + Xor 表达式为

评估图是

规则数组为:

至少,以评估图为指导,我们可以很容易地“看到这里发生了什么”。但我们使用的规则数组比上面的最小解决方案大得多,甚至比我们通过自适应进化找到的解决方案大得多。

这是在许多其他类型的系统中看到的典型情况(例如排序网络):有可能有一个具有清晰结构和规律性并且“可理解”的“构造解决方案”。但最小解决方案(或通过自适应进化找到的解决方案)往往要小得多。但它们几乎总是在很多方面看起来是随机的,并且不容易理解或解释。

到目前为止,我们一直在研究计算特定函数的规则数组。但要了解规则数组可以做什么,我们可以考虑“可编程”的规则数组,因为它们的输入指定它们应该计算什么函数。例如,这里有一个 And + Xor 规则数组(由自适应进化发现),它将任何(偶数)布尔函数的“位模式”作为左侧的输入,然后将该布尔函数应用于右侧的输入:

使用相同的规则数组,我们现在可以计算任何可能的(偶数)布尔函数。例如,这里它正在评估 Or:

其他类型的模型和设置

关键词

sequence continuation

我们的主要目标是建立能够捕捉神经网络和机器学习最基本特征的模型,但这些模型的结构足够简单,我们可以轻松“查看内部”并了解它们在做什么。我们主要关注规则数组,以此提供标准“感知器式”前馈神经网络的最小模拟。但是其他架构和设置呢?

实际上,我们的规则数组是细胞自动机的“时空非齐次”概括——其中自适应进化决定在每个(空间)位置和每个(时间)步骤应该使用哪个规则(比如来自有限集合)。另一种理想化(事实上我们已经在上面的一节中使用过)是拥有一个普通的齐次细胞自动机——但只有一个由自适应进化决定的“全局规则”。规则数组类似于前馈网络,其中规则数组中的给定规则实际上只在数据“流经”系统时使用一次。普通的齐次细胞自动机就像循环网络,其中单个数据流实际上会一遍又一遍地遵循相同的规则。

这些情况之间存在各种插值。例如,我们可以想象一个“分层规则阵列”,其中不同步骤的规则可以不同,但给定步骤上的规则都是相同的。这样的系统可以看作是卷积神经网络的理想化,其中给定层将相同的内核应用于所有位置的元素,但不同的层可以应用不同的内核。

分层规则数组无法像通用规则数组那样编码那么多信息。但它仍然能够显示机器学习式的现象。例如,这是分层 And + Xor 规则数组的自适应进化,逐步解决生成一个只存在 30 步的模式的问题:

也可以想象“垂直分层”的规则阵列,其中不同的规则用于不同的位置,但任何给定的位置都会永远运行相同的规则。然而,至少对于我们在这里考虑的问题类型而言,仅仅能够选择运行不同规则的位置似乎还不够。似乎要么需要在不同的(时间)步骤中更改规则,要么需要能够自适应地发展底层规则本身。

规则数组和普通细胞自动机具有共同的特征,即每个细胞的值仅取决于前一步相邻细胞的值。但在神经网络中,给定节点的值取决于前一层的许多节点的值是标准做法。在神经网络中,这一点很简单,因为来自先前节点的值(加权,也可能经过其他变换)只需通过简单的数值加法即可组合 - 并且加法(n 元且具有结合性)可以接受任意数量的“输入”。然而,在细胞自动机(或布尔函数)中,输入的数量始终是确定的,由函数的结构决定。在最简单的情况下,输入仅来自最近相邻的细胞。但并不要求事情必须这样运作 - 例如,我们可以选择任何“本地模板”来引入函数的输入。这个模板可以在每个位置和每个步骤上都是相同的,也可以在不同位置从某个集合中以不同的方式挑选出来——实际上给了我们“模板数组”以及规则数组。

那么,如果像我们在上面的第一个神经网络示例中那样拥有一个完全连接的网络,会怎么样呢?要建立这种离散模拟,我们首先需要某种离散的 n 元关联“累加器”函数来填补数值加法的位置。为此,我们可以选择一个像 And、Or、Xor 或 Majority 这样的函数 。如果我们不打算在给定层的每个节点上都得到相同的值,我们需要设置与每个连接相关的权重的某种模拟——我们可以通过对流经每个连接的值应用 Identity 或 Not(即翻转或不翻转)来实现。

下面是此类网络的示例,经过训练可以计算我们上面讨论的函数:

这里只有两种连接:翻转和非翻转。在每个节点上,我们都在计算多数函数——如果其输入的多数为 1,则给出值 1,否则给出值 0。借助我们之前使用的输入和输出的“独热编码”,以下是该网络如何评估我们的函数的几个示例:

这是仅使用应用于连接类型的 1000 步单点突变进行训练的。损失系统地下降——但即使实现了零损失(即即使在完全学习该函数之后),连接类型的配置仍然看起来相当随机:

在我们刚刚所做的操作中,我们假设所有连接都继续存在,尽管它们的类型(或有效符号)可能会发生变化。但我们也可以考虑一个网络,其中连接最终可能会在训练期间被清零 - 因此它们实际上不再存在。

我们在这里用机器学习所做的大部分工作都集中在尝试学习 x f [ x ] 形式的变换。但机器学习的另一个典型应用是自动编码——或者实际上是学习如何压缩代表特定示例集的数据。同样,可以使用规则数组完成这样的任务,通过一系列单点突变实现学习。

首先,考虑训练一个规则数组(由细胞自动机规则 4 和 146 组成)来重现任意宽度的黑色细胞块,而不改变其形状。有人可能认为这很简单。但事实并非如此,因为实际上,初始数据不可避免地会在规则数组中“磨碎”,最后必须重新构建。但是,是的,我们仍然可以训练一个规则数组,至少粗略地做到这一点——尽管我们发现能够做到这一点的规则数组看起来非常随机:

但要设置一个非平凡的自动编码器,让我们想象一下,我们逐渐“挤压”中间的数组,创建一个越来越窄的“瓶颈”,数据必须通过这个瓶颈流动。在瓶颈处,我们实际上拥有原始数据的压缩版本。我们发现,至少在瓶颈的某个宽度范围内,可以创建规则数组,这些规则数组有合理的概率可以作为原始数据的成功自动编码器:

LLM 的成功凸显了机器学习在序列延续方面的应用,以及 Transformer 在这方面的有效性。但与其他神经网络一样,实际使用的 Transformer 的形式通常非常复杂。但能否找到一个能够捕捉“Transformer 的本质”的最小模型呢?

The success of LLMs has highlighted the use of machine learning for sequence continuation—and the effectiveness of transformers for this. But just as with other neural nets, the forms of transformers that are used in practice are typically very complicated. But can one find a minimal model that nevertheless captures the “essence of transformers”? LLM 的成功凸显了机器学习在序列延续方面的应用,以及 Transformer 在这方面的有效性。但与其他神经网络一样,实际使用的 Transformer 的形式通常非常复杂。但能否找到一个能够捕捉“Transformer 的本质”的最小模型呢?

假设我们有一个想要继续的序列,例如:

我们希望用向量对每个可能的值进行编码,如下所示

例如,我们的原始序列被编码为:

然后我们有一个“头”,它读取一组连续的向量,挑选出某些值并将它们成对地送入 And 和 Xor 函数,以获得布尔值向量:

最终,这个头部将沿着我们的序列“滑动”,“预测”序列中的下一个元素是什么。但不知何故,我们必须从布尔值向量转到序列元素(的概率)。可能我们只需使用规则数组就可以做到这一点。但为了我们的目的,我们将使用完全连接的单层 Identity + Not 网络,其中在每个输出节点,我们只需找到到达它的值的数量的总和 - 并将其视为确定(通过 softmax )相应元素的概率:

在这种情况下,具有最大值的元素是 5,因此在“零温度”下,这将是我们对下一个元素的“最佳预测”。

为了训练整个系统,我们只需对所有事物进行一系列随机点突变,保留不会增加损失的突变(其中损失基本上是预测的下一个值和实际的下一个值之间的差异,或者更准确地说是“分类交叉熵”)。以下是这种损失在典型的此类训练中的进展方式:

在本次训练结束时,以下是我们最小变压器的组件:

首先是序列中不同可能元素的编码。然后是头部,这里显示应用于原始序列的第一个元素的编码。最后有一个单层离散网络,它从头部获取输出,并推断出接下来不同元素的相对概率。在本例中,下一个元素的最高概率预测应该是元素 6。

为了模拟 LLM,我们从一些初始“提示”开始,即适合头部宽度(“上下文窗口”)的初始序列。然后我们逐步应用我们的最小变换器,例如在每一步都将下一个元素作为具有最高预测概率的元素(即在“零温度下”运行)。使用此设置,“预测强度”集合以灰色显示,“最佳预测”以红色显示:

在我们原始训练数据之外运行这个程序,我们发现我们得到了一个连续正弦波的“预测”:

正如我们所料,我们的最小 Transformer 能够做出如此合理的预测,这依赖于正弦曲线的简单性。如果我们使用“更复杂”的训练数据,例如“数学定义的”()蓝色曲线

训练和运行最小变压器的结果现在是:

而且,毫不奇怪,它无法“计算出正确的计算结果”来正确地延续曲线。顺便说一句,不同的训练运行将涉及不同的突变序列,并会产生不同的预测(通常伴有周期性的“幻觉”):

在研究“感知器式”神经网络时,我们最终使用规则数组(或实际上是时空非均匀细胞自动机)作为最小模型。在这里,我们最终得到了一个稍微复杂一些的 Transformer 神经网络最小模型。但如果我们进一步简化它,我们最终得到的将不是细胞自动机之类的东西,而是标签系统之类的东西,其中有一个元素序列,并且在每个步骤中从开头删除一个块,并且根据其形式在末尾添加某个块,如下所示:

Here we’ve ended up with a slightly more complicated minimal model for transformer neural nets. But if we were to simplify it further, we would end up not with something like a cellular automaton but instead with something like a tag system. 如果我们进一步简化它,我们最终得到的将不是细胞自动机之类的东西,而是标签系统之类的东西。

是的,这样的系统可以产生极其复杂的行为——这强化了我们在这里反复看到的想法,即机器学习通过选择与已设定的目标相符的复杂性来发挥作用。

按照这种思路,我们可以将各种不同的计算系统视为机器学习的基础。我们一直在研究类似细胞自动机和标签系统的例子。但例如,我们的物理项目向我们展示了基于超图重写的系统的强大功能和灵活性。从我们在这里看到的情况来看,超图重写之类的东西似乎可以作为机器学习更强大、更灵活的基础。

那么机器学习到底发生了什么?

关键词

#irreducible computation #path of steepest descent

我认为,从我们在这里所做的工作中可以得出几个相当惊人的结论。首先,比传统神经网络简单得多的模型似乎能够捕捉机器学习的基本特征——事实上,这些模型很可能是新一代实用机器学习的基础。

但从科学的角度来看,这些模型的一个重要特点是,它们的结构非常简单,可以立即将其内部运作可视化。研究这些可视化结果时,最引人注目的特征是它们看起来非常复杂。

one of the things that’s important about these models is that they are simple enough in structure that it’s immediately possible to produce visualizations of what they’re doing inside. And studying these visualizations, the most immediately striking feature is how complicated they look. 这些模型的一个重要特点是,它们的结构非常简单,可以立即将其内部运作可视化。研究这些可视化结果时,最引人注目的特征是它们看起来非常复杂。

机器学习可能会以某种方式“破解系统”,并找到其功能的简单表示。但这似乎根本不是正在发生的事情。相反,似乎正在发生的事情是,机器学习在某种意义上只是“搭便车”利用了计算宇宙的普遍丰富性。它不是“专门构建一个人需要的行为”;相反,它所做的是利用计算宇宙中“已经存在”的行为。

这种方法之所以可能奏效,取决于一个至关重要的(乍一看可能出乎意料的)事实:在计算型宇宙中,即使是非常简单的程序也能普遍产生各种复杂的行为。关键在于,这种行为具有足够的丰富性和多样性,因此有可能找到符合机器学习目标的实例。从某种意义上说,机器学习所做的就是在计算型宇宙中“挖掘”能够执行所需操作的程序。

这并不是说机器学习可以确定一个特定的精确程序。相反,在机器学习的典型成功应用中,有很多程序“或多或少做了正确的事情”。如果一个人试图做的事情涉及到一些计算上不可约的东西,机器学习通常无法“很好地协调”以正确地“完成不可约计算的所有步骤”。但似乎许多“类人任务”是现代机器学习特别关注的重点,可以成功完成。

顺便说一句,我们可以预期,通过这里探索的最小模型,可以更切实地描述哪些类型的目标可以通过机器学习成功实现,哪些不能。机器学习操作的关键不仅在于存在可以做特定事情的程序,还在于它们可以通过自适应进化过程实际找到。

one can expect that with the minimal models explored here, it becomes more feasible to get a real characterization of what kinds of objectives can successfully be achieved by machine learning, and what cannot. 我们可以预期,通过这里探索的最小模型,可以更切实地描述哪些类型的目标可以通过机器学习成功实现,哪些不能。

在我们所做的工作中,我们经常使用本质上最简单的适应性进化过程:一系列点突变。我们发现,即使这样通常也足以让我们得到令人满意的机器学习解决方案。我们的适应性进化之路可能会一直陷入困境,无法得到任何解决方案。但这种情况不会发生,这似乎与我们正在研究的系统中普遍存在的计算不可约性密切相关,这会导致有效的随机性,这种随机性极有可能“让我们摆脱困境”。

we’ve often used what’s essentially the very simplest possible process for adaptive evolution: a sequence of point mutations. 我们(寻找机器学习解决方案)经常使用本质上最简单的适应性进化过程:一系列点突变。

从某种意义上说,计算不可约性为不同的自适应进化过程“提供了公平的竞争环境”,甚至简单的过程也能成功。我们正在使用的整个框架似乎也发生了类似的事情。任何一类系统似乎都能够成功地进行机器学习,即使它们没有传统神经网络的详细结构。我们可以将此视为计算等价原理的典型体现:即使系统在细节上可能有所不同,但它们最终在它们可以进行的计算方面都是等价的。

计算不可约性现象导致了一种根本的权衡,这在思考人工智能之类的事情时尤为重要。如果我们想要提前知道——并且大致保证——一个系统将要做什么或能够做什么,我们必须将系统设置为计算可约性的。但是,如果我们希望系统能够最大限度地利用计算,它将不可避免地具备计算不可约的行为。机器学习也是如此。如果我们希望机器学习能够做到最好,甚至给我们一种“实现魔法”的印象,那么我们必须让它表现出计算不可约性。如果我们希望机器学习“可以理解”,它必须是计算可约性的,而不是能够充分利用计算能力。

不过,一开始,机器学习是否真的需要这种能力还不清楚。也许存在一些计算上可简化的方法来解决我们想要使用机器学习解决的问题。但我们在这里发现,即使在解决非常简单的问题时,机器学习核心的自适应进化过程最终也会采样并使用我们预期的计算上不可简化的过程。

和生物进化一样,机器学习的根本目的在于找到可行的方法,不受人类在一步步明确设计事物时强加给我们的“可理解性”约束。我们能想象限制机器学习以使事物变得可理解吗?这样做会有效地阻止机器学习获得计算不可简化过程的能力,从这里的证据来看,在这种限制下,我们在机器学习中看到的那种成功似乎不太可能实现。

Like biological evolution, machine learning is fundamentally about finding things that work—without the constraint of “understandability” that’s forced on us when we as humans explicitly engineer things step by step. 和生物进化一样,机器学习的根本目的在于找到可行的方法,不受人类在一步步明确设计事物时强加给我们的“可理解性”约束。

那么,这对“机器学习科学”意味着什么呢?人们可能希望能够“深入了解”机器学习系统,并获得有关其运行情况的详细叙述性解释;实际上,人们将能够“解释一切机制”。但我们在这里看到的表明,一般来说,这样的方法行不通。人们只能说,在计算宇宙的某个地方,存在一些(通常是计算不可约的)过程“恰好”与我们想要的一致。

是的,我们可以基于计算不可约性做出一般性陈述,例如此类过程的可发现性,例如通过自适应进化。但如果我们问“系统如何详细工作?”,答案就不多了。当然,我们可以追踪其所有计算步骤,并看到它以某种方式运行。但我们不能指望它正在做什么的“全球人类层面的解释”。相反,我们基本上只能研究一些计算不可约的过程,并观察到它“恰好起作用”——而且我们不会对“为什么”做出高层次的解释。

但这一切都有一个重要的漏洞。在任何计算上不可约的系统中,总是不可避免地存在计算可约性的口袋。而且——正如我在物理项目中详细讨论的那样——正是这些计算可约性的口袋让我们这些计算受限的观察者能够识别出诸如“自然法则”之类的东西,从中我们可以构建“人类层面的叙述”。

那么机器学习又如何呢?其中出现了哪些计算可约性,我们可以从中构建“人类水平的科学定律”?就像在气体分子或空间最终离散元素水平上发生的计算不可约过程中出现的“简单连续行为”一样,我们可以预期,当处理大量组件时,至少某些计算可约性特征会更加明显。事实上,在足够大的机器学习系统中,当人们观察训练曲线等探测到的聚合行为时,通常会看到平滑的曲线和明显的规律性。

但关于可约性口袋的问题始终是它们最终是否与我们认为有趣或有用的东西相一致。是的,机器学习系统可能会表现出某种集体(“类似脑电图”)行为。但尚不清楚的是,这种行为是否会告诉我们有关系统中正在进行的实际“信息处理”(或其他)的任何信息。如果要有一门“机器学习科学”,那么我们希望的是,我们可以在机器学习系统中找到与我们可以测量和关心的事物相一致的计算可约性口袋。

那么,鉴于我们已经能够在这里探索到机器学习的基础,我们能如何评价机器学习系统的终极威力呢?一个关键的观察是,机器学习的工作原理是“搭载”计算不可约性,实际上是通过寻找恰好符合目标的“计算不可约的自然片段”。但是,如果这些目标涉及计算不可约性呢——就像人们在处理一个已经成功以计算术语形式化的过程(如数学、精确科学、计算 X 等)时经常发生的那样?好吧,我们的机器学习系统“在内部使用一些计算不可约性”是不够的。为了实现特定的计算不可约目标,系统必须做一些与实际、具体目标密切相关的事情。

然而,必须指出的是,通过在这里揭示机器学习的更多本质,至少可以更容易地定义将典型的“形式计算”与机器学习相结合的问题。传统上,系统的计算能力与其可训练性之间存在权衡。事实上,就我们在这里看到的情况而言,这似乎反映了这样一种感觉,即“更大的计算不可约性”更难以融入人们通过自适应进化过程逐步建立起来的东西中。

那么我们最终应该如何看待机器学习?实际上,它的力量来自于利用计算不可约性的“自然资源”。但是,当它使用计算不可约性时,它通过“搜寻”恰好有助于实现其目标的碎片来实现。想象一下一个人在建一堵墙。一种可能性是制作出一种特定形状的砖块,这些砖块知道它们可以拼在一起。但另一种可能性是只看一眼周围散落的石头,然后尽可能将它们拼合在一起来建造这堵墙。

Imagine one’s building a wall. One possibility is to fashion bricks of a particular shape that one knows will fit together. But another is just to look at stones one sees lying around, then to build the wall by fitting these together as best one can. 想象一下一个人在建一堵墙。一种可能性是制作出一种特定形状的砖块,这些砖块知道它们可以拼在一起。但另一种可能性是只看一眼周围散落的石头,然后尽可能将它们拼合在一起来建造这堵墙。

如果有人问“为什么墙上会有这样或那样的图案?”,答案基本上是“因为那是从碰巧散落在周围的石头上得到的”。它本身并没有总体理论;它只是对现有资源的反映。或者,在机器学习的情况下,可以预期,人们所看到的东西在很大程度上反映了计算不可约性的原始特征。换句话说,机器学习的基础与任何植根于规则学的东西一样多。在很大程度上,我们应该从这门科学入手,努力更多地了解机器学习中“到底发生了什么”,很可能也包括神经科学。

历史及个人笔记

从某种程度上来说,这似乎是思想史的一个怪癖,我在这里讨论的那些基础问题很久以前并没有得到解决——从某种程度上来说,这似乎是某些直觉和工具最近才发展起来的必然结果。

大脑从根本上来说是由相互连接的神经细胞组成的观点是在 19 世纪后期提出的,并在 20 世纪最初几十年开始流行——1943 年,沃伦·麦卡洛克 (Warren McCulloch) 和沃尔特·皮茨 (Walter Pitts) 的工作中,以计算方式运作的神经网络的形式化概念得以完整呈现。到 20 世纪 50 年代末,出现了以“感知器”形式实现的神经网络硬件(通常用于图像处理)。尽管早期人们对神经网络充满热情,但实际结果却好坏参半,20 世纪 60 年代末,人们宣布可以通过数学分析解决的简单问题——这导致人们普遍认为“神经网络无法做任何有趣的事情”。

自 20 世纪 40 年代以来,人们开始对神经网络进行一些常规分析,尤其是使用物理学方法。但这些分析通常以连续近似之类的结果结束,而这些结果几乎无法说明神经网络的信息处理方面。与此同时,人们一直坚信神经网络可以以某种方式解释和再现大脑的工作方式,但似乎没有方法可以解释大脑是如何运作的。然后在 20 世纪 80 年代初,人们对神经网络的兴趣又重新兴起,来自多个方向。其中一些研究集中在非常实际的努力上,以使神经网络能够执行特定的“类似人类”的任务。但有些则更具理论性,通常使用统计物理学或动态系统的方法。

但不久之后,这种热潮就渐渐消退了,几十年来,只有少数几个团队仍在研究神经网络。2011 年,神经网络在图像分析方面的应用取得了令人意外的突破。这是一个重要的实用进步。但它是由技术理念和发展推动的,而不是任何重大的新理论分析或框架。

这也是几乎所有后续事件的模式。人们花费了巨大的努力来设计出有效的神经网络系统——关于如何最好地实现这一点的各种民间传说层出不穷。但实际上甚至没有尝试过建立基础理论;这是一个工程实践领域,而不是基础科学。

正是在这种传统下,ChatGPT 在 2022 年底一炮走红。LLM 的几乎所有方面似乎都很复杂。是的,从经验上看,确实存在一些大规模的规律(比如缩放定律)。我很快就怀疑 LLM 的成功是人类语言中普遍规律的强烈暗示,而这些规律以前并没有被清楚地识别出来。但除了一些异常的例子外,几乎没有什么关于“LLM 内部发生了什么”的事情似乎很容易破译。而为系统运行设置“强有力的护栏”的努力——实际上是为了让它在某种程度上“可预测”或“可理解”——通常似乎会大大降低它的能力(这一点现在在计算不可约性的背景下是有意义的)。

我与机器学习和神经网络的接触始于 1980 年,当时我正在开发我的 SMP 符号计算系统,并想知道是否有可能将系统的符号模式匹配基础推广到某种更接近人类思维的“模糊模式匹配”。我知道神经网络,但认为它们是大脑的半现实模型,而不是我想象中的可能“解决”模糊匹配的算法的潜在来源。

部分原因是,为了理解神经网络等系统的本质,我在 1981 年提出了后来被我视为一维细胞自动机的东西。不久,我便深入研究细胞自动机,并形成了新的直觉,即复杂行为如何从简单规则中产生。但当我了解到最近有人试图利用统计力学的思想来构建理想化的神经网络模型时,我至少有足够的好奇心去建立模拟,试图更多地了解这些模型。

但我所做的并不成功。我既不能让这些模型做任何具有重大实际意义的事情,也没有设法从理论上理解它们。不过,我一直在想,细胞自动机“只是运行”和神经网络等可以“学习”的系统之间可能存在什么关系。事实上,在 1985 年,我试图制作一个基于细胞自动机的最小模型来探索这一点。这就是我现在所说的“垂直分层规则阵列”。虽然在很多方面我已经提出了正确的问题,但这是一个不幸的特定系统选择——我对它的实验并没有揭示我们现在看到的现象。

很多年过去了。我在《一种新科学》中写了一节关于“人类思维”的内容,讨论了思维本质的简单基本规则的可能性,甚至包括了神经网络的最小离散模拟。不过,当时我并没有发展这些想法。然而,到了 2017 年,即这本书出版 15 年后——并且知道了深度学习的突破——我开始更具体地思考神经网络是如何通过从整个计算宇宙中采样程序来获得能力的。但我仍然不明白这将如何运作。

与此同时,机器学习的实践经验中出现了一种新的直觉:如果你“足够猛烈地”攻击几乎任何系统,它都会学习。这是否意味着也许不需要神经网络的所有细节就可以成功地进行机器学习?也许可以创建一个结构足够简单的系统,使其操作可以可视化?我在 2023 年初撰写 ChatGPT 和 LLM 的论述时特别想知道这一点。我一直在谈论“LLM 科学”,但没有太多机会去研究它。

但几个月前,为了理解科学和人工智能之间关系,我尝试了一种“一次性实验” ——令我惊讶的是,它似乎成功地捕捉到了生物进化的一些本质。但其他适应性进化呢——特别是机器学习?所需的模型与我 1985 年研究的模型非常接近。但现在我有了新的直觉——而且,多亏了 Wolfram 语言,我有了更好的工具。

当然,这只是一个开始。但我很高兴能够看到我认为的机器学习基础科学的开端。已经有了明确的实际应用方向(不用说,我计划探索)。有迹象表明,也许我们最终能够理解机器学习的“魔力”为何以及何时发挥作用。

致谢

感谢 Wolfram 研究所的 Richard Assar 提供的大量帮助。还要感谢 Brad Klee、Tianyi Gu、Nik Murzin 和 Max Niederman 提供的具体成果,感谢 Symbolica 的 George Morgan 和其他人的早期关注,以及感谢 Kovas Boguta 多年前建议将机器学习与《一种新科学》中的想法联系起来。

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

胖车库
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开