- • 机器学习是实现人工智能的一种主流方法, 深度学习是机器学习一个分支, 大语言模型是深度学习的一个应用。
- • 本文主要是 MIT 6.390 Introduction to Machine Learning [1] 的学习笔记。
一、从一个具体问题开始
现在有 5 套房子最近的交易数据:
那如何预测一套 85 平米房子的成交价?
有一种做法是:在坐标系里画出这 5 个点,拿一条直线去拟合,然后在这条直线上去读出 85 对应的值。这条直线就是最简单的模型——线性回归(linear regression):
是输入(面积), 是斜率(面积每增加一个单位,价格变化多少), 是截距。一维情况下这就是一条直线。后面遇到多维输入时(比如同时考虑面积和楼层), 就变成向量内积——把每个输入分别乘以各自的权重再加起来。
如何找最好的那条线?可以定义一个目标函数来衡量拟合的好坏:
是预测值跟真实值之间偏差的平方,在所有训练样本上取平均。 越小拟合越好。找到使 最小的 和 ,就找到了最好的直线——这是一个优化问题。线性回归比较特殊,这个优化问题有解析解(closed-form solution)——直接用公式算出最优参数,不需要迭代。
拿这 5 个点算出来,,。输入 85 平米:
这就是机器学习在做的事:从数据里学出规律(体现为参数),拿去预测新输入下的结果。教材把这个过程概括成一条流水线 [1]:
训练数据 ,算法从模型类 里挑一个模型 出来,拿去预测新数据。教材里"模型"和"假设"混着用 [1],本文统一用"模型"。
二、直线不是弯的
再回看那 5 个数据点:面积从 60 到 100 每增加 10 平米,价格分别增加 39、36、42、36 万。大体均匀,所以直线拟合得还行。但如果数据是下面这样呢:
面积从 40 到 60,价格增加了 130 万;从 100 到 120 只增加了 10 万。这些点不在一条直线上,而是一条逐渐变平的曲线。直线怎么拟合都会有系统性偏差。
怎么办?可以给输入进行改造:除了 ,再造一个 ,把 当作新的输入,然后照样做线性回归 [1]:
画出来是一条抛物线,能拟合弯曲的数据了。而对参数 来说,每个参数仍然只出现一次,所以线性回归的整套工具直接能用。这个思路叫特征变换(feature transformation)[1]。
问题是 还是得人来设计。用 还是 还是其它函数?选什么变换取决于对问题的理解——有时候靠经验,有时候靠专业领域知识(比如是否需要考虑 KCL/KVL)。这在机器学习里叫特征工程(feature engineering)[1]。
三、让机器自己学特征——神经网络
能不能不手工设计 ,让模型自己从数据里学?神经网络(neural network)干的就是这件事:把特征变换也变成可学习的参数,训练时跟着一起优化。网络的整体结构——多少层、每层多宽、用什么连接方式——目前大多还是人来设计的。
最小的结构叫神经元(neuron)。一个神经元内部做两个运算:先是跟线性回归一样的加权求和:
然后过一个激活函数 :
为什么需要激活函数?没有它的话,叠再多层做的都是线性变换,一百层也跟一层没区别。激活函数引入非线性,可以打破这个限制。常用的比如 ReLU(Rectified Linear Unit,),负数变零正数不变——简单,但足以让多层网络的表达力远超单层。
把神经元堆成一层再叠多层就是深度神经网络(DNN)。一层里的所有神经元同时工作、各自做自己的"加权求和 + 激活"——写成矩阵形式,权重向量 变成权重矩阵 (每列对应一个神经元),偏置 变成偏置向量 。 层网络逐层算( 是输入):
这个公式就是把一层里所有神经元的运算打包成了一次矩阵运算。每一层可以理解为一次自动的特征变换。
数据从输入层依次通过每一层到达输出层,这个从前往后的计算过程叫前向传播(forward propagation)。
但神经网络没有解析解,需要迭代逼近。目前最常用的是梯度下降(gradient descent)及其变体:
是 对 的梯度(gradient),指向 增长最快的方向。公式里减去它,就是反过来往 下降最快的方向走, 控制步子多大。反复走直到 到达驻点。
驻点是不是最优解?这取决于目标函数的形状。如果目标函数是凸函数(像碗一样,碗口朝上,从任何方向看都往中间低),驻点就是全局最优(严格凸则唯一)。线性回归的目标函数恰好是凸的,但神经网络的通常不是——地形凹凸不平,有很多局部洼地,梯度下降可能停在局部最小甚至鞍点上。
知道了方向怎么走,还要解决梯度怎么算。多层网络的梯度通过反向传播(backpropagation)来算——链式法则从输出端往回乘。实际跑的时候用 SGD(随机梯度下降)或 Adam(自适应学习率的改进版),每次只拿一小批数据算梯度——快,但有噪声,最后未必找到全局最优。用梯度下降反复调参数让 尽量小,教材里把这个过程叫训练(training)[1]。
四、从数字到语言——DNN 不够用的地方
到目前为止处理的都是"一组数字进去、一个数字出来"这类问题。换到语言处理,问题的性质变了。
全连接 DNN 把输入当成一个扁平的向量,缺乏对序列关系的显式建模——不知道词与词之间该有什么依赖,也没有机制捕捉相对位置。而且实际文本长度不固定,固定拼接很不方便(短句补零,长句截断)。
用一个简单示例看。词表三个词,Embedding 各为一个标量:猫=1,吃=2,鱼=3。"猫 吃 鱼"拼成 ,"鱼 吃 猫"拼成 ——意思完全不同。
一层全连接输出 ,但 是训练后固定的——不管输入什么,位置 1 永远乘 ,位置 3 永远乘 。网络能做的只是给不同位置分配不同的固定权重,没法根据"吃"这个动词去动态决定该关注哪个位置。
每个位置的计算方式训练后就固定了,不随内容调整。指代消解("它"指谁?)、长距离依赖等语言现象,都需要模型根据内容动态决定信息怎么流动。
Transformer [2] 的做法是把关于序列数据的先验知识直接设计进网络结构里——不是从数据里学,而是架构本身就假定了"输入是有顺序的序列,词和词之间需要互相参照"。教材把这种做法叫结构先验(inductive bias)[1]。Transformer 编进了两个核心设计。
第一个是自注意力(self-attention):每个词去"查看"序列里所有其他词,根据内容决定从谁那里获取多少信息——正是 DNN 缺少的能力。具体做法是:输入 (每一行是一个词的 Embedding)分别乘以三个可学习的权重矩阵 ,得到三组向量 [2]:
Q(Query,"我在找什么")、K(Key,"我能匹配什么")、V(Value,"匹配上了拿到的内容")。然后用 Q 和 K 算相关度,决定每个词该关注谁:
算每对 token 的相关度,softmax 归一化成注意力系数,对 V 加权求和。 是训练时学到的固定参数,但注意力系数随输入而变——这正是关键所在。
回到猫吃鱼的例子:假设"吃"的 Q 总是跟施事者的 K 内积大——"猫吃鱼"里"吃"关注"猫","鱼吃猫"里"吃"关注"鱼"。同样的参数,不同的句子,不同的注意力。
第二个是位置编码(positional encoding)。self-attention 本身不携带顺序信息——交换输入顺序只会让输出同步重排 [2]。位置编码把位置信息注入 Embedding,让模型同时具备"动态关注内容"和"感知位置"。
五、语言模型怎么训练——标签从哪来
前面的房价例子里每条数据都带标准答案(成交价)——这叫监督学习(supervised learning)。传统做法是人工标注:邮件让人标"垃圾/正常",图片让标注员分类(ImageNet 上千万张图就是这么标的)。共同特点:贵。
大语言模型用自监督学习(self-supervised learning):标签从文本自身构造。"今天天气很好"拆成:
本质上还是监督学习,只不过标签按位置顺移一格自动得到。因为不需要人工标注,数据规模的瓶颈就去掉了——互联网上有多少文本就能用多少,所以能推到万亿 token 的规模。
这意味着模型学的不是"问题 → 答案",而是:给定前面所有词,下一个词的概率分布。如果训练数据里"今天天气"后面既跟过"很好"也跟过"怎么样",模型学到的是一个分布——不存在唯一正确的下一个词。
训练过程和前面一样:梯度下降 + 反向传播,在万亿 token 上不断重复"猜下一个词 → 算损失 → 反向传播 → 调参数"。
下篇讨论评估、过拟合、推理解码,以及大语言模型为什么会出错。
参考文献
[1] MIT 6.390 课程笔记,Introduction to Machine Learning,https://introml.mit.edu/notes/
[2] Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., & Polosukhin, I. (2017). Attention Is All You Need. NeurIPS 2017.