Current: Week 1

0%

Week 1

Week 1 - 必要数学直觉:先学会读AI 公式

Key question怎样把 AI 公式翻译成数据、shape 和代码?

Learning objectives

  • 理解并应用 Week 1 - 必要数学直觉:先学会读 AI 公式

50 min estimated reading time

Week progress: 0 of 26 sections (0%)Course progress: 0 of 321 sections (0%)

本周的问题:怎样把“根据几个输入预测一个数”写成可计算的程序?你已经会函数和列表,暂时不需要矩阵知识。先运行一个函数,再为已经看见的数字结构命名。

python
def predict(x, w, b):
    return sum(value * weight for value, weight in zip(x, w)) + b

x = [1.0, 2.0]
w = [0.5, 0.4]
b = 0.1
print(predict(x, w, b))  # 1.4
print(predict([2.0, 1.0], w, b))  # 1.5

上面是可独立运行的最小演示,约定 x 与 w 长度相同。x 是一次送来的输入;w 和 b 是我们暂时指定的规则。换 x 是换一道题,换 w 或 b 是改规则。程序现在会计算,还没有从数据学习。

Scroll horizontally to view all columns.

Course data table
学习单元完成的具体动作
一:输入和规则读数字、向量、特征顺序;解释为什么交换输入会改变结果。
二:一行怎样算逐项相乘、求和、加偏置;把 Σ 翻成循环。
三:多行与多输出把两个样本、两个输出排成表;从循环得到 X @ W + b。
四:独立完成运行 course_examples/week01_linear_layer.py,再换输入预测结果。

本周需掌握:一个数字叫标量;一组有序数字叫向量;多组排成表叫矩阵。shape 说明每条轴有多少项,不能代替“这条轴是什么”的说明。四个学习单元可分次完成,阅读与实验交替进行。

完成标准:不看答案写出 [4,3] 的输入、[3,2] 的权重和 [2] 的偏置怎样得到 [4,2];说明为什么参数还需要下一周自动调整。指数和概率先定位用途,详细计算留到 Week 6。

Week 1 核心目标

Scroll horizontally to view all columns.

Course data table
写法先这样读小例子
= / ≈完全相等 / 四舍五入后接近1/3≈0.333;不要把近似数当精确值
x₁、x₂同一组数的第 1、2 项;下标不是乘方x=[3,5] 时 x₂=5;Python x[1]=5
x 乘自己(-3)²=9;Python 用 x ** 2
Σ把指定几项加起来Σᵢ xᵢ=3+5=8
∈ ℝ属于实数;可以有小数或负数x∈ℝ³ 表示三个实数
用右边结果替换旧值w←w−0.1:把 w 减去 0.1

本书符号会随局部任务出现:η(eta)是训练步长,θ(theta)是所有参数的统称,τ(tau)是后期生成的温度。现在不用背,第一次使用时会再说明。

这套教程不是要先补完一本高等数学。

我们的目标更实用:当你看到一个AI 公式时,能够把它翻译成数据、代码和shape。

本周只详细理解五件事:

  1. Scalar、Vector、Matrix 分别是什么;
  2. Shape 为什么像程序里的类型契约;
  3. Dot Product 为什么是neuron 的核心计算;
  4. Function、Parameter 和Input 的区别;
  5. 如何把公式逐步翻译成Python。

本周的主线是:

现实信息

数字

Vector / Matrix

加权计算

一个Prediction

Week 2 会继续回答:Prediction 错了以后,模型怎样自动修改参数。

本章怎样学习每个概念

后面每个数学对象都不要只记名字。固定问四个问题:

  1. 它是什么数据结构?
  2. 为什么模型需要它?
  3. 它在公式中做什么?
  4. 它在代码中的shape 和类型是什么?

数学在这里不是一组孤立公式,而是描述程序中数据流和变化关系的精确语言。

1. AI 首先处理的是数字

我们看到一句话:

这套房子离CBD 很近

计算机不能直接对“很近”做矩阵乘法。我们需要把现实信息表示成数字,例如:

面积

= 100

卧室数量

= 3

距离CBD

= 8

房龄

= 12

这些数字不是知识本身,而是模型能够处理的representation(表示)。

为什么必须做representation?因为现实概念没有统一的机器运算接口。“离CBD 很近”“房屋较新”“用户很喜欢”都需要先变成可比较、可组合的数值。Representation 决定模型能够看见什么:如果输入里从未表达“距离”,再复杂的模型也无法直接利用这个信息。

因此AI 的第一层设计问题往往不是选择多少layers,而是:

怎样把问题中的对象和关系,转换成不会丢失关键含义的数字?

把图片特征写成 [0.8,0.6,0.2] 是为了手算;这些分数假定已由某个处理步骤产生,不是原始图片自己附带的答案。房价例子中的面积也会改成 1、2、3、4 等教学数字。换单位或换特征时,要同时说明含义,不能直接把玩具输出当现实价格。

2. Scalar:一个数字

Scalar(标量)就是一个单独的数字:

房价= 800000

温度= 22.5

Loss = 0.18

Python 中:

python
price = 800000
temperature = 22.5
loss = 0.18

以后一个训练 batch 通常会汇总成一个 scalar loss。这样我们先选定一个明确的优化目标,再计算它对参数的梯度。多元素输出也能求导,但需要说明怎样组合各输出;Week 5 再解释,当前先用平均损失。

Scalar 的作用是表示“一个量”。它没有内部方向或位置结构。例如一个模型可以输出很多predictions,但训练通常把它们对应的errors 汇总成一个scalar loss,作为本次update 的统一目标。

这并不表示每个example 的差异消失了。每个example 对这个scalar 都有贡献,Backward 会再把总Loss 的影响分配回各个parameters。

3. Vector:一组有顺序的数字

同一套房子的多个feature 可以放进一个Vector:

x=[10038]x = \begin{bmatrix} 100 \\ 3 \\ 8 \end{bmatrix}

分别表示:

x₁ = 面积

x₂ = 卧室数量

x₃ = 距离CBD

代码里可以先把它看成list:

python
x = [100, 3, 8]

Vector 的两个重点:

  • 数字有固定顺序;
  • 每个位置代表一个确定含义。

如果训练时顺序是[面积, 卧室, 距离],预测时却传入[距离, 面积, 卧室],程序可能不会报错,但含义已经完全错了。

Scroll horizontally to view all columns.

Course data table
同样三个数Shape意义
[0.8,0.6,0.2][3]一维向量,只有一个轴
[[0.8,0.6,0.2]][1,3]一行三列
[[0.8],[0.6],[0.2]][3,1]三行一列

正文把每个样本放在一行,批量输入写 X:[B,D]。手写竖排向量是另一种排版约定;代码里的 [3] 并不自带“行”或“列”。真正相乘前要写出 shape。

Knowledge check

把三个特征写成一行和一列,元素数一样,shape 也一样吗?

为什么Vector 不只是普通List

List 强调“装了多个值”;Vector 还强调这些值共同表示同一个对象,并且可以作为整体参加加法、缩放、点积等运算。

例如用户画像:

[购买频率, 平均金额, 最近活跃度]

这三个数字的组合才是完整representation。Vector 的dimension 表示模型用多少个数描述对象;dimension 越多不一定越好,关键是每个维度能否通过training 承载有用信息。

4. Shape:数据的结构契约

上面的Vector 有三个元素,所以shape 是:

[3]

把四套房子放在一起:

X=[10038802151404695311]X = \begin{bmatrix} 100 & 3 & 8 \\ 80 & 2 & 15 \\ 140 & 4 & 6 \\ 95 & 3 & 11 \end{bmatrix}

它的shape 是:

[4, 3]

意思是:

4 rows

= 4 个examples

3 columns = 每个example 有3 个features

对软件工程师来说,可以把shape 看成数据的type signature:

Tensor[batch_size, feature_count]

很多AI bug 不是公式错,而是shape 不符合契约。

Dimension、Axis 与Shape 的区别

[4,3] 是shape;它有两个dimensions(也常叫axes)。第0 维长度是4,第1 维长度是3。

重要的不只是数字,还要写出语义:

X.shape = [4, 3]

axis 0 = examples

axis 1 = features

两个tensors 即使shape 相同,语义也可能不同。例如[8,32] 可能是“8 个tokens,每个32 个features”,也可能是“8 个examples,每个32 个features”。框架只检查数字是否兼容,业务语义要由我们保证。

5. Weight:模型怎样看待不同输入

假设模型给三个feature 分配三个weights:

w=[0.70.50.4]w = \begin{bmatrix} 0.7 \\ 0.5 \\ -0.4 \end{bmatrix}

直觉上:

面积

weight 为正

卧室数量

weight 为正

距离CBD weight 为负

Weight 可以先理解为:

某个输入影响结果的方向和强度。

这些weights 不是程序员逐个写出来的。Training 会根据数据自动寻找它们。

权重的符号先告诉我们:固定其他输入时,这一项会把当前线性分数往上推还是往下拉。权重大小只有在输入单位和尺度可比较时才便于比较。把面积从“平方米”改成“百平方米”,等价模型的权重也要变;权重大不自动证明现实因果关系更强。

Weight 为什么必须存在

如果所有inputs 都直接相加,模型只能认为每个feature 同样重要,而且只能产生固定规则。Weight 为每条输入路径提供一个可调旋钮:

  • 正数表示input 增大时倾向推高结果;
  • 负数表示input 增大时倾向压低结果;
  • 接近0 表示当前位置该input 的影响很弱;
  • 绝对值较大表示影响倍率较强。

Weight 的含义还与feature 的尺度有关。面积用平方米、价格用万元或元,会改变数字大小,所以不能脱离input scale 机械比较两个weight 的绝对值。

6. Dot Product:把多个输入合成一个分数

Dot Product(点积)是本周最关键的计算。

它之所以反复出现在神经网络中,是因为它能把“多个证据及各自重要程度”压缩成一个综合分数。每个wᵢxᵢ是一项证据,求和后得到neuron 对当前input 的总体响应。

公式:

wx=w1x1+w2x2+w3x3w \cdot x = w_1x_1 + w_2x_2 + w_3x_3

它做的事情非常朴素:

每个input × 对应weight

全部相加

得到一个数

为了方便手算,假设:

x = [0.8, 0.6, 0.2]

w = [0.7, 0.5, -0.4]

那么:

wx=(0.7)(0.8)+(0.5)(0.6)+(0.4)(0.2)w \cdot x = (0.7)(0.8) + (0.5)(0.6) + (-0.4)(0.2)
=0.56+0.300.08= 0.56 + 0.30 - 0.08
=0.78= 0.78

Python:

python
x = [0.8, 0.6, 0.2]
w = [0.7, 0.5, -0.4]
score = 0.0

for input_value, weight in zip(x, w):
    score += input_value * weight

print(score)  # 0.78

数学符号・,对应的就是“对应相乘,再全部相加”。

Knowledge check

输入 [2,3],权重 [0.5,-1],点积是多少?

Dot Product 为什么要求长度一致

每个input 必须能找到唯一对应的weight:

x₁ ↔w₁

x₂ ↔w₂

x₃ ↔w₃

如果x 有三个features、w 只有两个weights,第三个feature 没有明确的影响规则。这就是shape mismatch 背后的业务含义,不只是矩阵库的语法限制。

7. Bias:额外的可学习偏移

模型通常还会加一个Bias:

z=wx+bz = w \cdot x + b

假设:

w・x = 0.78

b = 0.10

那么:

z=0.78+0.10=0.88z = 0.78 + 0.10 = 0.88

代码:

python
bias = 0.1
z = score + bias

Bias 让模型不必在所有输入都为0 时强制输出0。它和weight 一样,也是模型需要学习的parameter。

用门槛理解Bias

假设neuron 在z > 0 时被认为“触发”。没有bias 时,判断边界必须穿过原点。加入bias 后:

wx+b>0w \cdot x + b > 0

等价于允许模型移动触发门槛。例如综合证据分数是0.78,但只有超过0.90 才希望触发,那么模型可以学到约b=-0.90。Weight 控制边界方向,Bias 控制边界位置;二者缺一会限制模型能表达的规则。

8. Function:输入经过规则得到输出

Function 可以理解成一个有明确输入和输出的处理过程:

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

代码:

python
def f(x):
    return 2 * x + 1

对于模型:

python
def model(x, w, b):
    return w * x + b

这里:

  • x 是Input;
  • w、b 是Parameters;
  • 函数结构是Model;
  • 返回值是Prediction。

这四个词在Week 2 会反复出现。

Function 与Model 的关系

所有model 都可以看作function,但不是所有function 都会学习。普通函数的规则由程序员固定;可训练model 的结构由程序员定义,其中一部分数值parameters 由数据决定。

固定代码:return w * x + b

可学习状态:w, b

运行时输入:x

产生结果:prediction

Training 改变的是w 和b,不是每一步重新改写forward 代码。

9. Variable、Parameter 与Hyperparameter

三者很容易混淆。

Variable

计算过程中可能变化的值,例如input、prediction、loss。

Parameter

模型通过training 学到的值,例如weights 和biases。

Hyperparameter

由训练者先选择的设置,例如learning rate、batch size、layer count。

Parameter → model learns

Hyperparameter → human chooses

为什么Hyperparameter 不能简单交给同一次training 自动学习?因为它们往往定义“学习过程本身”或architecture 结构,例如layer count 会决定graph 有多少节点,learning rate 会决定parameter update的步长。它们可以通过外层实验、搜索或其他算法调优,但不属于普通forward/backward 中直接更新的model parameters。

10. Matrix:同时处理很多向量

一个 predict 只能给一个输出。如果我们想让同一组输入产生两种分数,不是复制输入的含义,而是为每个输出准备一套权重。两个样本仍使用同一套参数;参数不会因为样本排在第几行而改变。

Scroll horizontally to view all columns.

Course data table
数值行与列的意义
X[[1,2],[3,4]]两行是两个样本;每行两个特征,顺序固定。
W[[0.5,−0.3],[0.4,0.8]]每行对应一个输入特征;每列对应一个输出。
b[0.1,−0.2]每个输出各有一个偏置;所有样本共用。

先只算第一行第一个输出:1×0.5+2×0.4+0.1=1.4。再算第一行第二个输出:1×(−0.3)+2×0.8−0.2=1.1。第二行用 [3,4] 替换输入,参数不动,得到 [3.2,2.1]。

Z=XW+b=[1.41.13.22.1]Z=XW+b=\begin{bmatrix}1.4&1.1\\3.2&2.1\end{bmatrix}
python
X = [[1, 2], [3, 4]]
W = [[0.5, -0.3], [0.4, 0.8]]
b = [0.1, -0.2]
Z = [[sum(row[i] * W[i][j] for i in range(2)) + b[j]
      for j in range(2)] for row in X]
print(Z)  # 约 [[1.4, 1.1], [3.2, 2.1]]

这是可独立运行的标准 Python。矩阵乘法只是把这些相同的乘加运算一起表示。X 的列数必须与 W 的行数一致,因为每个输入都需要对应权重;外侧两个数决定结果有多少样本、多少输出。下一节把这条规则扩展到任意 shape。

Knowledge check

EX01:把第一行输入从 [1,2] 改为 [2,1],参数保持不变。两个输出各是多少?再写出四个样本、三个特征、两个输出时 X/W/b/Z 的 shape。

11. Matrix Multiplication 的最重要规则

不用现在背完整矩阵乘法,只记住shape:

[m,n]×[n,p][m,p][m,n] \times [n,p] \rightarrow [m,p]

中间维度必须相同。

例如:

[4,3]×[3,2][4,2][4,3] \times [3,2] \rightarrow [4,2]

意思是:

4 个examples

每个有3 个features

进入2 个neurons

得到每个example 的2 个outputs

这比死记矩阵计算步骤更重要。

Scroll horizontally to view all columns.

Course data table
同一个输入 x=[0.8,0.6,0.2]三项乘积加偏置后
第 1 个输出;权重 [0.7,0.5,-0.4]0.56+0.30−0.08=0.780.78+0.1=0.88
第 2 个输出;权重 [0.2,-0.1,0.8]0.16−0.06+0.16=0.260.26−0.2=0.06
x=[0.8,0.6,0.2],W=[0.70.20.50.10.40.8],b=[0.1,0.2],xW+b=[0.88,0.06]x=[0.8,0.6,0.2],\quad W=\begin{bmatrix}0.7&0.2\\0.5&-0.1\\-0.4&0.8\end{bmatrix},\quad b=[0.1,-0.2],\quad xW+b=[0.88,0.06]

W 的每一列负责一个输出,shape=[输入数,输出数]=[3,2]。转置 Wᵀ 只交换行列,把同一份数重新排成 [2,3];不是求逆,也不是改变权重值。Week 5 的 nn.Linear 把每个输出的权重存成一行,记作 W_store=Wᵀ,因此代码计算 X @ W_store.T + b。两种写法做的是相同点积。

Knowledge check

X:[4,3]、W:[3,2]、b:[2],输出是什么 shape?

输出Shape 为什么是[m,p]

左侧matrix 提供m 个examples,右侧matrix 提供p 组output weights。每个example 都会与每组weights 做一次dot product,因此最终得到:

m 个examples × p 个outputs

中间的n 是每次dot product 要配对并消掉的feature dimension,所以不会出现在输出shape 中。

12. 求和符号Σ

Σ 读“求和”。下面 i=1 到 3 是依次取第 1、2、3 项,不是在求一个神秘变量。先展开 x₁w₁+x₂w₂+x₃w₃,再执行三次乘法和两次加法。数学常从 1 编号;Python 列表从 0 编号,同一个 x₁ 在代码里是 x[0]。

下面两个公式是同一件事:

w1x1+w2x2+w3x3w_1x_1 + w_2x_2 + w_3x_3
i=13wixi\sum_{i=1}^{3} w_i x_i

Σ 只是在说:让i 从1 走到3,把每一项加起来。

它对应代码:

python
total = 0
for i in range(3):
    total += w[i] * x[i]

看到Σ 时,先把它翻译成loop。

Σ 存在的原因只是让重复模式写得更紧凑。它不引入新的operation;下标告诉loop 从哪里开始,上标告诉loop 到哪里结束,右侧表达式就是每次迭代累加的内容。

13. 平方、指数、概率:先建立最低限度直觉

Scroll horizontally to view all columns.

Course data table
算术工具例子后面用在哪里
括号与负号(-2)²=4;-2²=-(2²)=-4平方误差
分数与除法1/4=0.25=25%平均和概率
零次方与负指数e⁰=1;e⁻¹=1/e≈0.368Softmax
概率检查0.2+0.3+0.5=1几个互斥候选的完整分布

e≈2.718 是一个固定常数,就像圆周率 π 一样;此处先用计算器或 math.exp 算 e 的幂。自然对数 ln 是指数的反向问题:“e 的几次方等于这个数?”例如 e⁰=1,所以 ln(1)=0。Week 6 会用 −ln(p) 把概率变成损失。

这些概念后面会出现,但本周不需要展开。

平方

x2=x×xx^2 = x \times x

Week 2 会用平方表示error 的大小。

指数

exe^x

它能把任意实数转换成正数。Week 6 的Softmax 会使用它。

概率

0p10 \le p \le 1

概率越接近1,代表模型越倾向某个结果。Language Model 会为下一个token 产生一整组概率。

现在只需要知道它们将在哪里使用,不需要提前记公式。

为什么平方适合表示误差

正误差和负误差不应互相抵消,平方会把它们都变成非负数;同时较大错误会受到更强惩罚。Week 2 会把这一点发展成MSE。

为什么指数适合生成概率

Softmax 需要把任意logits 转为正数,再归一化到总和为1。指数函数始终为正,而且会保留“更大的logit应得到更大权重”的顺序。

概率不等于确定事实

p=0.8 表示模型在当前参数和上下文下给予某结果更高权重,不代表现实世界中有80% 的客观真理。模型概率是对其学到的数据分布的表达。

14. 读AI 公式的固定顺序

以后看到公式,例如:

z=xW+bz = xW + b

按下面顺序读:

  1. 每个符号代表什么?
  2. 每个对象的shape 是什么?
  3. 运算顺序是什么?
  4. 输出shape 是什么?
  5. 哪些值是parameters?
  6. 代码里是哪一行?

例如:

python
# Shape trace
# x: [batch, input_features]
# W: [input_features, neurons]
# b: [neurons]
# z: [batch, neurons]

然后才看代码:

python
z = x @ W + b

如果只看符号而不看shape,Wx 和xW 很容易被当成同一件事;如果只看代码而不问参数含义,又会把能运行的tensor 运算误当成正确模型。固定的六步阅读顺序,就是在“数学正确、shape 正确、业务语义正确”之间建立检查链。

15. Week 1 Python 小实验

python
inputs = [0.8, 0.6, 0.2]
weights = [
    [0.7, 0.5, -0.4],
    [0.2, -0.1, 0.8],
]
biases = [0.1, -0.2]
outputs = []

for neuron_weights, bias in zip(weights, biases):
    z = bias
    for x, w in zip(inputs, neuron_weights):
        z += x * w
    outputs.append(z)

print(outputs)

这段代码已经完成了一个neural network layer 的核心计算:

Inputs

Dot Products

Add Biases

Layer Outputs

我们还没有加入activation,也没有training。Week 2 和Week 3 会依次补上。

16. Week 1 最应该理解的6 件事

  1. 现实信息要先转换成数字表示。
  2. Vector 是一个example 的一组有顺序的features。
  3. Matrix 可以同时装下多个examples 或多组weights。
  4. Shape 是数据结构契约。
  5. Dot Product 是“对应相乘再相加”。
  6. 行样本约定下的 XW+b,是后续 neuron、layer、Transformer 中线性变换的基础;nn.Linear 存储权重时使用等价的 XW_storeᵀ+b。

17. 理解测试

Knowledge check

假设: x = [2, 3] w = [0.5, -0.2] b = 0.1 计算:

Review the relevant lesson
z=wx+bz = w \cdot x + b

答案:

z=(0.5)(2)+(0.2)(3)+0.1z = (0.5)(2) + (-0.2)(3) + 0.1
=10.6+0.1=0.5= 1 - 0.6 + 0.1 = 0.5

如果你能把它直接翻译成:

python
z = 0.5 * 2 + (-0.2) * 3 + 0.1

本周的核心已经掌握。

18. Week 1 → Week 2

我们现在可以用parameters 做prediction:

y^=wx+b\hat{y} = wx + b

但仍有一个关键问题:

如果prediction 错了,计算机怎样知道应该修改哪个parameter、修改方向是什么、每次修改多少?

Week 2 会用Loss、Derivative、Gradient 和Gradient Descent 回答这个问题。