第 4 章:神经网络如何“学会”东西

开篇问题

你已经知道大模型处理的是 Token,也知道语言模型的目标是根据上下文预测下一个 Token。但一个更底层的问题随之出现:

模型最开始并不会写代码、不会翻译、不会总结,甚至不知道“苹果”和“水果”有什么关系。它只是一些随机初始化的数字。训练之后,它为什么能把输入映射成看起来有意义的输出?

这一章不要求你有机器学习背景。我们会用开发者熟悉的“函数”“参数”“测试反馈”“逐步调参”来理解神经网络学习的本质。

本章你会理解什么

读完本章,你应该能理解:

  • 神经网络本质上是一个带大量参数的函数。
  • “学习”不是模型获得意识,而是参数被持续调整。
  • 损失函数如何把“错得多不多”变成一个可优化的数字。
  • 梯度下降为什么像一次次沿着错误变小的方向改代码。
  • 为什么大模型训练需要海量数据、算力和多轮迭代。

核心概念

神经网络是一个可调函数

在程序里,我们经常写这样的函数:

function score(input: Input): Output {
  return someLogic(input);
}

普通业务函数的逻辑由开发者直接写死。神经网络也可以看成一个函数:

output = model(input, parameters)

区别在于,神经网络的大部分逻辑不是人手写的 if/else,而是藏在一组参数里。训练的目标就是找到一组参数,让这个函数在大量样本上表现得足够好。

对语言模型来说,输入可以是一串 Token,输出通常是“下一个 Token 的概率分布”。例如输入:

今天天气很

模型不会只输出一个词,而是输出一个概率表:

好: 0.32
热: 0.21
冷: 0.08
...

训练就是不断调整参数,让真实下一个 Token 的概率尽量变高。

参数是模型内部的“可学习配置”

你可以把参数理解成一个规模极大的配置文件。传统配置文件可能只有几十项:

{
  "timeout": 3000,
  "retry": 2
}

神经网络的参数可能有几十亿、几千亿项。它们不是人直接读写的业务含义,而是大量矩阵中的数字。每个数字本身很难解释,但这些数字组合起来,就决定了模型如何处理输入。

这也是为什么不要把神经网络理解成“数据库”。它不是把训练样本逐条存进去,然后查询出来。它更像是从样本中压缩出一套复杂的映射规则。

损失函数把错误变成数字

如果模型预测“下一个 Token 是 的概率为 0.32”,而训练数据里的正确答案确实是 ,那这次预测还不错,但还可以更自信。如果正确答案是 ,而模型给 的概率很低,那就错得更多。

损失函数负责把这种“错得多不多”变成一个数字:

预测越接近答案,loss 越小
预测越偏离答案,loss 越大

开发者可以把 loss 类比成测试失败报告中的一个分数。分数越高,说明当前实现越不符合目标行为。

梯度告诉参数该往哪边改

知道错了还不够,模型还需要知道怎么改。梯度就是这个“修改方向”的信号。

如果某个参数稍微变大一点,loss 会下降,那么训练就倾向于让它变大。如果某个参数变大导致 loss 上升,训练就倾向于让它变小。大量参数一起调整,就形成了梯度下降。

这不是一次改对,而是很多次小步更新:

看一批样本
计算预测
计算 loss
计算梯度
微调参数
再看下一批样本

大模型训练就是这个过程被放大到极端规模。

机制拆解

第一步:把输入变成向量

神经网络不能直接处理字符串。Token 会先被转换成向量,也就是一组数字。

例如:

"猫" -> [0.12, -0.35, 0.88, ...]
"狗" -> [0.10, -0.31, 0.82, ...]
"数据库" -> [-0.44, 0.09, 0.17, ...]

这些向量不是人工定义的标签,而是在训练中逐渐学出来的。训练后,语义相近或用法相近的 Token,向量往往会在某些方向上接近。

第二步:一层层变换信息

神经网络由很多层组成。每一层接收上一层的向量,做一次变换,再交给下一层。

可以把它想成一个多阶段编译流程:

原始 Token
-> Token 向量
-> 低层特征
-> 中层组合关系
-> 高层上下文表示
-> 下一个 Token 概率

这只是帮助理解的类比,不代表每一层都有清晰可命名的职责。真实模型里的表示是分布式的:一个概念可能分散在许多参数和许多维度里。

第三步:预测下一个 Token

语言模型训练时常见的任务是 next token prediction,也就是给定前文,预测下一个 Token。

训练样本可以从普通文本中自动构造:

输入:大模型的核心能力来自
答案:训练

同一句话还可以切成很多训练位置:

输入:大
答案:模型

输入:大模型
答案:的

输入:大模型的
答案:核心

这就是语言模型能利用海量文本训练的原因之一:文本本身就提供了监督信号。

第四步:用反向传播更新参数

预测完成后,模型会计算 loss。接着,反向传播会从输出层一路往回计算每个参数对 loss 的影响。

你不需要掌握反向传播的数学细节,但需要理解它解决的问题:

当前错误由哪些参数共同造成?
每个参数应该朝哪个方向微调?
每个参数应该改多少?

一次更新只会改变参数的一小部分数值。训练足够久以后,模型的整体行为才会发生明显变化。

第五步:从局部预测积累出复杂能力

看上去,预测下一个 Token 是一个很简单的任务。但要在复杂文本里持续预测正确,模型必须学到很多东西:

  • 词语搭配:什么词经常跟在什么词后面。
  • 语法结构:主谓宾、括号闭合、代码缩进。
  • 事实关联:巴黎和法国、HTTP 和状态码。
  • 推理模式:如果前文给出条件,后文应该满足条件。
  • 风格约束:正式、口语、技术文档、诗歌等。

模型不是被显式教会这些能力,而是在降低预测错误的过程中,被迫形成有用的内部表示。

开发者常见误解

误解一:神经网络是在记忆所有训练文本

训练确实可能带来记忆,尤其是重复出现、格式固定或高度独特的文本。但神经网络的主要机制不是键值查询,而是参数化的函数逼近。

更准确的说法是:模型从训练数据中学习统计规律和表示结构,同时也可能在某些情况下记住局部片段。

误解二:参数越多,模型就一定越聪明

参数规模提供了更大的表达能力,但能力还取决于数据质量、训练方法、模型结构、优化稳定性和推理时的上下文。一个巨大的模型如果训练数据混乱,或者训练目标设计不当,也可能表现很差。

参数多像是给程序更多可配置空间,但空间本身不等于正确配置。

误解三:loss 降低就代表模型真正理解了

loss 是训练目标下的数值指标。它降低说明模型更擅长完成训练任务,但不自动等于人类意义上的理解。

开发者更应该把它看成“某个目标函数下的拟合程度”。至于模型是否具备稳定推理、抽象泛化或可靠遵循指令,还需要额外评估。

误解四:训练像写规则,模型按规则执行

传统程序的行为来自显式规则。神经网络的行为来自参数组合。你很难指出某个具体参数代表“知道 JavaScript 闭包”,也很难用一条规则解释模型的全部输出。

这也是大模型强大但不完全可控的根源之一。

小实验/思考实验

实验一:用一个数字拟合一个规则

想象你只有一个参数 w,模型的输出是:

output = input * w

训练数据是:

1 -> 2
2 -> 4
3 -> 6

如果 w = 0.5,模型会输出 0.5, 1, 1.5,明显偏小。loss 会很高。训练会发现:让 w 变大可以降低错误,于是不断把 w 往 2 的方向推。

真实神经网络只是把这个过程扩展到大量参数、非线性变换和复杂数据。

实验二:把模型想成一个自动调参系统

假设你写了一个搜索排序函数,有 100 个权重:

score = 0.3 * titleMatch + 0.2 * freshness + ...

如果每次用户点击都能告诉你排序好不好,你就可以根据反馈调整权重。神经网络训练与此相似,只是:

  • 权重数量巨大。
  • 中间计算更复杂。
  • 调参方向由梯度自动计算。
  • 目标不是单一业务规则,而是大规模预测任务。

本章小结

神经网络不是魔法,也不是一个显式规则库。它是一个由大量参数控制的函数。训练时,模型先根据输入做预测,再用损失函数衡量错误,通过梯度下降一点点调整参数。

对语言模型来说,“预测下一个 Token”提供了一个简单但强大的训练目标。为了把这个任务做好,模型会逐渐形成对词语、语法、语义、上下文和世界知识的内部表示。后面几章要讨论的 Transformer,就是让这种表示学习在长序列上变得更有效的关键结构。

自测题

  1. 为什么说神经网络是一个“带大量参数的函数”?
  2. 损失函数在训练中承担什么角色?
  3. 梯度下降为什么不是一次性找到正确答案,而是很多次小步更新?
  4. 语言模型为什么可以从普通文本中构造训练信号?
  5. “模型学会了规律”和“模型记住了样本”有什么区别?