【知乎转载】ChatGPT在做什么...为什么它能够成功

转载自 SIY.ZChatGPT在做什么…为什么它能够成功

这篇可能是知乎上关于ChatGPT目前为止最为详尽的文章,堪称ChatGPT基础知识百科全书,是对Stephen Wolfram大佬的雄文的细致翻译。为了增加趣味性,我使用了ChatGPT Plus协助创作(幽默点说,这相当于让ChatGPT解释自己怎么工作的),并保留某些的人工修正痕迹(比如指出ChatGPT翻译有问题的地方)。这样不仅降低了我的工作负担,也非常好的展示了ChatGPT的能力以及局限,还让我练习了如何使用ChatGPT创作,可谓一文三用。在【】内的内容都是我添加的,包含了一些“不平凡”的修正和指示。全文用了Mathematica(Wolfram 语言)这个软件作例子(Wolfram就是其创立者),所有的图也是Mathematica生成的,我以前也受益于Mathematica,翻译这个也算是对Mathematica的软广吧(原文所有的图都有Mathematica源码,可以学习怎么用Mathematica生成这些图片和进行计算)。

ChatGPT是以“词”为单位进行文本生成的

ChatGPT能够自动生成看起来很像人类写作的文本,这非常了不起且出乎意料。但是它是如何做到的?我的目的在于概述ChatGPT内部进行的过程,然后探讨它为什么能够成功地生成我们认为有意义的文本。我首先声明,我将集中讨论整体情况,并提到一些工程细节,但不会深入探讨它们。同时,我说的要点同样适用于其他当前的“大型语言模型”(LLMs),不仅仅限于ChatGPT。

首先要解释的是,ChatGPT始终基本上是在尝试生成“文本的合理延续”,这个延续是基于已有的文本,其中“合理”的意思是“在查看了数十亿个网页等人类编写的文本之后,我们可能会期望某个人会写下这样的内容。”

因此,我们假设已有文本为“人工智能最专长的一点是…”【原ChatGPT译文:“人工智能最好的一点在于其能力”,这虽然符合原意,但是翻译成中文后由于改变了词语顺序,在此处意思不对了】,然后想象一下扫描数十亿个人类编写的文本(例如网络内容和数字化书籍),找到所有这些文本的实例,看看下一个单词出现的频率是多少。ChatGPT实际上做了一些类似的事情,但(如我将解释的那样)它不是直接查看文字,而是寻找在某种意义上“匹配”内容。无论如何,最终它生成了一个排名,列出可能跟随文本的单词和它们的“概率”:

令人惊奇的是,ChatGPT尝试写一篇文章时,基本上只是一次又一次地询问“在已有的文本基础上,下一个单词应该是什么?” ,然后每次都添加一个单词。(更准确地说,如我所解释的那样,它添加的是一个“标记”【注:token】,这可能仅仅是一个单词的一部分,这也是为什么它有时会“创造出新词语”的原因。)【注:比如说对于“apple”这个单词,ChatGPT可能先生成“app”,然后再接上“le”。这样就有机会生造出"bananapple" 这样不存在的词。ChatGPT生成的最小的单元近似于一个Unicode,也就是原则上ChatGPT可以生成互联网上所有国家的文本,包括emoji和各类颜表情,以及它们的所有组合】

每一步,ChatGPT都会生成一个带有概率的单词列表。但是,它应该选择哪一个单词添加到正在写的文章(或其他内容)中呢?人们可能认为应该选择“排名最高”的单词(即被分配了最高“概率”的单词)。但是在这里,一些巫术开始悄悄渗入进来。因为由于某种原因(也许有一天我们会科学地理解它),如果我们总是选择排名最高的单词,我们通常会得到一篇非常“平淡”的文章,似乎从来没有“展现出任何创造力”(甚至有时完全重复)。但是如果有时(随机地)选择排名较低的单词,我们就能得到一篇“更有趣”的文章。

这里有随机性意味着,如果我们多次使用相同的提示,我们可能每次都会得到不同的文章。并且,符合巫术思想的是【注:就像炼丹一样,莫名其妙的配方产生了特别好的效果】,有一个特定的所谓“温度”参数,它控制了较低排名的单词会被使用的频率。对于文章生成,我们发现“温度”为0.8效果最好。(值得强调的是,这里没有使用任何“理论”,而只是基于实践的发现。例如,这里的“温度”的概念,对应于统计物理学中熟悉的指数分布上的温度,但至少就我们所知,这两个温度没有“物理”上的联系。)

在继续之前,我应该解释一下,为了方便演示,我文章的大部分内容不会使用ChatGPT中的完整系统;相反,我通常会使用更简单的GPT-2系统,这个系统的优点在于它足够小,可以在标准台式电脑上运行。因此,我将能够为我所展示的基本上所有内容提供明确的 Wolfram 语言代码,您可以立即在计算机上运行它们。【此处ChatGPT显然不能意识到这不是原来网页,忠诚地翻译了“(单击此处的任何图片即可复制其背后的代码。)”】

例如,以下是如何获取上述概率表。首先,我们必须先获取一个类似ChatGPT的“语言模型”,它是一个神经网络【由于“看”不到下面的图片,ChatGPT原来的翻译崩了】:

这个模型是GPT-2,ChatGPT目前基于GPT3.5

稍后,我们将深入研究这个神经网络,讨论它的工作原理。但是现在,我们可以将这个“网络模型”作为黑匣子【注:这里意思是我们只关心如何输入输出,但对中间的过程一无所知】应用于我们已有的文本中,然后询问模型预测的前5个概率最高的单词:

我们可以把结果转成一个数据表格,这样看的更加清楚:【ChatGPT翻译原文:这将结果转换为明确的格式化“数据集”】:

如果一次次地“应用模型”,每次都添加具有最高概率的单词(这个代码中被指定为模型生成文本的“策略”),会发生什么?

如果继续下去会发生什么?在这种情况下(“零温度”),结果很快就变得混乱和重复【满篇空话大话和车轱辘话】:

但是,如果不总是选择“最佳”的单词,而是有时随机选择“非最佳”单词(与“温度”0.8对应的“随机性”)呢?同样,可以构建文本:

每次这样做时,都会进行不同的随机选择,文本也会不同——如下5个例子:

值得指出的是,每一步生成下一个单词的概率分布时,虽然有很多可能的“下一个单词”可以选择(在温度0.8的情况下),但【如果按照概率对所有的下一个单词排序】它们的概率会很快地随着排名增加而降低(下面这个对数-对数图上的直线对应于一个n^–1的“幂律”衰减,这是语言的一般统计特征【注:人类的自然语言中,一段话语对应的下面可能出现的单词的概率分布呈现“幂律分布”】):

如果继续下去会发生什么?这里是一个随机例子。它比最高概率(零温度)情况要好一些,但仍然有些奇怪:

这是使用最简单的GPT-2模型(来自2019年)进行的。使用更新和更大的GPT-3模型会得到更好的结果。以下是使用相同的“提示”生成的最高概率(零温度)文本,但使用最大的GPT-3模型:

以下是一个【GPT3使用】“温度0.8”【生成】的随机例子:

那么这些概率从何而来呢?

ChatGPT总是根据概率选择下一个单词。但是这些概率从哪里来的?让我们先从一个更简单的问题开始。考虑一次生成英文文本一个字母(而不是单词)。我们如何计算每个字母的概率?

我们可以简单地采样英文文本,并计算不同字母出现的频率。例如,这是对“cats”维基百科文章【注:标题是“猫”的文章,下面类似】中字母的计数:

这是对“dogs”做同样的事情:

结果是类似的,但不完全相同(“o”在“dogs”文章中无疑更常见,因为它出现在“dog”本身这个词中)。不过,如果我们采样足够多的英文文本,我们可以期望最终获得相当一致的结果:

这是仅根据这些概率生成字母序列的示例:

我们可以通过添加空格作为具有一定概率的“字母”来将其分解成“单词”:

我们可以通过强制“单词长度”的分布与英文一致来更好地生成“单词”:

我们这里没有得到任何“实际单词”,但结果看起来略微更好。然而,要进一步,我们需要做的不仅仅是分别随机选择每个字母。例如,我们知道如果有一个“q”,下一个字母基本上必须是“u”。

这是字母概率的绘图:

这是显示典型英文文本中字母对(“2-grams”)的概率【注:连续的两个字母作为一个单元,这个单元出现的概率】的图。可能的第一个字母显示在页面上端,第二个字母在页面左侧【注:ChatGPT原文把这里的below翻译成了“页面下面”,是因为看不到图】:

我们在这里看到,例如,“q”列除了在“u”行之外都是空白(零概率)。那么,现在我们不是一次一个字母地生成我们的“单词”,而是使用这些“2-gram”概率一次两个字母地生成它们【就是每次根据最后一个字母,用条件概率生成下一个字母】。这里是结果的一个示例,其中恰好包括一些“实际单词”:

通过足够多的英文文本,我们不仅可以获得单个字母或字母对(2-grams)的概率的相当准确的估计,还可以获得更长字母序列的概率估计。如果我们使用逐渐更长的n-gram概率【注:即第n个字母的概率分布取决于之前的n-1个字母】生成“随机单词”,我们会发现它们变得越来越“真实”:

但是现在假设——与ChatGPT的做法差不多——我们处理的是整个单词,而不是字母。英语中有大约40,000个常用单词。通过查看大量英文文本(例如几百亿个单词的数百万本书),我们可以估计每个单词的出现频率。使用这个,我们可以开始生成“句子”,其中每个单词都是独立地随机选择的,具有在语料库中出现的相同的概率。这是一个示例:

很明显,这是胡言乱语。那么我们该如何改进?就像处理字母时一样,我们可以开始考虑不仅仅是单个单词的概率,还可以考虑一对或更长的n-gram单词概率。对于一对单词,以下是我们从“cat”单词开始得到的5个例子:

看起来更加“有道理”了。我们可以想象,如果我们能使用足够长的n-gram,基本上我们将“得到一个ChatGPT”——这意味着我们将获得能够以“正确的整体文章概率”生成文章长度的单词序列的东西。但问题在于:没有足够的文本可供我们推断这些概率。

在网络爬行中可能有数千亿个单词;在已数字化的书籍中可能有另外数百亿个单词。但是,对于40,000个常用单词,即使是可能的二元组也已经有16亿个,三元组的数量是60万亿。因此,我们无法从已有的文本中估计所有这些可能性的概率。而当我们到达20个单词的“文章片段”时,可能性的数量比宇宙中的粒子数量还要大,因此从某种意义上说,它们永远都无法全部写下来。

那么我们该怎么办?大的想法是制作一个模型,让我们估计序列应该出现的概率,即使我们在查看的文本语料库中从未明确看到这些序列。而ChatGPT的核心正是一个被称为“大型语言模型”(LLM)的模型,,它的设计使得它在估计这类概率方面做得很好【ChatGPT原文:它被构建为在估计这些概率方面做得很好】。

什么是模型?

假设你想知道(就像加利略在16世纪后期所做的那样),从比萨斜塔的每层掉下来的炮弹需要多长时间才能击中地面。好吧,你可以在每个高度下测量它并制作一个结果表。或者你可以做理论科学的本质:制作一个可以计算答案的模型,而不仅仅是测量和记忆每个情况。

让我们想象我们有(有点理想化的)数据,可以了解从各个楼层掉下来的炮弹需要多长时间:

没有明确数据时,我们如何确定它掉下来需要多长时间?在这种特殊情况下,我们可以使用已知的物理法则来计算。但是假设我们只有数据,不知道支配它的基本规律。然后,我们可以做出数学猜测,比如说或许我们应该使用一条直线作为模型:

我们可以选择不同的直线。但这是平均最接近我们所给定数据的线条。而从这条直线我们可以估算出任何楼层的掉落时间。

我们如何知道在这里尝试使用一条直线?在某种程度上,我们并不知道。使用直线在数学上是简单的,而我们已经习惯了许多测量的数据沿着简单的直线分布这个事实。当然,我们可以尝试更复杂的数学方法,比如a + bx + cx²,然后在这种情况下我们可以更好地符合数据:

然而,有些情况会出现问题。比如说这是我们使用a + b / x + c sin(x)最好的结果:

需要理解的是,从来没有“没有模型的模型”。您使用的任何模型都具有某种特定的基本结构,然后有一定的“旋钮可以调节”(即您可以设置的权重)来适应您的数据。在ChatGPT的情况下,使用了许多这样的“旋钮”,实际上有1750亿个。

然而ChatGPT背后的模型“只”需要这么多参数,就足以成为一个计算下一个单词概率“足够好”的模型,甚至可以为我们生成长达上千字的连贯文章。要知道,单词的三元组的数量就达到了60万亿,1000个单词的组合的数量(40000^1000)已经让很多“天文数字”(比如常用来比较的可观测宇宙的原子数)“自形惭秽“。相比之下,1750亿个参数确实微不足道。

【ChatGPT的翻译原文:ChatGPT的基本结构,仅仅有这么多参数,足以制作一个计算下一个单词概率“足够好”的模型,从而为我们提供合理的长度的文章。】

人类任务的模型

上面给出的例子涉及到制作一个符合数值数据的模型,这些数据基本上来自于简单的物理,几个世纪以来我们已经知道“简单的数学【注:指的是几页纸能写清楚且普遍适用的那种,这种意义下,“麦克斯韦方程组”等是简单的】适用【于建模很多物理现象】”。但对于 ChatGPT,我们必须对类似于人脑所产生的人类语言文本进行建模。对于这样的事情,我们还没有任何像“简单的数学”一样的东西。那么它的模型会是什么样子呢?

在谈论语言之前,让我们谈论另一项类似于人类的任务:图像识别。作为这个问题的一个简单例子,我们来考虑数字的图像(这也是一个经典的机器学习例子):

我们可以做的一件事是获得每个数字的一堆示例图像:

然后,为了找出我们输入的图像是否对应于特定数字,我们可以使用我们已经拥有的样本进行显式的逐像素比较。但作为人类,我们肯定做得更好,因为即使它们是手写的,并具有各种修改和扭曲,我们仍然可以识别这些数字:

当我们为先前的数值数据制作模型时,我们能够使用我们得到的数值 x,并为特定的 a 和 b 计算 a + b x。因此,如果我们将这里每个像素的灰度值视为某些变量 x_i,那么是否有某些以所有变量为输入的函数,当计算它时,会告诉我们图像是哪个数字?事实证明,可以构造这样的函数。并不奇怪的是,这个函数并不特别简单,一个典型的函数可能涉及大约五十万个数学运算。

但最终结果是,如果我们将图像的像素集合输入到此函数中,我们将得到对应该图像的数字。稍后,我们将讨论如何构建这样的函数以及神经网络的思想。但现在让我们把这个函数当作一个黑匣子,我们将手写数字的图像(作为像素值的数组)输入,我们得到相应的数字:

但这里到底发生了什么?我们逐渐模糊数字。一段时间内,我们的函数仍然“识别”它,此时我们称其为“2”。但不久它“失去了”它,并开始给出“错误”的结果:

我们为什么说这是“错误”的结果?在这种情况下,我们预先已经知道我们得到所有图像都是通过对“2”进行模糊处理得到的。但是,如果我们的目标是生成"人类识别图像"的模型,真正需要问的问题是:如果不知道图像来源,人类会怎样做?

如果我们的函数的结果通常与人类的看法相一致,那么我们就有了一个“好的模型”。而有个非平凡的科学事实是,在像这样的图像识别任务中,我们现在基本上知道如何构建可以做到这一点的函数。

我们能“数学证明”它们的有效性吗?不能。因为要做到这一点,我们必须有一个关于人类认知和行为的数学理论。拿这张“2”的图像并改变一些像素,我们可能想象,如果只是有几个像素“不在位”,我们仍然应该将其视为“2”。但是这会到达何种程度?这是人类视觉感知的问题。假如回答“这个图片表示的内容是否和之前相同”的并不是人类,比如蜜蜂或章鱼来说,答案可能不同-对于假定的外星人来说可能完全不同【 :这个玩意和之前变了几个像素,我不觉得是和之前同一个东西,毕竟我外星人也没学过怎么认读阿拉伯数字】。

神经网络

那么一个典型的用于图像识别等任务的模型,实际上是如何工作的呢?当前最成功和受欢迎的方法是使用神经网络。神经网络可以被认为是对大脑似乎是如何工作的简单理想化。

人类大脑中有约1000亿个神经元(神经细胞),每个神经元可以每秒产生多达一千次的电脉冲。这些神经元相互连接成一个复杂的网络,每个神经元都有像树枝一样的分支,使其能够向其他神经元传递电信号,每个连接的权重不同,神经元是否在某个时刻产生电脉冲大致取决于它接收到其他神经元的脉冲,而不同的连接对脉冲产生的影响不同。

当我们“看到一张图像”时,当光子从图像落在眼睛后面的“光感受器”细胞上时,它们在神经细胞中产生电信号。这些神经细胞连接到其他神经细胞,最终信号经过一整个神经元层的序列。正是在这个过程中,我们“认识”这个图像,最终“形成”我们“看到一个2”的想法(也许最终会做出诸如大声说“2”之类的事情)。

上一节中的“黑盒”函数是这样一个“数学化”的神经网络。它恰好有11个层(尽管只有4个“核心层”【注:包含主要权重的层】):

类似神经网络是如何“识别事物”的呢?关键在于“吸引子”的概念。我们想象一下,我们有手写的1和2的图像:

我们希望所有的1“被吸引到一个地方”,所有的2“被吸引到另一个地方”。或者换句话说,如果一个图像在“更接近1”的意义下,我们希望它最终在“1的地方”,反之亦然。

一个简单的类比,假设我们在平面中有某些位置,用点表示(在现实生活中,它们可能是咖啡店的位置)。那么我们可以想象,从平面上的任何点开始,我们总是希望最终到达最近的那个点(也就是我们总是去最近的咖啡店)。我们可以通过将平面分成区域(“吸引盆地”),由理想化的“分水岭”分隔来表示这一点:

我们可以将此视为一种“识别任务”,在该任务中,我们不是识别哪个数字最相似,而是直接查看给定点最接近哪个点。(在此处所示的“Voronoi图”中,它将二维欧几里德空间中的点分开;可以认为数字识别任务非常相似,但是空间不是2维,而是每个图像中的所有像素的灰度级形成的784维空间)

那么我们如何使神经网络“执行识别任务”?让我们考虑这个非常简单的例子:

我们的目标是将对应于位置{x,y}的“输入”转换为最接近的三个点之一。换句话说,我们希望神经网络计算{x,y}的函数,如下所示:

我们如何使用神经网络实现这一点呢?神经网络是由一系列理想化的“神经元”组成的连接集合,通常排列在层中【注:分层排列,即一层之间的神经元互不相连,且每层都只和它的上层和下层相连】,一个简单的例子如下所示:

每个“神经元”实际上被设置为评估一个简单的数值函数【注:就是完成一个简单的运算,比如对输入求和】。要“使用”网络,我们只需在顶部输入数字(如我们的坐标x和y),然后在每个层上有神经元“评估其函数”,并将结果向前【“前”是下方】传递,最终在底部产生最终结果:

传统(生物启发式)设置中,每个神经元都有一定数量的“输入连接”来自前一层的神经元,每个连接被分配一个“权重”(可以是正数或负数)。给定神经元的值是通过将“前一层神经元”的值与它们相应的权重相乘,然后将它们相加并乘以一个常数来确定的,并最终应用“阈值”(或“激活”)函数。在数学上,如果一个神经元具有输入x = {x1,x2 …},那么这个神经元会计算f [w * x + b],其中权重w和常量b通常对于网络中的每个神经元选择不同;函数f通常相同。

计算w * x + b只是一个矩阵乘法和加法问题。 “激活函数”f引入了非线性(最终导致非平凡行为)。通常有各种激活函数可供使用; 在这里我们将只使用 ReLU:

对于我们希望神经网络执行的每个任务(或等效地说,对于我们希望评估的每个整体函数),我们将有不同的权重选择。 (如我们稍后讨论的那样,这些权重通常是通过使用机器学习,即从我们想要的输出的示例来“训练”神经网络确定的)

最终,每个神经网络都对应于某个总体数学函数——尽管可能很难写出。对于上面的示例,它将是:

ChatGPT的神经网络也对应于这样的数学函数——但却有数十亿个权重【注:ChatGPT翻译成了“术语”】。

让我们回到单个神经元。以下是具有两个输入(表示坐标x和y)的神经元使用各种权重和常量(以及ReLU作为激活函数)组成的各种函数:

这就上面的较大网络计算的内容:

它不能算完全“正确”,但它接近我们上面展示的“最近点”函数。

让我们看看其他神经网络会发生什么。在每种情况下,正如我们稍后将解释的那样,我们使用机器学习找到最佳的权重选择。然后我们在这里展示带有这些权重的神经网络计算出的内容:

更大【权重更多,结构更复杂】的网络通常更好地逼近我们的目标函数。在每个吸引子盆地的中心,我们通常得到我们想要的确切答案。但是在边界处【颜色交错的地方】——神经网络“难以作出决定”的地方——事情可能会更混乱。

对于这种简单的,数学上可以轻易表示的“识别任务”,“正确答案”很明显。但是在识别手写数字的问题中,情况就不那么清楚了。如果有人写一个“2”看起来像一个“7”,怎么办?尽管如此,大多情况下神经网络神经网络仍然可以很好的区分数字——这给出了一个指示【接下文】:

我们能否“从数学上”说明网络如何区分数字?【由于神经网络及其复杂,将它对应的函数写在纸上,可能要消耗上百万张纸】,因而实际上不行。但是我们知道,神经网络只是“做神经网络所做的事情”,但事实证明,这通常与人类的区分相当吻合。

让我们看一个更详细的例子。假设我们有猫和狗的图像,我们有一个经过训练可以区分它们的神经网络。这是它在一些示例中可能会做的事情:

对于这类问题,“正确答案”甚至更不清楚了:比如猫装扮成狗,从图像上来说到底是算猫还是狗?但是,不论输入是什么,神经网络都会生成一个答案。同时事实证明,它以与人类所做的相似的,相当一致的方式进行操作。正如我之前所说的,这不是我们可以“从第一性原理”【这里的意思是,即使你完全知道神经网络的每一个参数的作用,也不足以让你“理解”或者“直观感受”到为何神经网络能够正确进行分类,你只会看到非常复杂的数学运算得到了正确的结果】推导出的事实。至少在某些领域,它的发现是经验性的【指的是,人们只是通过大量实验知道神经网络效果很好,但是不了解其原理】。但这是神经网络有用的关键原因之一:它们以某种方式捕捉到了一种“类似人类”的做事方式。

如果让你自己看一张猫的图片,然后问“为什么那是一只猫?”。也许你会说:“我看到了它尖尖的耳朵等等。”但是很难解释你如何识别该图像为猫,因为猫的要素显然不止尖尖的耳朵,很多其他动物也有。但是你的大脑却直接给了你答案。然而,对于一个大脑,还没有(至少目前)“进入内部”并看到它是如何做出决定的。对于(人工)神经网络呢?当你展示猫的图片时,去研究每个“神经元”都在做什么是很简单的。但即使对所有的神经元做一些基本的可视化通常都是非常困难的。

在我们用于上面的“最近点”问题的最终网络中有17个神经元。在识别手写数字的网络中有2190个。在我们用于识别猫和狗的网络中有60,650个。通常很难想象60,650维空间的内容。但是,因为这是一个处理图像的网络,它的许多神经元层都组织成数组,就像它正在查看的输入的像素数组一样。

如果我们拿一张典型的猫的图片

然后我们可以抽取第一层神经元输出的“图像”的集合表示第一层神经元的状态,其中许多图像我们可以轻松解释为类似于“没有背景的猫”或“猫的轮廓”之类的东西:

当我们观察第10层的输出时,已经很难解释正在发生什么:

但总的来说,我们可以说神经网络“挑选出某些特征”(也许尖尖的耳朵是其中之一),并使用这些特征确定图像的内容。但“尖尖的耳朵”这些特征是我们有名称的特征,大多数情况下这些特征既没有名称,也难以形容【“猫”的大多数情况下,猫的特征没有熟知的名称,比如“猫的总体轮廓构成的某种形状”】。

我们的大脑是否使用类似的特征?大多数情况下我们不知道。不过我们知道,像我们在这里展示的神经网络的前几层似乎会挑选图像的某些特征(例如对象的边缘),类似于我们大脑的第一级视觉处理中选择的特征。

但假设我们想在神经网络中获得“猫识别理论”。我们可以说:“看,这个特定的网络可以做到识别猫”。特定的网络立刻让我们对“它有多难的问题”有了一些感觉(例如需要多少个神经元或层数)。但至少到目前为止,我们没有一种用语言具体描述的精确方法来说明网络在做什么。也许这是因为它真的是计算上不可约的【注:计算上不可约是本文反复提及的概念,意思指某些问题本质上就无法有简单的数学方法或者计算方法,无法取巧,比如总结出一种方便人自己理解或者计算的方式】,我们除了一步步明确跟踪每个神经网络计算的每个步骤外,没有一般的方法可以找出它的操作方式。或者可能是因为我们还没有找到系统解释神经网络本质的科学体系或者法则。

当我们谈论使用ChatGPT生成语言时,我们将遇到相同的问题。再次强调,现在还不清楚是否有方法“总结它的操作方式”。但是,语言的丰富性和细节(以及我们的经验)可能比图像更容易让我们做出进一步的研究。

机器学习和神经网络的训练

到目前为止,我们一直在讨论“已经知道”如何执行特定任务的神经网络。但神经网络(我们的大脑也一样)不仅可以执行各种任务,而且它们可以从示例中逐步“进行训练”以更好的执行这些任务。

当我们制作一个区分猫和狗的神经网络时,我们实际上不必编写一个程序(比如)明确找到猫的触须。相反,我们只需展示大量的猫和狗的图像示例,然后让网络从中“机器学习”如何区分它们。

关键在于,训练过的网络会从它所显示的特定示例中“概括”出一般的操作方式。就像我们之前看到的那样,网络并不仅仅是识别它所展示的某个猫的图像的特定像素模式;相反,神经网络以某种方式学习到了“一般猫”的某些通用性质来区分图像,不仅仅限制在局部的像素模式。

神经网络的训练是如何进行的?本质上,我们一直在努力寻找能够使神经网络成功复制我们所给出示例的权重。然后,我们依靠神经网络以“合理的”方式在这些示例之间“插值”(或“概括”)。

让我们来看一个比先前最近点问题更简单的问题。我们只是尝试让神经网络学习以下函数:

对于这个任务,我们需要一个只有一个输入和一个输出的网络,例如:

但是应该使用什么权重?使用每种可能的权重集,神经网络都会计算某个函数。例如,以下是使用几组随机选择的权重所得到的结果:

我们可以明显看到,在这些情况下,它无法复制我们想要的函数。那么我们如何找到可以复制该函数的权重?

基本思想是提供大量的“输入→输出”示例来进行“学习”,然后尝试找到可以复制这些示例的权重。以下是使用逐渐增加的示例,完成学习的结果:

10,000 至 10,000,000 个示例

在“训练”中的每个阶段,网络中的权重逐步调整,我们看到最终得到一个成功复制所需函数的网络。那么我们如何调整权重呢?基本思想是在每个阶段看“离我们想要的函数有多远”,然后以使其更接近的方式更新权重。

我们通常计算“损失函数”(有时称为“成本函数”),来了解“我们离目标有多远”。这里我们使用一个简单(L2)的损失函数,它只是获取值和真实值之间差值的平方和。我们可以看到随着训练过程的进行,损失函数逐渐减小(对于不同任务而言,遵循不同的“学习曲线”),直到我们达到一个点,网络(至少在很好的近似情况下)成功复制所需的函数:

好的,现在需要解释的最后一个关键部分是如何调整权重以减少损失函数。正如我们所说,损失函数给出了我们(通过神经网络)获得的值与真实值之间的“距离”。但是“我们获得的值”是由当前版本的神经网络及其中的权重在每个阶段决定的。假设权重是变量,比如说w_i,我们想知道如何调整这些变量的值,以最小化(依赖它们的)损失。

例如,想象一下(极大地简化了实际使用的典型神经网络),我们只有两个权重w1和w2。然后我们可能会得到一个损失函数,它看起来像这样(等高线图热度图):

数值分析提供了各种技术来在这种情况下寻找最小值。一个典型的方法是,从前面的w1和w2开始,沿着最陡下降的路径逐步进行:

就像水流下山一样,只能保证这个过程最终会到达表面的某个局部最小值(“山谷中的湖”);它可能无法到达最终的全局最小值。

对于一般函数,我们不清楚如何找到“权重景观”上最陡下降的路径。但是微积分是我们的救星。如上所述,我们总可以将神经网络视为计算一个数学函数——它依赖于其输入和权重。但现在考虑对这些权重求导数【当然,函数要是“几乎处处可微”的,不过这不难做到】。结果发现微积分的链式规则【chain rule】实际上让我们“展开”了神经网络中连续层所做的操作【也就是可以逐层求导数】。结果是我们可以在某种局部逼近的情况下“反演”神经网络的操作,并逐步找到能够最小化输出相关损失的权重。

上图展示了只有2个权重的不真实情况下进行的最小化过程。但事实证明,即使有更多的权重(ChatGPT使用了1750亿个),仍然可能做到最小化,至少在某种逼近的水平上。事实上,“深度学习”在2011年左右的重大突破与这个发现有关,即在某种意义上,当涉及到大量权重时,可能更容易做到(至少是近似)最小化,而当涉及到相当少的权重时则更容易陷入局部最小值(“山湖”)而无法找到“出路”【注:其实不少理论已经证实,当维度足够高,即权重足够多时,局部最小值不是主要问题,“局部最小值是优化不收敛的罪魁祸首“ 是一种低纬度下的错觉】。

值得指出的是,一般情况下,有许多不同的权重集合都可以给出几乎具有相同性能的神经网络。通常在实际神经网络训练中会进行许多随机选择,这些选择会导致“不同但等价的解决方案”,如下所示:

但是,每个这样的“不同解决方案”都会具有稍微不同的行为。如果我们要求在我们给出训练示例的区域之外进行“外推”,我们可能会得到截然不同的结果:

但这些结果中哪一个是“正确的”呢?实际上没有办法说。它们都“与观察到的数据一致”。它们外推的结果在数学上,都是合理的。比如找规律: 1,2,4,8,16,?, 最后一个数有很多种选择,每种选择都可以出自一个“合理的原因”。不过有些可能对我们人类来说比其他的“更合理”。

神经网络训练的实践与技巧

特别是在过去的十年中,神经网络训练的艺术已经取得了许多进展。没错,这基本上是一门艺术【现在常称为“炼丹”】。有时候,特别是事后看来,可以看到我们的成功应用是基于某些“科学解释”。但大多数东西都是通过试错发现的,不断添加的想法和技巧逐渐建立了与神经网络一起工作的重要技术传统。

这里有几个关键部分。首先是针对特定任务应该使用哪种神经网络结构。然后就是一个关键问题,就是如何获取用于训练神经网络的数据。当下越来越多的情况是,我们不需要从头开始训练一个网络:新网络可以直接包含另一个已经训练好的网络,或者至少可以利用该网络为自己生成更多的训练示例。

人们可能会认为,对于每一种特定的任务,我们都需要一种不同的神经网络结构。但是人们发现,即使是明显不同的任务,相同的结构似乎经常也能起作用。在某种程度上,这让人想起了通用计算的想法(以及我的计算等价性原则),但是,正如我将在后面讨论的那样,我认为这更多地反映了我们通常试图让神经网络完成的任务是“类似于人类”的,而神经网络可以捕捉相当普遍的“类似于人类的过程”。

在神经网络早期的日子里,人们倾向于认为应该“尽可能地减少神经网络的负担”。例如,在将语音转换为文本时,人们认为应该首先分析语音,将其分解为音素等。但是发现,在至少对于“类似于人类的任务”而言,通常最好只是尝试在“端对端问题”上训练神经网络【也就是不过度介入数据的预处理和特征工程,直接将相对原始的数据喂给神经网络】,让它自动“发现”所需的中间特征、编码等。

人们还有一个想法,就是应该向神经网络引入复杂的单独组件,让它实际上“显式地实现特定的算法思想”。但是再次强调,这在大多数情况下都不值得,相反,最好只是处理非常简单的组件,并让它们“自我组织”(尽管通常以我们无法理解的方式)实现(假定)这些算法思想的等价物。

这并不是说神经网络没有相关的“结构思想”。例如,在处理图像的早期阶段,使用具有本地连接的神经元的2D数组至少非常有用。而且具有“回顾序列”【就是下一层中排后面的神经元会连接(回顾)上一层中排前面的神经元,非常类似于“通过前面的词推测后面的词”】的连接模式似乎是有用的——正如我们将在稍后看到的那样——处理像ChatGPT中的人类语言这样的事情。

但就像计算机一样,神经网络的一个重要特征是它们最终只是在处理数据。当前的神经网络——以及目前的神经网络训练方法——某种意义上只是专门处理数字数组。但在处理过程中,这些数组可以被完全重新排列和重新塑形。例如,我们在上面用于识别数字的网络从一个2D“图像样式”的输入数组开始,很快“加厚”到许多通道,但然后经过一层层的网络后“集中”到一个1D数组中,最终这个1D数组包含代表不同可能输出数字的元素:

但是,怎样才能确定针对特定任务需要多大的神经网络呢?这有点像艺术。在某种程度上,关键是要知道“任务的难度”。但对于类似于人类的任务,通常很难估计它的难度。是的,可能有一种系统的方法可以通过计算机非常“机械地”完成任务。但很难知道是否有所谓的技巧或快捷方式,使人们可以至少以“类人水平”更轻松地完成任务。以游戏为例,在“机械”玩某个游戏时,可能需要列举一个巨大的游戏树;但可能有更简单的(“启发式”)方法来实现“人类水平的游戏”。

当处理微小的神经网络和简单的任务时,有时可以明确地看到“此路不通”的情况。例如,下面是使用几个小型神经网络完成上一节任务的最佳结果:

我们所看到的是,如果神经网络太小,(无论我们多么努力)它就不能复现我们想要的函数。但是当它的规模超过一定程度时,通常只要我们用足够多的样本进行足够长时间的训练,就可以解决这个问题。另外,这些图片说明了神经网络中的一个技巧:可以通过在中间设计一个“瓶颈”,强制所有信息都要通过一个较小的中间神经元数量,来压缩的网络的大小,同时不会太影响性能。(值得一提的是,“无中间层”的神经网络(或所谓的“感知器”)只能学习本质上是线性的函数,但只要存在至少一个中间层,原则上始终可以将任何函数近似得足够好,至少是如果我们有足够多的神经元的话,尽管为了使其可行地进行训练,通常需要进行某种形式的正则化或规范化。)

好的,假设我们已经确定了一种神经网络的结构。现在的问题是如何获取用于训练网络的数据。神经网络和机器学习的许多实际挑战集中于获取或准备必要的训练数据。在许多情况下(“监督学习”),我们希望获得输入和期望输出的明确示例。因此,例如,我们可能希望标记图像中的内容或其他属性。也许我们需要明确地通过一些努力进行标记【比如数据标注团队】。但是通常情况下,我们可以利用已经完成的工作,或将其用作某种代理来解决这个问题。例如,我们可能会使用已提供的网络图像的alt【网页上图像的提示文本】,来标记这个图像的信息。或者在不同的领域中,我们可以使用为视频创建的封闭字幕。或者在语言翻译培训中,我们可以使用不同语言中存在的网页或其他文档的平行版本。

为了训练神经网络,需要展示多少数据?同样,从第一原则来估计很难。当然,通过使用“迁移学习”将已在另一个网络中学习到的重要特征列表“转移”过来,可以大大降低要求。但通常来说,神经网络需要“看到很多例子”才能训练得好。对于某些任务来说,重复的训练示例可能非常重要。事实上,一个标准的策略是将所有现有的示例都重复地显示给神经网络。在每个“训练轮次”(epoch)中,神经网络将处于至少稍微不同的状态,因此“提醒它记住特定的示例对于使其“记住该示例”是有用的。(是的,这可能类似于人类记忆中的重复的效用。)

但仅仅重复同一个示例并不足够,还需要向神经网络展示示例的变化。而这也是神经网络的技巧之一,即数据扩充的变化不必很复杂,即使使用基本的图像处理轻微修改图像也可以使其对神经网络训练“与新的图像一样好”。同样,当我们用完了训练自动驾驶汽车所需的实际视频等数据时,我们可以使用运行在类似于模拟游戏的环境中的模拟数据,而不需要所有真实世界场景的细节。

那像ChatGPT这样的模型呢?它有一个不错的特点,即可以进行“无监督学习”,这使得获取训练所需的示例变得更加容易。回想一下,ChatGPT的基本任务是找出如何继续给定的文本片段。因此,要获取训练示例,我们只需获取一段文本,并遮盖掉其结尾,然后将其用作“要训练的输入”,“输出”是完整的未遮盖的文本。我们将在后面进一步讨论这个问题,但主要观点是:与学习图像中的内容不同,ChatGPT不需要“明确的 token”;ChatGPT实际上可以直接从给定的文本示例中进行学习。

神经网络的实际学习过程最终都归结为确定哪些权重最能捕捉给定的训练示例。有各种详细的选择和“超参数设置”(因为权重可以被视为“参数”)可以用来调整这一点。有不同的损失函数选择(平方和、绝对值之和等)。有不同的损失最小化方法(每步在权重空间中移动多远等)。然后有诸如每个连续学习更新“批次”大小之类的问题,用于减少要最小化的损失。我们可以应用机器学习(例如,在Wolfram Language中),来自动化机器学习,并自动设置超参数等。但最终,可以通过观察损失如何逐步减小来表征整个训练过程(如在这个Wolfram 自家产品显示)。

人们通常会看到,损失在一段时间内下降,但最终会平稳在某个值。如果该值足够小,则训练可以被认为是成功的;否则这可能意味着应该尝试更改网络架构。

能否知道“学习曲线”要平稳需要多长时间?就像许多其他事情一样,似乎存在近似幂律缩放关系,这取决于所使用的神经网络规模和数据量。但总的结论是,训练神经网络很困难,需要大量计算工作量。实际上,绝大部分的工作量都是在进行数字数组操作【比如矩阵乘法】,这正是GPU擅长的,这就是为什么神经网络训练通常受到GPU可用性的限制。

在未来,是否会出现根本上更好的方法来训练神经网络,或者出现基本上和神经网络差不多,但是更高效的算法 【注:此处ChatGPT原文“或者通常做神经网络所做的事情”】?我认为几乎肯定会。神经网络的基本思想是利用大量简单的(基本相同的)组件创建一个灵活的“计算结构”,并使这个“结构”能够被增量地修改以从示例中进行学习。在当前的神经网络中,人们实际上是利用微积分的思想——应用于实数——来进行这种增量修改。但越来越明显的是,高精度数字并不重要;即使使用当前的方法,8位或更少的位数可能已经足够。

【更加激进的方法是】使用类似元胞自动机这样的计算系统,在许多单独的位上进行并行操作。从来没有清楚如何进行这种增量修改,但没有理由认为这是不可能的。事实上,就像“2012年的深度学习突破”一样,这种增量修改在更复杂的情况下可能会更容易。

神经网络(或许有点像大脑)被设置为具有实质上固定的神经元网络,而修改的是它们之间连接的强度(“权重”)。 (或许在至少年轻的大脑中,还可以增长大量全新的连接。)但是,虽然这对生物学可能是一个方便的设置,但它根本不清楚它是否接近我们需要功能的最佳实现方法。而涉及到渐进式网络重写的事情(也许类似于我们的Wolfram Physics Project),最终可能更好。

即使在现有神经网络的框架内,仍存在一个关键限制:目前进行神经网络训练的方式是基本上是按顺序【按批次,mini-batch】进行的,每批示例的影响都会向后传播以更新权重。实际上,即使考虑到GPU,当前计算机硬件在训练过程中也大多数情况下是“空闲”的,只有一部分时间会被更新。从某种意义上讲,这是因为我们当前的计算机往往具有与CPU(或GPU)分离的内存。但是在大脑中,这可能是不同的——每个“内存元素”(即神经元)也是潜在的活动计算单元。如果能够以这种方式设计未来的计算机硬件,训练可能会变得更加高效。

“一个足够大的网络可以做任何事情!”

ChatGPT这样的技术能力看起来非常令人印象深刻,以至于人们可能认为如果只是“继续训练”越来越大的神经网络,它们最终就能够“做任何事情”。如果一个人关注的是那些人类直接可以思考到的事情【直觉上可以做到事情】,这很可能是正确的。但过去几百年的科学教导我们,有些东西可以通过正式的过程推算出来,但人类直接思考却难以解决。

非平凡的数学就是一个很好的例子。但总的来说,这实际上等价于某种计算。而最终的问题是计算不可简化现象。有些计算可能需要很多步才能完成,但事实上它们可以被“简化”成非常直接的形式。但计算不可简化的发现意味着这种方法并不总是奏效。相反,有些过程,比如下面这个例子【一维元胞自动机】,不可避免地需要追踪每一步计算才能弄清楚发生了什么:

我们通常用大脑处理的事情,可能是有选择地避免计算不可简化的【即不可归约】。在大脑中进行(不可简化的)数学运算需要特殊的努力。实际上,在脑海中“思考”任何非平凡程序操作的步骤【比如纯粹通过在脑海中想象运算的过程,生成一份文件的SHA-256摘要】在实践中几乎是不可能的。

但是,我们有计算机。通过计算机,我们可以轻松地完成长时间的计算不可简化的事情。关键在于,一般而言,这些事情没有捷径。

是的,我们可以记忆许多特定的例子,这些例子包括某个特定计算系统中会发生什么。或许我们甚至可以看到一些(“计算可简化”)模式,使我们能够进行少量的概括。但是,计算不可简化意味着我们永远无法保证不会发生意外情况,只有通过明确地进行计算,才能告诉你在任何特定情况下实际会发生什么。

最后,学习与计算不可简化之间存在一种根本的张力。学习实际上是通过利用规律来压缩数据。但计算不可简化意味着,无论掌握多少规律,都存在着无法压缩数据。

实际上,人们可以想象在可训练的系统中构建小的计算设备(例如细胞自动机或图灵机)。这些设备可以作为神经网络的良好“工具”,就像 Wolfram|Alpha 可以是 ChatGPT 的良好工具一样。但是,计算不可简化意味着我们不能指望“进入”这些设备并让它们进行学习。

换句话说,能力与可训练性之间存在根本的权衡:越想让系统充分利用其计算能力,它就越会表现出计算不可简化,越不容易训练。而越容易训练,它就越难以进行复杂的计算。

(对于 ChatGPT 的当前情况,情况实际上要极端得多,因为用于生成每个输出token的神经网络是一个纯“前馈”网络,没有循环,因此无法使用任何非平凡的“控制流”进行计算【比如无法进行递归,或者任意长度的循环】。)

当然,人们可能会想知道能够进行不可简化计算是否真的很重要。实际上,很长一段时间以来,我们认为有很多任务——包括写作——对计算机来说“从根本上太难了”。现在,我们看到 ChatGPT 这样的工具可以完成这些任务,我们往往会突然认为计算机必须已经变得非常强大了——尤其是超过了它们已经基本能够完成的事情(例如逐步计算细胞自动机等计算系统的行为)。

是的,神经网络肯定可以察觉到自然界中的规律,这些规律我们也可以很容易地用“未经人工智能辅助的人类思维”来注意到。但是,如果我们想解决属于数学或计算科学范畴的问题,神经网络将无法做到这一点,除非它有效地“使用”一个“普通”的计算系统作为工具。

但是,所有这些都可能存在潜在的混淆。过去,有许多任务——包括写作文——我们认为这些任务对计算机来说“基本上太难了”。现在我们看到ChatGPT等模型能够完成这些任务,我们往往突然认为计算机一定变得更加强大——特别是超越了它们已经基本能够做到的事情(例如从前的逐步计算类似元胞自动机的计算系统的行为)。

但这并不是正确的结论。计算不可简化的过程仍然是计算不可简化的,并且对于计算机来说在根本上仍然是困难的,即使计算机可以轻松地计算它们的各个步骤。相反,我们应该得出的结论是,在某种意义上,我们认为计算机无法完成的任务——例如写作——它的实际计算比我们想象的更容易。

换句话说,神经网络之所以能够成功地撰写文章,是因为写作的问题在某种程度上比我们想象的计算要更浅。在某种意义上,这推进了关于我们人类如何完成诸如写作之类的事情,或者在一般情况下如何处理语言的理论。

如果您有足够大的神经网络,那么,是的,您可能能够做到人类可以轻松做到的任何事情。但是,您将无法捕捉到自然界的一般能力,也无法捕捉到我们从自然界中制造的工具的能力。正是这些工具——无论是实用的还是概念性的——使我们在最近几个世纪中超越了“纯粹的人类思考”的界限,并为人类的目的捕捉了更多的物理和计算宇宙的内容

限于论坛字数限制,剩下内容请移步原文查看(,•́ . •̀,)