面向哲思的编程与架构
笔记哲思阅读动态搜索RSS 订阅
切换到深色模式
搜索
RSS 订阅
切换到深色模式
© 2026 Vic Chen. All rights reserved.CC BY-NC-ND 4.0
← 笔记
从预测一个词开始(一):机器学习到底在学什么

从预测一个词开始(一):机器学习到底在学什么

2026年3月2日4,86314分钟

系列开篇,从房价回归讲起,把机器学习最基本的动作「拟合一个函数」讲透:模型结构、损失函数、梯度下降、向量矩阵、神经网络为何要叠非线性、自动微分怎么把求导交给机器。这些都是地基,末尾埋下贯穿全系列的脊柱:一切语言模型都在做同一件事,估计「下一个词的概率分布」。


目录
  • TL;DR
  • 1. 模型:一个被数据选出来的函数
  • 2. 求解损失函数:从手解到求导
  • 3. 向量与矩阵:当一个特征不够用
  • 4. 神经网络:为什么要叠非线性
  • 5. 梯度下降:当手解不再可能
  • 6. 自动微分:把求导交给机器
  • 7. 收拢:地基已经铲平
目录
  • TL;DR
  • 1. 模型:一个被数据选出来的函数
  • 2. 求解损失函数:从手解到求导
  • 3. 向量与矩阵:当一个特征不够用
  • 4. 神经网络:为什么要叠非线性
  • 5. 梯度下降:当手解不再可能
  • 6. 自动微分:把求导交给机器
  • 7. 收拢:地基已经铲平
目录
  1. TL;DR
  2. 1. 模型:一个被数据选出来的函数
  3. 2. 求解损失函数:从手解到求导
  4. 3. 向量与矩阵:当一个特征不够用
  5. 4. 神经网络:为什么要叠非线性
  6. 5. 梯度下降:当手解不再可能
  7. 6. 自动微分:把求导交给机器
  8. 7. 收拢:地基已经铲平
机器学习语言模型
相关文章
  • 01
    从预测一个词开始(二):词怎么变成数2026/03
  • 02
    概率视角下的机器学习(三):贝叶斯概念学习与朴素贝叶斯2026/01
  • 03
    概率视角下的机器学习(二):概率论工具箱2026/01
← 上一篇概率视角下的机器学习(三):贝叶斯概念学习与朴素贝叶斯
下一篇 →从预测一个词开始(二):词怎么变成数

评论

© 2026 Vic Chen · 面向哲思的编程与架构CC BY-NC-ND 4.0

TL;DR

这是《从预测一个词开始》系列的第一篇。整个系列的文章(Chen 注:主要参考 Andriy Burkov 的《The Hundred-Page Language Models Book: Hands-On with PyTorch》,2025 年出版。原书延续作者上一本《The Hundred-Page Machine Learning Book》的极简路线:用尽量少的篇幅讲清楚一个领域最核心的东西,聚焦语言模型,并覆盖从 n-gram 到大语言模型微调对齐的完整链路。)会把现代语言模型讲清楚。

一切语言模型都在做同一件事:估计「下一个词的概率分布」,即 p(next∣context)p(\text{next}\mid\text{context})p(next∣context)。这也是本系列文章的核心主线。n-gram 用计数估、RNN 用循环状态估、Transformer 用注意力估,训练是在拟合这个分布,采样是在从这个分布里取样。后面几篇会反复回指这句话。

但在谈「下一个词的分布」之前,得先把更基本的问题铲平:机器学习本身在干什么?本篇文章不含任何语言模型的内容,却是唯一一处把模型、损失、梯度下降、神经网络这些地基词汇讲透的地方。语言模型说到底只是一种特殊的函数,用来学习特殊的分布,但它依然要用这套地基去训练。这一篇就把地基铲平,末尾埋下脊柱的第一个锚点。


1. 模型:一个被数据选出来的函数

机器学习要解决的问题,本质上可以写成一个函数:

y=f(x)y = f(x)y=f(x)

xxx 是输入,yyy 是输出,fff 是从输入到输出的映射规则。机器学习不凭空发明这个 fff,而是先收集一批 (x,y)(x, y)(x,y) 例子,再从数据里「选出」一个足够好的 fff。

拿一个具体问题落地:用房子的面积估算房价。数据集是一批 (面积, 房价) 对,比如 {(150,200),(200,600),… }\{(150, 200), (200, 600), \dots\}{(150,200),(200,600),…},面积单位是平方米,房价单位是千。给定一个新房子:面积 250 平方米,我们想要 fff 能给出一个合理的房价。

穷举所有可能的函数不现实,所以先钦定一个结构,只在这个结构里找最优参数。最简单的结构是线性函数:

f(x)=defwx+b(1.1)f(x) \overset{\text{def}}{=} wx + b \tag{1.1}f(x)=defwx+b(1.1)

这里 www 叫权重(weight),bbb 叫偏置(bias);本书统一用这两个词,不用「斜率」、「截距」等说法。确定 fff 只需要确定 www 和 bbb 这两个数。

ℹ
严格来说,wx+bwx + bwx+b 是仿射变换(affine transformation)而不是线性变换。真正的线性变换要求 b=0b = 0b=0。但机器学习里习惯上只要参数以「相乘再相加」的方式出现(不互相乘、不取幂、不塞进 exe^xex 之类的函数里),就叫它「线性」。这套用词本系列文章都会沿用。

www 和 bbb 可以取无穷多组值,需要一个标准来衡量哪组最好。最自然的标准是让 fff 的预测尽量贴近真实房价。给定一个例子 (xi,yi)(x_i, y_i)(xi​,yi​),模型的预测是 ,定义为(squared error):

err(y^i,yi)=def(y^i−yi)2(1.2)\text{err}(\hat{y}_i, y_i) \overset{\text{def}}{=} (\hat{y}_i - y_i)^2 \tag{1.2}err(y^​i​,yi​)

预测完全准确时误差为 0;偏差越大,误差越大;平方保证误差不会因为「高估」和「低估」而互相抵消抹平(Chen 注:误差 $\hat{y}_i-y_i$ 本身带符号:高估为正、低估为负。若不平方直接求和,一个时而高估、时而低估的坏模型可能正负抵消,算出很小的平均误差,掩盖真实偏差。平方把符号抹掉,只留下偏离幅度,才能如实衡量整体预测质量。)。

把整个数据集 {(xi,yi)}i=1N\{(x_i, y_i)\}_{i=1}^{N}{(xi​,yi​)}i=1N​(NN 是样本数)的平均误差记作一个关于 的函数 :

J(w,b)=def(wx1+b−y1)2+(wx2+b−y2)2+⋯+(wxN+b−yN)2N(1.3)J(w, b) \overset{\text{def}}{=} \frac{(wx_1+b-y_1)^2+(wx_2+b-y_2)^2+\cdots+(wx_N+b-y_N)^2}{N} \tag{1.3}J(w,b)=defN

这个 J(w,b)J(w, b)J(w,b) 就是损失函数(loss function),具体在这里就是均方误差(mean squared error,MSE)。数据集里的 xi,yix_i, y_ixi​,yi​ 都已知,唯二的未知量是 www 和 。我们要找的最优参数 ,就是让 最小的那组取值。

✓
这是全篇最重要的转换:「找一个好模型」被转换为「求一个函数的最小值」,一个纯粹的数学优化问题。后面梯度下降要解决的,正是这个问题在参数太多、无法手解时怎么办。

2. 求解损失函数:从手解到求导

J(w,b)J(w, b)J(w,b) 是关于 w,bw, bw,b 的二次函数,微积分保证它只有一个最小值。求最优值的标准做法:对每个变量求偏导,因为函数在极值点处,切线是水平的,因此令偏导数等于 0:

{∂J∂w=0∂J∂b=0\begin{cases} \dfrac{\partial J}{\partial w} = 0 \\[4pt] \dfrac{\partial J}{\partial b} = 0 \end{cases}⎩⎨⎧​

拿一个三个样本的具体数据集练手:(x1,y1)=(150,200)(x_1,y_1)=(150,200)(x1​,y1​)=(150,200),(x2,y2)=(200,600)(x_2,y_2)=(200,600)(x,。代入 (1.3) 式:

J(w,b)=def(150w+b−200)2+(200w+b−600)2+(260w+b−500)23J(w,b) \overset{\text{def}}{=} \frac{(150w+b-200)^2+(200w+b-600)^2+(260w+b-500)^2}{3}J(w,b)=def3(150w+

J(w,b)J(w,b)J(w,b) 是三层函数的复合(composition):先算三个关于 w,bw,bw,b 的线性函数 d1,d2,d3d_1, d_2, d_3d1​,d2​(如 ),再各自平方得到 ,最后取平均得到 。求偏导要用到(chain rule):复合函数 对 的导数,等于 对 的导数乘上 对 的导数。配合(求和的导数等于导数的求和)与(常数提出来不影响求导)两条规则,逐层展开:

∂J∂w=13(2⋅150(150w+b−200)+2⋅200(200w+b−600)+2⋅260(260w+b−500))\frac{\partial J}{\partial w} = \frac{1}{3}\Big(2 \cdot 150(150w+b-200) + 2 \cdot 200(200w+b-600) + 2 \cdot 260(260w+b-500)\Big)∂w∂J​=3 ∂J∂b=13(2(150w+b−200)+2(200w+b−600)+2(260w+b−500))\frac{\partial J}{\partial b} = \frac{1}{3}\Big(2(150w+b-200) + 2(200w+b-600) + 2(260w+b-500)\Big)∂b∂J​=31​

令两式为零、化简、解方程组,得到 w∗=2.58w^* = 2.58w∗=2.58,b∗=−91.76b^* = -91.76b∗=−91.76。也就是说,这三个房子的数据支持的最优模型是 f(x)=2.58x−91.76f(x) = 2.58x - 91.76f(x)=。代回式 1.3 算出训练损失 ,其平方根 ,即平均预测误差约。

ℹ
写出复合函数的结构、逐层套链式法则、令偏导为零解方程组,这三步是本篇能纯手算出闭式解的原因:数据点少、模型是线性的、损失是二次的。三者缺一,就再也没有闭式解,只能靠下面的梯度下降去迭代逼近。

到这里,监督学习的四步流程已经完整走了一遍:一是收集数据集;二是定义模型结构(如 y=wx+by=wx+by=wx+b);三是定义损失函数(如式 1.3);四是最小化损失。本篇第 1、2 节其实只做了第一到到第三步和「手解」版的第四步。语言模型的参数动辄十亿百亿,手解无从谈起。第 5 节的梯度下降,就是第四步在真实规模下唯一可行的做法。


3. 向量与矩阵:当一个特征不够用

估房价光靠面积不够,还得看卧室数、建成年份等。假设用面积和卧室数两个特征的话,输入就变成了一个特征向量:

x=def[x(1)x(2)]\boldsymbol{x} \overset{\text{def}}{=} \begin{bmatrix} x^{(1)} \\ x^{(2)} \end{bmatrix}x=def[x(1)x

本系列文章约定向量用小写斜粗体字母(如 x\boldsymbol{x}x、w\boldsymbol{w}w),矩阵用大写斜粗体字母(如 X\boldsymbol{X}X、W\boldsymbol{W}W),标量用斜体字母(如 xxx、DDD)。两个特征的权重也要打包成向量 w\boldsymbol{w},线性模型写成向量形式:

y=w⋅x+b(1.4)y = \boldsymbol{w} \cdot \boldsymbol{x} + b \tag{1.4}y=w⋅x+b(1.4)

w⋅x\boldsymbol{w} \cdot \boldsymbol{x}w⋅x 是点积(dot product),定义为 w⋅x=def∑j=1Dw(j)x(j)\boldsymbol{w} \cdot \boldsymbol{x} \overset{\text{def}}{=} \sum_{j=1}^{D} w^{(j)} x^{(j)}w⋅x=def∑, 是输入维度。点积把两个同维向量压缩成一个标量,是「加权求和」这个动作最紧凑的写法。

ℹ
点积在直觉上还有一层意思:两个向量 x,y\boldsymbol{x}, \boldsymbol{y}x,y 夹角 θ\thetaθ 的余弦,正好等于 cos⁡(θ)=x⋅y∥x∥∥y∥\cos(\theta) = \dfrac{\boldsymbol{x}\cdot\boldsymbol{y}}{\lVert \boldsymbol{x}\rVert \lVert \boldsymbol{y}\rVert}cos(θ)=,即点积除以两个向量的长度(,norm,向量各分量平方和再开根号)。这个「用点积算相似度」的技巧,第 2 篇讲词嵌入时会正式派上用场。词向量之间的,用的正是这条公式。

特征一多,参数个数就会膨胀到人手解不动的规模,而且高维空间里也没法用眼睛判断数据是否符合线性假设。矩阵把这套运算进一步打包:一个 mmm 行 nnn 列的矩阵 A\boldsymbol{A}A,可以把一整层神经网络的权重集中表示,配合矩阵乘法、矩阵-向量乘法,用 BLAS、cuBLAS 这类优化过的线性代数库高效计算,这正是神经网络能训练得起来的工程基础:把「逐个数循环相乘再求和」的操作,交给专门为矩阵运算做过硬件加速的库去执行。


4. 神经网络:为什么要叠非线性

线性模型有一个硬伤:多个线性函数复合起来,结果还是线性。设 y1=f1(x)=defa1xy_1 = f_1(x) \overset{\text{def}}{=} a_1 xy1​=f1​(x)=defa,,代入化简:

y2=a2y1=a2(a1x)=(a2a1)xy_2 = a_2 y_1 = a_2(a_1 x) = (a_2 a_1) xy2​=a2​y1​=a

a2a1a_2 a_1a2​a1​ 就是个新常数,y2y_2y2​ 依然是 xxx 的线性函数。不管叠多少层纯线性变换,表达能力都不会超过一层。要跳出这个天花板,得在每层线性变换后插入一个固定的非线性函数,称为激活函数(activation):

y=ϕ(wx+b)y = \phi(wx+b)y=ϕ(wx+b)

三个常见选择:

  • ReLU(rectified linear unit):ReLU(z)=defmax⁡(0,z)\text{ReLU}(z) \overset{\text{def}}{=} \max(0, z)ReLU(z)=defmax(0,z),输出非负,是当今神经网络里最常用的激活;
  • Sigmoid:σ(z)=def11+e−z\sigma(z) \overset{\text{def}}{=} \dfrac{1}{1+e^{-z}}σ(z),输出压缩到 ,适合二分类;
图 1. 三种常见激活函数示意图
(图片来源:Andriy Burkov, The Hundred-Page Language Models Book, §1.5)
图 1. 三种常见激活函数示意图
(图片来源:Andriy Burkov, The Hundred-Page Language Models Book, §1.5)

把带激活函数的单元逐层堆叠、彼此嵌套,就搭出了神经网络:y=f2(f1(x))=ϕ(c ϕ(ax+b)+d)y = f_2(f_1(x)) = \phi(c\,\phi(ax+b)+d)y=f2​(f1​(x))=ϕ(cϕ(ax+。每个非线性单元叫一个(artificial neuron),信息从输入到输出单向流动、不含循环的网络叫(feedforward neural network,FNN);一层里每个神经元都连接下一层所有神经元,叫(fully connected layer)或(multilayer perceptron,MLP)。

用简单的两层网络举例:输入是二维向量 x\boldsymbol{x}x,第一层用矩阵 W1\boldsymbol{W}_1W1​(3×23\times23×2)和向量 b1\boldsymbol{b}_1b1​ 把 变成三维输出:

y1=ϕ(W1x+b1)(1.6)\boldsymbol{y}_1 = \phi(\boldsymbol{W}_1 \boldsymbol{x} + \boldsymbol{b}_1) \tag{1.6}y1​=ϕ(W1​x+b

第二层用 W2\boldsymbol{W}_2W2​(1×31\times31×3)和标量 b2,1b_{2,1}b2,1​,把 y1\boldsymbol{y}_1 变成最终输出:

y2=ϕ(W2y1+b2,1)(1.7)y_2 = \phi(\boldsymbol{W}_2 \boldsymbol{y}_1 + b_{2,1}) \tag{1.7}y2​=ϕ(W2​y1​+

这套「矩阵乘向量再加激活函数」的模板,逐层叠加、层数越深、每层单元越多,模型就越能拟合复杂的高维数据,包括自然语言这种典型的高维数据。本书第 3 章讲的循环神经网络(recurrent neural network,RNN)会在这套前馈结构里加入循环连接,让网络能处理任意长度的序列;这是本系列第 4 篇的正题,这里先记住「前馈」和「循环」的分野。


5. 梯度下降:当手解不再可能

神经网络通常层数深、非线性函数套得多,损失函数早就不是能手解的二次函数了。这时候要用梯度下降(gradient descent)算法,通过迭代一步步逼近最小值。这也是包括语言模型在内几乎所有现代神经网络的训练方式。

换一个更贴近「分类」的例子来讲梯度下降:二分类(binary classification),判断一封邮件是否为垃圾邮件。数据集 {(xi,yi)}i=1N\{(\boldsymbol{x}_i, y_i)\}_{i=1}^N{(xi​,yi​)}i=1N​,。模型定义为:

y^=σ(w⋅x+b)(1.8)\hat{y} = \sigma(\boldsymbol{w} \cdot \boldsymbol{x} + b) \tag{1.8}y^​=σ(w⋅x+b)(1.8)

这个模型叫逻辑回归(logistic regression),尽管名字里有「回归」,但它做的是分类:sigmoid 把线性输出压缩到 (0,1)(0,1)(0,1),可以读作「属于正类的概率」。

ℹ
逻辑回归已经诞生 80 多年,至今仍是生产环境里最常用的算法之一,原因不是它多花哨,而是它简便、稳定、可解释。后面读到语言模型的分类应用(如第 6 篇 GPT-2 当分类器用)时会再遇到它的身影。

对应的损失函数是二元交叉熵(binary cross-entropy),也叫逻辑损失(logistic loss):

loss(y^i,yi)=def−[yilog⁡(y^i)+(1−yi)log⁡(1−y^i)](1.9)\text{loss}(\hat{y}_i, y_i) \overset{\text{def}}{=} -\big[y_i \log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i)\big] \tag{1.9}loss(y^​i​,y

验证两个极端:预测完全正确(yi=0,y^i=0y_i=0, \hat{y}_i=0yi​=0,y^​i​=0)时,损失为 −log⁡(1)=0;预测完全相反()时,损失趋向 。惩罚的方向是对的:越接近真相损失越小,越离谱损失越大。

要用梯度下降最小化这个损失,需要对每个参数求偏导。把 zi=w⋅xi+bz_i = \boldsymbol{w}\cdot\boldsymbol{x}_i+bzi​=w⋅xi​+b,损失是三层复合:zi→y^i=σ(zi)→loss(。用链式法则逐层展开,权重 和偏置 上的偏导数出乎意料地简洁:

∂ loss∂w(j)=1N∑i=1N(y^i−yi)⋅xi(j),∂ loss∂b=1N∑i=1N(y^i−yi)(1.11)\frac{\partial \,\text{loss}}{\partial w^{(j)}} = \frac{1}{N}\sum_{i=1}^{N}(\hat{y}_i-y_i)\cdot x_i^{(j)}, \qquad \frac{\partial\, \text{loss}}{\partial b} = \frac{1}{N}\sum_{i=1}^{N}(\hat{y}_i-y_i) \tag{1.11}∂w(j)
✓
这份简洁不是巧合。Sigmoid 和交叉熵都源自 eee:sigmoid 把值压进 (0,1)(0,1)(0,1) 用来表示概率,交叉熵把 [0,∞)[0,\infty)[0,∞) 当作惩罚的尺度。两者搭配求导时,指数和对数正好抵消,最后只剩一个线性表达式 y^i−yi\hat{y}_i - y_iy^,一个预测值减真实值如此朴素的东西。这种「设计对了,数学会自己变简单」的现象,后面读 softmax 配交叉熵(第 5 篇采样)时会再次出现。

把梯度打包成一个向量 ∇loss\nabla \text{loss}∇loss(包含所有参数的偏导数),梯度下降的迭代规则就是:

w(j)←w(j)−η∂ loss∂w(j),b←b−η∂ loss∂bw^{(j)} \leftarrow w^{(j)} - \eta \frac{\partial\, \text{loss}}{\partial w^{(j)}}, \qquad b \leftarrow b - \eta \frac{\partial\, \text{loss}}{\partial b}w(j)←w(j)−η

η\etaη 是学习率(learning rate),一个人为设定的超参数(hyperparameter,不是学出来的,是训练前手动设的),控制每步走多远。之所以用「减去梯度」而不是「加上」:梯度指向损失上升最快的方向,要最小化损失,就该往梯度的反方向走。η\etaη 太小则收敛慢,太大则可能在最小值附近来回震荡甚至发散。这条权衡,训练任何神经网络(包括语言模型)时都要面对。

完整流程的五个步骤:一是用当前参数算预测值;二是用式(1.11)算梯度;三是按学习率更新参数;四是算新的损失;五是重复步骤一到步骤四,直到损失收敛或达到预定迭代次数(步数,step)。


6. 自动微分:把求导交给机器

前两节手推了线性回归和逻辑回归这两次梯度,已经能感觉到了繁琐。真实的神经网络参数动辄百万、十亿计,手推梯度不现实。自动微分(automatic differentiation,简称 autograd)解决了这个问题:框架在执行前向计算时自动记录每一步运算,需要梯度时直接沿着记录反向套用链式法则,全程不需要人写一条求导公式。

用 PyTorch 实现上面的逻辑回归:

片段 1. 逻辑回归模型定义
import torch
import torch.nn as nn
import torch.optim as optim
 
model = nn.Sequential(
    nn.Linear(n_inputs, n_outputs),  # 对应 (1.8) 式里的 w·x+b
    nn.Sigmoid()                     # 对应 (1.8) 式里的 σ
)

nn.Linear(n_inputs, n_outputs) 就是式(1.8)里 w⋅x+b\boldsymbol{w}\cdot\boldsymbol{x}+bw⋅x+b 的封装。数据、模型、损失函数、优化器一起搭起来:

片段 2. 数据、损失函数与优化器
inputs = torch.tensor([
    [22, 25], [25, 35], [47, 80], [52, 95], [46, 82], [56, 90],
    [23, 27], [30, 50], [40, 60], [39, 







inputs 是一个 12×212 \times 212×2 的矩阵,即 12 个样本、每个样本 2 个特征(年龄、收入),对应用来预测是否会购买某商品。训练循环只需四行:

片段 3. 训练循环
for step in range(500):
    optimizer.zero_grad()                    # 清空上一步残留的梯度
    loss = criterion(model(inputs), labels)  # 前向传播,算损失
    loss.backward()                          # 反向传播,自动求梯度
    optimizer.step()                         # 按梯度更新参数

loss.backward() 这一行,就是自动微分登场的地方:PyTorch 在 model(inputs) 执行前向传播时,已经在背后搭好了一张计算图(computational graph),记录了每一步运算;backward() 沿着这张图反向套用链式法则,一次性把所有参数的梯度算出来,写进各参数的 .grad 属性。数据从输入到输出流动的过程叫前向传播(forward pass),沿着计算图反向求梯度的过程叫反向传播(backward pass),这个词也是深度学习最核心的算法名字。

ℹ
换模型只需要换 nn.Sequential 里的层,训练循环这四行完全不用动。这正是自动微分最实际的好处:写模型的人不用为每种新结构手推一份新的求导公式,框架帮你把这件事一次性解决了。第 3 篇之后我们会看到,无论 n-gram 之后的 RNN 还是 Transformer,用的都是同一套 loss.backward()。

7. 收拢:地基已经铲平

图2. 本篇内容结构——从函数到损失,从标量到向量矩阵,从线性到非线性,最后落到梯度下降与自动微分

这一篇没有出现任何「语言」或「词」,因为它讲的是所有监督学习共享的地基:模型是一个被数据选出来的函数。先钦定结构,再用损失函数衡量好坏,最后用梯度下降(在能手解的小问题上,直接解方程)找出最优参数;向量和矩阵是把这套计算压缩、加速的表示法;神经网络靠叠非线性摆脱了「复合线性还是线性」的天花板;自动微分让「求梯度」这件全书反复出现的动作,从人力劳动变成了框架自动完成的例行操作。

这些概念本身不专属于语言模型,但语言模型要解决的问题,同样可以写成 y=f(x)y = f(x)y=f(x) 的模样,只是 xxx 和 yyy 不再是面积和房价,而是文本。下一篇要做的第一件事,就是回答一个具体得多的问题:文字要怎么变成数,才能塞进这一篇讲的这套机器(向量、矩阵、损失函数、梯度下降)里?答案会从分词开始:把一段文字切成词或子词,一路走到词嵌入,也就是把每个词映射成一个向量。而这一篇里 y=f(x)y=f(x)y=f(x) 那个笼统的「拟合一个函数」,到下一篇会第一次演化成本系列真正的主角:拟合一个分布 p(。语言模型要学的,就是给定上文,下一个词该是什么的概率分布。这根脊柱,会贯穿本系列剩下的六篇。

y^i=f(xi)\hat{y}_i = f(x_i)
y^​i​=f(xi​)
预测误差
平方误差
=def
(y^​i​−
yi​)2
(1.2)
N
w,bw, bw,b
J(w,b)J(w, b)J(w,b)
(wx1​+b−y1​)2+(wx2​+b−y2​)2+⋯+(wxN​+b−yN​)2
​
(1.3)
bb
b
w∗,b∗w^*, b^*w∗,b∗
J(w,b)J(w, b)J(w,b)
∂w
∂J
​
=
0
∂b∂J​=0
​
2​
,
y2​
)
=
(200,600)
(x3,y3)=(260,500)(x_3,y_3)=(260,500)(x3​,y3​)=(260,500)
b
−
200
)2
+
(
200
w
+
b
−
600
)2
+
(
260
w
+
b
−
500
)2
​
,
d3​
d1=def150w+b−200d_1 \overset{\text{def}}{=} 150w+b-200d1​=def150w+b−200
err1,err2,err3\text{err}_1, \text{err}_2, \text{err}_3err1​,err2​,err3​
JJJ
链式法则
f(g(x))f(g(x))f(g(x))
xxx
fff
ggg
ggg
xxx
和的导数
常数倍导数
1
​
(
2
⋅
150(150w+
b−
200)+
2⋅
200(200w+
b−
600)+
2⋅
260(260w+
b−
500))
(
2
(
150
w
+
b−
200)+
2(200w+
b−
600)+
2(260w+
b−
500))
2.58
x
−
91.76
J(2.58,−91.76)≈15403.19J(2.58, -91.76) \approx 15403.19J(2.58,−91.76)≈15403.19
≈124.1\approx 124.1≈124.1
12.41 万元(Chen 注:取平方根是为了让误差单位与房价单位对齐(房价是千,误差单位是「千的平方」,开根号才能读成「千」),更好解读。)
(2)
​
]
w
j=1D​
w(j)
x(j)
DDD
∥x∥∥y∥
x⋅y
​
范数
余弦相似度
1
​
x
y2=f2(y1)=defa2y1y_2 = f_2(y_1) \overset{\text{def}}{=} a_2 y_1y2​=f2​(y1​)=defa2​y1​
2​
(
a1​
x
)
=
(a2​a1​)x
=def
1+e−z1​
(0,1)(0,1)(0,1)
  • Tanh(双曲正切):输出压缩到 (−1,1)(-1,1)(−1,1)。
  • b)+
    d)
    人工神经元
    前馈神经网络
    全连接层
    多层感知机
    x\boldsymbol{x}x
    1
    ​
    )
    (1.6)
    y1​
    b2,1​)
    (1.7)
    yi∈{0,1}y_i \in \{0, 1\}
    yi​∈{0,1}
    i
    ​
    )
    =def
    −[yi​log(y^​i​)+
    (1−
    yi​)log(1−
    y^​i​)]
    (1.9)
    -\log(1) = 0
    −log(1)=0
    yi=0,y^i=1y_i=0, \hat{y}_i=1yi​=0,y^​i​=1
    −log⁡(0)→∞-\log(0) \to \infty−log(0)→∞
    y^i,yi)z_i \to \hat{y}_i = \sigma(z_i) \to \text{loss}(\hat{y}_i, y_i)
    zi​→y^​i​=σ(zi​)→loss(y^​i​,yi​)
    w(j)w^{(j)}w(j)
    bbb
    ∂loss
    ​
    =
    N1​i=1∑N​(y^​i​−
    yi​)⋅
    xi(j)​,∂b∂loss​=
    N1​i=1∑N​(y^​i​−
    yi​)
    (1.11)
    ​
    i​
    −
    yi​
    ∂w(j)∂loss​
    ,
    b
    ←
    b−
    η∂b∂loss​
    57
    ], [
    53
    ,
    95
    ], [
    48
    ,
    88
    ]
    ], dtype=torch.float32)
    labels = torch.tensor([
    [0], [0], [1], [1], [1], [1], [0], [1], [1], [0], [1], [1]
    ], dtype=torch.float32)
    optimizer = optim.SGD(model.parameters(), lr=0.001)
    criterion = nn.BCELoss() # 对应 (1.10) 式的二元交叉熵
    next∣context)p(\text{next}\mid\text{context})
    p(next∣context)