type
status
date
slug
summary
tags
category
icon
password
ChatGPT 能够自动生成类似于人类书写文本的东西,即使是表面上的相似,这是非常了不起的,也是出乎意料的。但它是如何做到的呢?为什么它会起作用呢?我的目的在于大致概述 ChatGPT 内部发生的事情,然后探讨它为什么能够在生成我们认为有意义的文本方面做得如此出色。我应该在一开始就说,我将专注于正在发生的大局,并且虽然我会提到一些工程细节,但我不会深入探讨它们。(我将要说的实质同样适用于其他当前的“大型语言模型”[LLMs],如同适用于 ChatGPT。)
首先要解释的是,ChatGPT 始终试图做的基本工作是产生当前文本的“合理延续”,所谓“合理”,指的是“在看到人们在数十亿网页上写的内容后,人们可能期望看到的内容”。
那么我们假设有这样一段文字:“AI 最好的地方在于它的能力”。想象一下扫描数十亿页人类书写的文字(比如网页和数字化书籍),找到所有这段文字的实例,然后看看接下来是什么词,以及在多大程度上。ChatGPT 实际上做了类似的事情,只是(我会解释)它不看文字的字面意思;它寻找的是在某种意义上“匹配的东西”。但最终结果是它生成了一个可能跟随的单词的排名列表,以及“概率”。
值得注意的是,当 ChatGPT 做类似写一篇文章的事情时,它实际上只是一遍又一遍地问“在目前的文本中,下一个词应该是什么?”——然后每次添加一个词。(更准确地说,正如我将解释的那样,它添加了一个“标记”,这可能只是一个词的一部分,这就是为什么它有时可以“编造新词”。)
但是,在每一步,它都会得到一个带有概率的单词列表。但它应该选择哪一个单词添加到它正在写作的文章(或其他内容)呢?有人可能认为应该选择“排名最高”的单词(即分配了最高“概率”的单词)。但这就是巫术开始悄悄渗入的地方。因为出于某种原因——也许有一天我们会对此有科学式的理解——如果我们总是选择排名最高的单词,我们通常会得到一篇非常“平淡”的文章,似乎从不“展现任何创造力”(有时甚至逐字重复)。但如果有时(随机地)选择排名较低的单词,我们会得到一篇“更有趣”的文章。
这里存在随机性意味着如果我们多次使用相同提示,很可能每次得到不同的文章。而且,与巫术的概念保持一致,有一个特定的所谓“温度”参数,决定了低排名词语被使用的频率,对于文章生成来说,一个“温度”为 0.8 似乎是最佳的。(值得强调的是这里没有使用“理论”;这只是根据实践中发现的有效方法。例如,“温度”概念之所以存在,是因为统计物理学中熟悉的指数分布恰好被使用,但至少据我们所知,这并没有“物理”联系。)
(二八定律永不过时)
在我们继续之前,我应该解释一下,为了说明的目的,我大多数情况下不会使用 ChatGPT 中的完整系统;相反,我通常会使用一个更简单的 GPT-2 系统,它有一个很好的特性,就是它足够小,可以在标准台式电脑上运行。因此,对于我展示的所有内容,我都可以包含明确的 Wolfram 语言代码,您可以立即在您的计算机上运行。(单击这里的任何图片以复制其后面的代码。)
例如,这里是如何获取上面概率表的方法。首先,我们必须检索基础的“语言模型”神经网络:
稍后,我们将深入研究这个神经网络,并讨论它的工作原理。但目前我们可以将这个“网络模型”简单地应用于我们的文本,将模型认为应该跟随的前 5 个单词按概率排序。
这将获取该结果并将其转换为一个明确格式化的“数据集”:
如果一个人反复“应用模型”,在每一步中添加具有最高概率的单词(在此代码中指定为模型的“决策”),会发生什么?
如果一个人继续下去会发生什么?在这种(“零温度”)情况下,很快就会变得相当混乱和重复:
但是,如果不总是选择“顶部”单词,而是有时随机选择“非顶部”单词(与“温度”0.8 对应的“随机性”)呢?再次可以构建文本:
每次这样做时,都会做出不同的随机选择,文本也会不同,就像这 5 个例子中所示:
值得指出的是,即使在第一步,也有很多可能的“下一个词”可供选择(在温度 0.8 下),尽管它们的概率迅速下降(是的,在这个对数-对数图上的直线对应于一种 n –1 “幂律”衰减,这在语言的一般统计特征中非常典型)。
那么如果一个人继续下去会发生什么呢?这里有一个随机的例子。这比顶部词(零温度)的情况要好,但仍然最多有点奇怪:
这是用最简单的 GPT-2 模型(来自 2019 年)完成的。随着更新更大的 GPT-3 模型,结果更好。这是使用最大的 GPT-3 模型生成的相同“提示”的顶级词(零温度)文本:
个人感觉2019年的GPT-2已经很强大了,但是我们当时绝大多数人还没有意识到 2019互联网红利基本消失殆尽
好的,ChatGPT 总是根据概率选择下一个单词。但这些概率是从哪里来的呢?让我们从一个更简单的问题开始。让我们考虑一次生成一个字母的英文文本(而不是单词)。我们如何计算每个字母的概率呢?
我们可以做的一个非常简单的事情就是拿一段英文文本的样本,然后计算不同字母在其中出现的频率。例如,这个示例计算了维基百科关于“猫”的文章中的字母:
这对“狗”也是一样的
结果是相似的,但并非完全相同(“o”在“dogs”一词中无疑更常见,毕竟它出现在“dog”一词中)。然而,如果我们采样足够大的英文文本,最终可以期望至少得到相当一致的结果:
这是一个示例,如果我们只是根据这些概率生成一系列字母,我们会得到什么:
我们可以通过以一定概率添加空格来将其分解为“单词”
我们这里没有得到任何“实际单词”,但结果看起来稍微好一些。然而,要进一步,我们需要做的不仅仅是随机挑选每个字母。例如,我们知道如果有一个“q”,下一个字母基本上必须是“u”。
这是一个关于单个字母概率的图表:
这是一个显示典型英文文本中字母对(“2 元组”)概率的图表。可能的第一个字母横跨页面显示,第二个字母纵向显示:
在这里,例如,我们看到“q”列是空白的(概率为零),除了“u”行。好的,现在,我们不再一次生成我们的“单词”,而是一次生成两个字母,使用这些“2-gram”概率。这里是结果的一个样本,其中包括一些“实际单词”:
有足够多的英文文本,我们不仅可以获得单个字母或字母对(2 元组)的概率的相当准确的估计,还可以获得更长的字母序列的概率。如果我们使用逐渐更长的 n-gram 概率生成“随机单词”,我们会发现它们逐渐变得“更加真实”。
但现在让我们假设——或多或少像 ChatGPT 一样——我们处理的是整个单词,而不是字母。 英语中大约有 40,000 个相当常用的单词。 通过查看大量的英语文本语料库(比如几百万本书,总共几百亿个单词),我们可以估计每个单词有多常见。 并且使用这个,我们可以开始生成“句子”,其中每个单词都是独立随机选择的,具有它在语料库中出现的相同概率。 这是我们得到的一个样本:
毫不奇怪,这是无稽之谈。那么我们该如何做得更好呢?就像处理字母一样,我们可以开始考虑不仅是单个词的概率,还有词对或更长的词组的概率。对于词对来说,以下是从单词“cat”开始的 5 个例子。
它看起来稍微更加“合理”。我们可以想象,如果我们能够使用足够长的 n-gram,基本上我们会“得到一个 ChatGPT”—意思是我们会得到一些能够生成长度为文章的单词序列,具有“正确的整体文章概率”的东西。但问题在于:甚至没有足够的英文文本被写出来,以便推断这些概率。
在网络爬虫中可能有数百亿字;在已数字化的书籍中可能还有另外数百亿字。但是,即使是有 4 万个常见词,可能的 2-gram 数量已经达到了 16 亿,而可能的 3-gram 数量则是 60 万亿。因此,我们无法从已有的文本中估计所有这些的概率。当我们到达 20 个字的“文章片段”时,可能性的数量已经超过了宇宙中的粒子数量,因此从某种意义上说,它们永远无法全部被记录下来。
那么我们能做什么呢?大致的想法是建立一个模型,让我们能够估计序列应该出现的概率,即使我们在查看的文本语料库中从未明确看到过这些序列。而 ChatGPT 的核心正是一个所谓的“大型语言模型”,它被构建得很好,能够很好地估计这些概率。
- 估计序列应该出现的概率
What Is a Model?什么是模型?
假设你想知道(就像伽利略在 16 世纪末那样)从比萨斜塔的每层楼上掉下来的炮弹要多久才能击中地面。嗯,你可以在每种情况下测量它,并制作一个结果表。或者你可以做理论科学的本质:制作一个模型,提供一种计算答案的程序,而不仅仅是测量和记住每种情况。
做理论科学的本质:制作一个模型,提供一种计算答案的程序,而不仅仅是测量和记住每种情况。
让我们想象一下,我们有(有些理想化的)数据,显示炮弹从不同楼层掉落所需的时间:
我们如何确定从一个我们没有明确数据的楼层掉下来需要多长时间?在这种特殊情况下,我们可以利用已知的物理定律来计算。但假设我们只有数据,而不知道支配它的基本规律。那么我们可能会做出一个数学猜测,比如也许我们应该使用一条直线作为模型:
(这是在教授如何解决事物惯常问题的方法)
我们可以选择不同的直线。但这条直线是平均最接近我们所给数据的直线。通过这条直线,我们可以估计任何楼层的下落时间。
我们怎么知道要在这里尝试使用直线?在某种程度上,我们并不知道。这只是数学上简单的事情,我们习惯于许多我们测量的数据结果与数学上简单的事物相吻合。我们可以尝试一些数学上更复杂的东西——比如 a + b x + c x 2 ——在这种情况下,我们做得更好:
情可能会出现很大的问题。就像这里我们能做的最好的是 a + b/x + c sin(x):
值得理解的是,从来没有“无模型的模型”。您使用的任何模型都具有某种特定的基本结构,然后有一定的“可以调整的旋钮”(即您可以设置的参数)来适应您的数据。在 ChatGPT 的情况下,使用了许多这样的“旋钮”——实际上有 1750 亿个。
但值得注意的是,ChatGPT 的基本结构——仅仅具有那么多参数——足以创建一个计算下一个词概率的模型,使我们能够得到合理长度的文章。
Models for Human-Like Tasks 类似人类任务的模型
我们上面提到的例子涉及制作一个模型,用于基本上来自简单物理学的数值数据,几个世纪以来我们已经知道“简单数学适用”。但是对于 ChatGPT,我们必须制作一个模型,用于人类大脑产生的人类语言文本。对于这样的东西,我们还没有类似于“简单数学”的东西(至少目前还没有)。那么它可能是什么样的模型呢?
在我们讨论语言之前,让我们先谈谈另一个类似人类的任务:识别图像。作为这个的一个简单例子,让我们考虑数字图像(是的,这是一个经典的机器学习例子)。
我们可以做的一件事是为每个数字收集一堆样本图像:
然后,要找出我们输入的图像是否对应于特定的数字,我们可以通过与我们拥有的样本进行逐像素比较来做到这一点。但作为人类,我们似乎肯定做得更好——因为我们仍然可以识别数字,即使它们是手写的,而且经过各种修改和扭曲:
当我们为上面的数值数据制作模型时,我们能够取得给定的数值 x,并仅计算特定 a 和 b 的 a + b x。因此,如果我们将每个像素的灰度值视为某个变量 x,是否存在所有这些变量的某个函数——当进行评估时——告诉我们图像是什么数字?结果表明,构建这样的函数是可能的。毫不奇怪,它并不特别简单。一个典型的例子可能涉及大约五十万次数学运算。
但最终结果是,如果我们将图像的像素值集合输入到这个函数中,输出将是指定我们所拥有图像的数字。稍后,我们将讨论如何构建这样一个函数,以及神经网络的概念。但现在让我们将这个函数视为黑匣子,我们输入手写数字的图像(作为像素值数组),然后得到这些对应的数字:
但这里到底发生了什么?假设我们逐渐模糊一个数字。在一小段时间内,我们的函数仍然“识别”它,这里是一个“2”。但很快它“失去了”,开始给出“错误”的结果:
但为什么我们说这是“错误”的结果呢?在这种情况下,我们知道我们通过模糊“2”得到了所有的图像。但如果我们的目标是制作一个模型,来模拟人类在识别图像方面的能力,真正要问的问题是,如果一个人看到其中一张模糊的图像,而不知道它来自哪里,他会做出什么反应。
如果我们从我们的函数得到的结果通常与人类的判断一致,那么我们就有一个“好模型”。而一个非平凡的科学事实是,对于像这样的图像识别任务,我们现在基本上知道如何构建能够实现这一点的函数。
我们能“数学证明”它们有效吗?嗯,不行。因为要这样做,我们必须有一个关于人类在做什么的数学理论。拿“2”这个图像,改变几个像素。我们可能会想象,只要有几个像素“错位”,我们仍然应该认为这个图像是一个“2”。但这应该持续到什么程度?这是一个关于人类视觉感知的问题。是的,答案毫无疑问对蜜蜂或章鱼可能会有所不同,对假设的外星人来说可能完全不同。
Neural Nets 神经网络
好的,那么我们用于识别图像等任务的典型模型实际上是如何工作的呢?目前最流行且最成功的方法是使用神经网络。神经网络是在 1940 年代发明的,其形式与今天的使用非常接近,可以被看作是大脑运作方式的简单理想化。
在人类大脑中,大约有 1000 亿个神经元(神经细胞),每个神经元都有可能产生高达每秒 1000 次的电脉冲。这些神经元连接成一个复杂的网络,每个神经元都有类似树枝的分支,使其能够将电信号传递给成千上万的其他神经元。粗略地说,任何给定神经元在某一时刻是否产生电脉冲取决于它从其他神经元接收到的脉冲,不同的连接具有不同的“权重”。
当我们“看到一幅图像”时,发生的是图像中的光子落在我们眼睛后面的“光感受器”细胞上时,它们会在神经细胞中产生电信号。这些神经细胞连接到其他神经细胞,最终信号通过一系列神经元层。在这个过程中,我们“认识”图像,最终“形成思维”,认为我们“看到了一个 2”(最终可能会做出像大声说“二”这样的动作)。
前一节中的“黑匣子”功能是这种神经网络的“数学化”版本。 它恰好有 11 层(尽管只有 4 个“核心层”):
introduction
这张图片展示了一个神经网络(NetChain)的结构,该网络是用于图像分类的卷积神经网络(Convolutional Neural Network, CNN)。下面详细介绍每一层及其功能:
网络结构
- 输入层(Input):
- 类型:图像(image)
- 大小:1×28×28(单通道28x28像素的灰度图像,如MNIST数据集中的手写数字图片)
- 第一卷积层(ConvolutionLayer):
- 输出大小:20×24×24(卷积操作后得到20个24x24的特征图)
- 激活函数层(Ramp):
- 类型:ReLU激活函数(Ramp),引入非线性变换。
- 池化层(PoolingLayer):
- 输出大小:20×12×12(池化操作后将特征图尺寸缩小一半)
- 第二卷积层(ConvolutionLayer):
- 输出大小:50×8×8(卷积操作后得到50个8x8的特征图)
- 激活函数层(Ramp):
- 类型:ReLU激活函数(Ramp),引入非线性变换。
- 池化层(PoolingLayer):
- 输出大小:50×4×4(池化操作后将特征图尺寸缩小一半)
- 展平层(FlattenLayer):
- 输出大小:向量(vector),大小为800(将50个4x4的特征图展平成一维向量)
- 全连接层(LinearLayer):
- 输出大小:向量(vector),大小为500(全连接操作,输出500个节点)
- 激活函数层(Ramp):
- 类型:ReLU激活函数(Ramp),引入非线性变换。
- 全连接层(LinearLayer):
- 输出大小:向量(vector),大小为10(全连接操作,输出10个节点,对应10个分类)
- Softmax层(SoftmaxLayer):
- 输出大小:向量(vector),大小为10(Softmax操作,将输出向量转化为概率分布)
- 输出层(Output):
- 类型:分类(class),根据概率分布选择最终的分类结果。
网络工作原理
- 卷积层:提取图像的局部特征,通过卷积核的滑动窗口操作获取特征图。
- 激活函数层:通过ReLU激活函数引入非线性变换,使模型能够学习到复杂的特征。
- 池化层:对特征图进行降采样,减小尺寸,降低计算复杂度,同时保留重要特征。
- 展平层:将三维的特征图展平成一维向量,便于后续全连接层处理。
- 全连接层:通过全连接操作进一步提取特征,最终输出分类结果。
- Softmax层:将全连接层的输出转换为概率分布,用于分类任务。
应用场景
该网络结构典型应用于图像分类任务,如MNIST手写数字识别。其简单而有效的设计使其适用于小规模数据集和初学者学习卷积神经网络的基本概念。
这个神经网络并没有什么特别“理论推导”的东西;它只是在 1998 年作为一种工程构建出来,并且被发现是有效的。(当然,这与我们描述大脑是通过生物进化过程产生的方式并没有太大不同。)
好的,但是这样的神经网络如何“识别事物”呢?关键在于吸引子的概念。想象一下,我们有手写的数字 1 和 2 的图像:
我们希望所有的 1 都“被吸引到一个地方”,所有的 2 都“被吸引到另一个地方”。换句话说,如果一幅图像在某种程度上“更接近于 1 而不是 2”,我们希望它最终出现在“1 的地方”,反之亦然。
作为一个直接的类比,让我们假设在平面上有一些位置,用点表示(在现实生活中,它们可能是咖啡店的位置)。然后我们可以想象,无论从平面上的哪个点开始,我们总是希望最终到达最近的点(即我们总是去最近的咖啡店)。我们可以通过将平面分成由理想化的“分水岭”分隔的区域(“吸引盆地”)来表示这一点。
我们可以将这看作是实现一种“识别任务”,在这种任务中,我们不是在做识别给定图像“最像哪个数字”的事情,而是直接看给定点最接近哪个点。(我们在这里展示的“Voronoi 图”设置将 2D 欧几里得空间中的点分开;可以将数字识别任务看作是在一个由每个图像中所有像素的灰度级形成的 784 维空间中做类似的事情。)
那么我们如何让神经网络“执行识别任务”呢?让我们考虑这个非常简单的情况:
我们的目标是接受一个与位置{x,y}对应的“输入”,然后将其“识别”为最接近的三个点之一。换句话说,我们希望神经网络计算{x,y}的函数:
introduction
这张图片展示了一个分段函数的二维和三维可视化图。具体来说,左图是一个二维的分类图,右图是相应的三维函数图。让我们详细解释这两幅图所展示的内容。
左图:二维分类图
- 轴:
x
和y
分别表示输入变量。
- 颜色表示分类:不同颜色代表不同的分类区域。
- 橙色区域
- 红色区域
- 蓝色区域
右图:三维函数图
- 轴:
x
、y
表示输入变量,z
表示输出值。
- 颜色和高度表示输出值:输出值由颜色梯度(从蓝色到红色)和高度表示。
- 颜色条(Color bar):右侧的颜色条表示输出值的范围,从-1(蓝色)到1(红色)。
解析函数
从这两幅图可以推断,函数是一个分段线性的分类函数。它将二维平面划分为三个区域,每个区域对应不同的输出值或类别。具体来说:
- 红色区域:
z
值在这个区域内为正且较大。
- 蓝色区域:
z
值在这个区域内为负且较大。
- 橙色区域:
z
值在这个区域内介于红色和蓝色区域之间。
分段函数示例
假设这个分段函数是一个简单的线性分类函数.
在这个定义中:
- 当
y
大于|x|
时,z
为1(红色区域)。
- 当
y
小于|x|
时,z
为-1(蓝色区域)。
- 其他情况(即
|x| < y < |x|
)中,z
为0(橙色区域)。
总结
这两幅图展示了一个分段线性分类函数的可视化结果,清晰地展示了不同区域的分类情况。通过二维图,我们可以直观地看到分类边界,通过三维图,我们可以更好地理解函数的高度变化及其对应的输出值。这样的可视化对理解分类算法的决策边界和模型行为非常有帮助。
那么我们如何使用神经网络来做到这一点呢?最终,神经网络是一个理想化的“神经元”连接集合,通常排列在层中,一个简单的例子是:
每个“神经元”都被有效地设置为评估一个简单的数值函数。为了“使用”网络,我们只需在顶部输入数字(比如我们的坐标 x 和 y),然后让每一层的神经元“评估它们的函数”并将结果向前传递通过网络——最终在底部产生最终结果:
在传统(受生物启发的)设置中,每个神经元实际上都有一定的一组“传入连接”,来自前一层的神经元,每个连接都被分配一个特定的“权重”(可以是正数或负数)。给定神经元的值是通过将“前一神经元”的值乘以它们对应的权重,然后相加并加上一个常数,最后应用“阈值化”(或“激活”)函数来确定的。在数学术语中,如果一个神经元有输入 x = {x 1 , x 2 …},那么我们计算 f[w . x + b],其中权重 w 和常数 b 通常对网络中的每个神经元选择不同的值;函数 f 通常是相同的。
权重和常数一般不同
计算 w . x + b 只是矩阵乘法和加法的问题。 “激活函数” f 引入了非线性(最终导致非平凡行为)。通常使用各种激活函数;这里我们将只使用 Ramp (或 ReLU):
introduction
这张图片展示了几种常见的激活函数(Activation Functions)及其对应的图形。激活函数是神经网络中引入非线性的重要组成部分,不同的激活函数在不同的应用场景中具有不同的特性和效果。下面逐一介绍这几种激活函数:
1. ReLU(Rectified Linear Unit)
- 公式:f(x)=max(0,x)
𝑓(𝑥)=max(0,𝑥)
- 图形特点:在x<0时输出0,在x>=0时输出x。
- 优点:
- 计算简单高效。
- 缓解梯度消失问题。
- 缺点:
- 可能出现“死亡ReLU”问题,即一些神经元在训练过程中可能永远不会被激活。
2. Tanh(双曲正切函数)
公式:
- 图形特点:S型曲线,输出范围为[-1, 1]。
- 优点:
- 输出均值为0,有助于模型收敛。
- 缺点:
- 可能出现梯度消失问题。
3. Sigmoid(S形函数)
公式:
- 图形特点:S型曲线,输出范围为[0, 1]。
- 优点:
- 输出值范围在0到1之间,可以解释为概率。
- 缺点:
- 容易出现梯度消失问题。
- 输出均值不为0,可能导致梯度更新效率降低。
4. Mish
公式:
- 图形特点:光滑且非单调的曲线。
- 优点:
- 保持了ReLU的优点,同时引入了非线性。
- 减少梯度消失和梯度爆炸的问题。
- 缺点:
- 计算相对复杂。
5. Swish
公式:𝑓(𝑥)=𝑥⋅𝜎(𝑥)
- 图形特点:平滑且单调的曲线。
- 优点:
- 在一些任务上表现优于ReLU。
- 减少梯度消失问题。
- 缺点:
- 计算相对复杂。
总结
这些激活函数各有优缺点,在实际应用中选择合适的激活函数需要考虑具体的任务和数据特点。ReLU由于其计算简单且有效,常用于深度神经网络。Tanh和Sigmoid在较浅的网络中仍有应用。Mish和Swish是近些年提出的新激活函数,通常在更复杂的模型中表现更好。
对于我们希望神经网络执行的每个任务(或者等效地,对于我们希望它评估的每个整体功能),我们将有不同的权重选择。(正如我们稍后将讨论的那样,这些权重通常是通过使用机器学习从我们想要的输出示例中“训练”神经网络来确定的。)
最终,每个神经网络只是对应于某种总体数学函数 - 尽管可能很难写出来。对于上面的例子,它将是:
ChatGPT 的神经网络也只是对应于这样一个数学函数,但实际上有数十亿个项。
但让我们回到单个神经元。以下是一个具有两个输入(代表坐标 x 和 y)的神经元可以使用各种权重和常数(以及 Ramp 作为激活函数)计算的功能示例:
introduction
这张图片展示了不同类型的神经网络层及其作用示意图,通过三维可视化展示输入如何被不同的层转换。每个图示都包含一个简单的三维图形和一个指向不同方向的箭头,表示输入特征和网络层的变化。以下是对每一层的介绍:
1. 输入层到卷积层(Convolution Layer)
- 图示:左边第一幅图。
- 描述:卷积层通过卷积核对输入特征进行局部感知和特征提取。图中展示了输入空间(二维平面)被卷积操作后产生的特征映射,表现为线性变换后的特征图。
2. 卷积层到激活层(Activation Layer)
- 图示:左边第二幅图。
- 描述:激活层引入非线性变换,常见的激活函数有ReLU、Sigmoid等。图中展示了经过非线性激活函数后,输入特征空间发生的非线性变换,特征图形状发生变化。
3. 卷积层到池化层(Pooling Layer)
- 图示:左边第三幅图。
- 描述:池化层对输入特征图进行下采样,减少特征图的尺寸,同时保留重要特征。图中展示了池化操作后,特征图的分辨率降低,特征空间变得更加简化。
4. 全连接层(Fully Connected Layer)
- 图示:右边第三幅图。
- 描述:全连接层将输入特征展平并通过线性变换映射到输出空间。图中展示了全连接层对输入特征进行的全局变换,特征图被展平成向量并经过线性变换。
5. 残差层(Residual Layer)
- 图示:右边第二幅图。
- 描述:残差层(ResNet中的残差块)通过跳跃连接(skip connection)将输入直接传递到输出,缓解梯度消失问题。图中展示了输入特征和经过变换后的特征相加,保留了原始输入的信息。
6. 输出层(Output Layer)
- 图示:右边第一幅图。
- 描述:输出层将网络的最终特征映射到目标输出空间,常用于分类任务中的Softmax层。图中展示了输入特征被映射到最终的输出空间,通常是一个概率分布或回归值。
总结
这张图通过可视化展示了神经网络中不同类型的层及其对输入特征的变换方式。卷积层提取局部特征,激活层引入非线性,池化层进行下采样,全连接层进行全局变换,残差层通过跳跃连接保留原始信息,输出层则将特征映射到目标输出。理解这些层的作用及其变换过程有助于构建和优化深度神经网络。
但是关于上面的更大网络呢?嗯,这是它计算的内容:
这不完全是“正确”的,但它接近我们上面展示的“最近点”函数。
让我们看看其他一些神经网络会发生什么。在每种情况下,正如我们稍后将解释的那样,我们正在使用机器学习来找到最佳的权重选择。然后我们在这里展示神经网络使用这些权重计算的结果:
introduction
这张图片展示了不同复杂度的神经网络结构及其对输入空间的映射效果。图片从左到右依次展示了三个神经网络模型:简单网络、中等复杂度网络和复杂网络。每个网络对应三个图示:网络结构图、二维平面映射图和三维函数图。以下是对每一部分的详细介绍:
左边:简单网络
网络结构图
- 节点和连接:少量节点和连接,表示一个简单的神经网络。
- 层数较少:通常由一层或两层神经元组成。
二维平面映射图
- 平滑过渡:颜色渐变平滑,表示函数值的平缓变化。
- 无明显边界:不同区域之间的过渡自然,无明显分类边界。
三维函数图
- 平坦表面:函数图像较为平坦,变化不大。
- 等高线稀疏:等高线分布较为稀疏,表示函数值变化较小。
中间:中等复杂度网络
网络结构图
- 节点和连接:更多节点和连接,表示一个中等复杂度的神经网络。
- 层数适中:通常由两到三层神经元组成。
二维平面映射图
- 部分边界清晰:颜色渐变出现一些明显边界,表示函数值的变化更为复杂。
- 局部非线性:有些区域呈现非线性变化,过渡不如简单网络平滑。
三维函数图
- 起伏表面:函数图像开始出现起伏,表示函数值变化加剧。
- 等高线增多:等高线分布更加密集,表示更多的局部变化。
右边:复杂网络
网络结构图
- 节点和连接:大量节点和连接,表示一个复杂的神经网络。
- 层数较多:通常由多层神经元组成,可能包括卷积层、全连接层等。
二维平面映射图
- 清晰边界:颜色渐变呈现出明显边界,表示函数值在不同区域间有显著变化。
- 复杂非线性:多数区域呈现复杂的非线性变化,分类边界清晰。
三维函数图
- 复杂表面:函数图像表现出复杂的起伏和变化,表示函数值有显著波动。
- 等高线密集:等高线分布非常密集,表示函数值有许多局部极值。
总结
这张图片通过展示简单、中等复杂度和复杂神经网络的结构及其对输入空间的映射效果,直观地体现了网络复杂度对函数拟合能力的影响。随着网络复杂度的增加,神经网络能够捕捉到更多的非线性特征,呈现更复杂的决策边界和函数值变化。这种能力对于处理复杂的分类和回归任务非常重要,但同时也增加了过拟合的风险,需要通过正则化和适当的模型选择进行控制。
更大的网络通常在逼近我们的目标函数时表现更好。在“每个吸引子盆地的中间”,我们通常会得到我们想要的答案。但在边界处——神经网络“难以做出决定”的地方——情况可能会更混乱。
通过这种简单的数学风格的“识别任务”,很明显可以知道“正确答案”是什么。但在识别手写数字的问题上,情况就不那么明显了。如果有人写的“2”看起来像“7”等等,那该怎么办呢?尽管如此,我们可以询问神经网络如何区分数字——这就给出了一个指示:
我们能用“数学方法”来解释网络是如何进行区分的吗?实际上不行。它只是“执行神经网络的操作”。但事实证明,这通常与我们人类所做的区分相当吻合。
让我们来看一个更详细的例子。假设我们有猫和狗的图像。我们有一个经过训练可以区分它们的神经网络。以下是它在一些示例中可能会做的事情:
现在,“正确答案”是什么变得更加不清楚了。一个穿着猫服装的狗怎么样?等等。无论输入什么,神经网络都会生成一个答案,并且在某种程度上与人类可能的方式相当一致。正如我上面所说的,这并不是我们可以“从第一原则中推导出来的事实”。这只是一些经验性发现的真相,至少在某些领域是如此。但这是神经网络有用的一个关键原因:它们以某种方式捕捉了“类似人类”的做事方式。
它们以某种方式捕捉了“类似人类”的做事方式。
展示给自己一张猫的图片,并问:“为什么那是一只猫?”也许你会开始说:“嗯,我看到它尖尖的耳朵等等。”但很难解释你是如何认出这张图片是一只猫的。只是你的大脑以某种方式弄清楚了。但对于大脑来说,目前(至少)还没有办法“进入”并看到它是如何弄清楚的。那么对于(人工)神经网络呢?嗯,当你展示一张猫的图片时,看到每个“神经元”做什么是很直接的。但即使要获得基本的可视化通常也是非常困难的。
在我们用于上面的“最近点”问题的最终网络中,有 17 个神经元。在用于识别手写数字的网络中,有 2190 个神经元。而在我们用于识别猫和狗的网络中,有 60,650 个神经元。通常很难想象 60,650 维空间的情况。但由于这是一个用于处理图像的网络,它的许多神经元层都被组织成数组,就像它正在查看的像素数组一样。
如果我们拿一张典型的猫的图片
然后,我们可以通过一系列衍生图像来表示第一层神经元的状态,其中许多我们可以轻松解释为诸如“没有背景的猫”或“猫的轮廓”之类的东西:
到了第十层,很难解释发生了什么:
但总的来说,我们可以说神经网络正在“挑选出某些特征”(也许尖耳朵是其中之一),并利用这些特征来确定图像的内容。但这些特征是我们有名称的特征吗,比如“尖耳朵”?大多数情况下不是。
(利用特征来分辨出它是什么)
我们的大脑是否使用类似的特征?大多数时候我们并不知道。但值得注意的是,像我们展示的这种神经网络的前几层似乎会挑选出图像的一些方面(如物体的边缘),这些方面似乎与我们知道的大脑视觉处理的第一层所挑选出的方面相似。
但是假设我们想要在神经网络中有一个“猫识别理论”。我们可以说:“看,这个特定的网络做到了” —— 立刻这给了我们一些“问题有多难”的感觉(例如,可能需要多少神经元或层)。但至少目前为止,我们没有办法“提供一个叙述性描述”来说明网络在做什么。也许这是因为它真的是计算上不可简化的,除非通过明确追踪每一步,否则没有一般方法可以找出它在做什么。或者可能只是因为我们还没有“弄清楚科学”,并且找到了允许我们总结正在发生的事情的“自然法则”。
当我们谈论使用 ChatGPT 生成语言时,我们会遇到相同类型的问题。再次,不清楚是否有方法来“总结它的工作内容”。但语言的丰富性和细节(以及我们对它的经验)可能使我们比使用图像更进一步。
Machine Learning, and the Training of Neural Nets机器学习和神经网络训练
到目前为止,我们一直在谈论“已经知道”如何执行特定任务的神经网络。但神经网络如此有用的原因(可能也在大脑中)是,它们不仅原则上可以执行各种任务,而且可以逐步从示例中“训练”来执行这些任务。
当我们制作一个神经网络来区分猫和狗时,我们不必有效地编写一个程序来(比如)明确地找到胡须;相反,我们只需展示许多关于什么是猫和什么是狗的例子,然后让网络从中“机器学习”如何区分它们。
关键在于训练过的网络会从展示的特定示例中“泛化”。就像我们上面看到的那样,网络不仅仅是识别它展示的一个猫图像的特定像素模式;相反,神经网络以某种我们认为是“一般猫”的基础来区分图像。
那么神经网络训练实际上是如何工作的呢?基本上,我们一直在尝试找到使神经网络成功复制我们提供的示例的权重。然后,我们依赖神经网络以“插值”(或“泛化”)的方式在这些示例之间以“合理”的方式进行操作。
我们来看一个比上面的最近点问题更简单的问题。让我们尝试让神经网络学习这个函数:
对于这个任务,我们需要一个只有一个输入和一个输出的网络,就像:
但是我们应该使用什么样的权重等等?对于每一组可能的权重,神经网络都会计算一些函数。例如,这里是它对一些随机选择的权重集合所做的事情:
是的,在这些情况中,我们可以清楚地看到它甚至没有接近复制我们想要的功能。那么我们如何找到能够复制函数的权重呢?
基本思想是提供大量“输入→输出”示例供“学习”,然后尝试找到能够复制这些示例的权重。以下是逐渐增加示例后的结果:
在这个“训练”过程中,网络中的权重会逐渐调整,最终我们会得到一个成功复现我们想要的功能的网络。那么我们如何调整权重呢?基本思想是在每个阶段看一下我们离想要的功能有多远,然后以更接近的方式更新权重。
为了找出“我们离目标有多远”,我们计算通常称为“损失函数”(有时称为“成本函数”)的东西。在这里,我们使用一个简单的(L2)损失函数,它只是我们得到的值与真实值之间差值的平方和。我们看到的是,随着训练过程的进行,损失函数逐渐减少(遵循某种对不同任务而言不同的“学习曲线”)—直到我们达到一个网络(至少在很好的近似情况下)成功地复制我们想要的函数的点:
好的,现在要解释的最后一个关键部分是如何调整权重以减少损失函数。正如我们所说,损失函数给出了我们得到的值与真实值之间的“距离”。但是我们得到的“值”是由当前版本的神经网络和其中的权重在每个阶段确定的。现在想象一下,权重是变量,比如说 w。我们想要找出如何调整这些变量的值以最小化依赖于它们的损失。
例如,想象一下(对实际使用的典型神经网络进行了难以置信的简化),我们只有两个权重 w 1 和 w 2 。然后,我们可能会有一个损失函数,它关于 w 1 和 w 2 的形式如下:
数值分析提供了各种技术,用于在这种情况下找到最小值。但典型的方法只是逐渐沿着从先前的 w 1 ,w 2 开始的最陡下降路径前进。
就像水流经山脉一样,这个过程的唯一保证是最终会达到表面的某个局部最小值(“山湖”);它很可能不会达到最终的全局最小值。
并不明显,能够在“权重景观”上找到最陡下降路径是可行的。但微积分来拯救。正如我们上面提到的,人们总是可以将神经网络视为计算数学函数——这取决于其输入和权重。但现在考虑对这些权重进行微分。事实证明,微积分的链式法则实际上让我们能够“解开”神经网络中连续层所做的操作。结果是,我们可以——至少在某种局部近似中——“反转”神经网络的操作,并逐渐找到最小化与输出相关的损失的权重。
上面的图片显示了我们可能需要在不切实际简单情况下只有 2 个权重的情况下进行的最小化操作。但事实证明,即使有更多的权重(ChatGPT 使用了 1750 亿个),仍然可以进行最小化操作,至少在某种程度上进行近似。事实上,“深度学习”在 2011 年左右发生的重大突破与发现有关,即在某种意义上,当涉及到大量权重时,进行(至少近似)最小化操作可能比涉及相当少的权重时更容易。
换句话说,有点违反直觉的是,用神经网络解决更复杂的问题可能比解决更简单的问题更容易。这种现象的大致原因似乎是,当有很多“权重变量”时,就会有一个高维空间,有“许多不同的方向”可以引导到最小值,而当变量较少时,更容易陷入局部最小值(“山湖”),从中没有“方向可以走出去”。
值得指出的是,在典型情况下,有许多不同的权重集合,它们都会产生几乎相同性能的神经网络。通常在实际的神经网络训练中会有很多随机选择,导致“不同但等效的解决方案”,就像这些一样:
但是每个这样的“不同解决方案”都会至少有稍微不同的行为。如果我们要求在我们提供训练示例的区域之外进行“外推”,我们可能会得到截然不同的结果。
但哪一个是“正确”的呢?实际上没有办法说。它们都“与观察到的数据一致”。但它们都对应于不同的“内在”方式来“思考”如何“超越常规”。对我们人类来说,有些可能看起来比其他的“更合理”。
- Author:NotionNext
- URL:https://tangly1024.com/article/ChatGPT%20%E6%AD%A3%E5%9C%A8%E5%81%9A%E4%BB%80%E4%B9%88%E2%80%A6%E2%80%A6%E4%B8%BA%E4%BB%80%E4%B9%88%E5%AE%83%E6%9C%89%E6%95%88%EF%BC%9F
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!