第0层是把0/1组织成张量,并能进行固定的线性代数运算(比如矩阵乘法、加法)。但此时的运算是“死”的:输入乘以随机生成的权重,输出毫无意义,而且永远不会改变。

第1层的任务,就是给这些0/1赋予“自我修正”的能力。 让那堆随机浮点数,通过不断观察数据,自动调整自己的值,最终变成能做预测、会分类、能识别的参数。这一层的核心技术就是自动微分 + 梯度下降,相当于AI这座大厦里的“学习引擎”。


1.1 从一个最简单的“学习者”开始

假设我们有一个极简模型:单神经元线性回归,要解决的任务是根据房屋面积 x 预测房价 y。公式是:

y_pred = w * x + b
  • w 是权重,b 是偏置——它们现在还是两个随机浮点数(在内存中是两串0/1)。
  • 我们有一组真实数据:面积 x_i 对应的真实售价 y_i(例如[50平米, 300万]、[80平米, 420万]……)。

如果 wb 是随机数,比如 w=0.5, b=100,那么输入 50 平米,预测 0.5*50+100 = 125 万,但真实是300万,错得离谱。怎么让 wb 自己变成合理的数(比如 w=4, b=100)?

1.2 前向传播 + 损失函数——量化“有多差”

第一步,把数据喂给模型,算出预测值,这步叫前向传播
对于每一对数据 (x_i, y_i),做一次张量计算(本质上就是标量乘加):

y_pred_i = w * x_i + b

然后我们需要一个数字来精确度量“整个模型目前有多差”。这个数字叫损失(Loss),由损失函数算出。最常用的是均方误差(MSE):

Loss = (1/n) * Σ (y_pred_i - y_i)²

当预测值和真实值完全一致时,Loss = 0;差距越大,Loss 越大。Loss 是一个标量,它由当前的 wb 决定。

此刻Loss是一个很大的数,比如90000。我们的目标就是通过调整 wb(即修改它们的0/1编码),让Loss变得尽可能小。

1.3 核心问题:该朝哪个方向改?引出梯度

wb 各可以变大或变小,我们不知道哪一种组合能让Loss下降。梯度就是用来回答这个问题的。

梯度是微积分里的概念,它指示了:如果我把这个参数往上拨一点点,Loss会朝哪个方向变化、变化多快。
- 如果 w 的梯度是正数,说明增大 w 会使Loss增大 → 我们应该减小 w
- 如果梯度是负数,说明增大 w 会使Loss减小 → 我们应该增大 w

所以,参数的更新方向,就是它梯度的反方向

对于这个简化的线性模型,我们可以直接用手动求导得到梯度公式:

dLoss/dw = (2/n) * Σ x_i * (y_pred_i - y_i)
dLoss/db = (2/n) * Σ (y_pred_i - y_i)

只要把所有数据代入计算,就能得到一个明确的“箭头”,告诉我们 wb 该增减多少。

1.4 梯度下降——小步快跑逼近最优解

拿到梯度后,更新规则非常简单:

w_new = w_old - learning_rate * dLoss/dw
b_new = b_old - learning_rate * dLoss/db

learning_rate(学习率)是一个很小的正数,比如0.001。它控制我们每次修正的步伐大小。步伐太小,学得太慢;太大,可能直接跨过最优位置。

这步更新,在硬件层面就是:CPU/GPU从内存取出代表 w 的那串0/1,用ALU做浮点减法和乘法,把新值写回内存。“学习”的本质就是这样一次参数值微调。

一轮完整的流程就是:
1. 前向传播:计算所有预测,得到当前Loss。
2. 计算梯度:手动(或自动)求出每个参数的梯度。
3. 梯度下降更新:沿梯度反方向微微挪动所有参数。
4. 重复1-3,直到Loss不再下降。

几百万次这样的迭代后,wb 会从最初的随机值,自动收敛到一组能较好拟合数据的值,比如 w≈4.1, b≈95。这就是模型“学会”了从面积预测房价。


1.5 当模型不再简单——自动微分的诞生

上面这个例子只有2个参数,求导笔算就能搞定。但现实中的神经网络有成百上千亿个参数,计算图极其复杂(有矩阵乘法、卷积、注意力、softmax……),不可能再由人手动推导梯度公式

这时就需要自动微分(Automatic Differentiation)。它的思路是:
不管你的模型多复杂,它都是通过一系列基本运算(加、乘、指数、log、取最大值等)组合而成的。只要我们知道每一个基本运算的局部导数(比如乘法的导数、sin的导数),就可以用链式法则把梯度从最末端一点点传播回每一个原始参数。这套机制叫反向传播

我们把这个过程拆开来看,它其实是一个两阶段的程序执行

阶段1:动态构建计算图

每次前向传播,深度学习框架(如PyTorch)会悄悄记录下你对张量做的每一次运算,并在内存中组装成一幅有向无环图。
例如,对于 L = (w*x + b - y)²,计算图可能是:
xw 做乘法 → 与 b 相加 → 减去 y → 取平方 → 求和/平均得 L
每个节点都是一个操作(Operation),张量在边上流动。

阶段2:反向传播:沿着图逆流,自动算出所有梯度

从最终的损失 L(标量)开始,设置 dL/dL = 1,然后沿计算图反向遍历:
- 经过“取平方”节点,根据导数规则 d(u²)/du = 2u,传入梯度乘以 2u 传给上一节点。
- 经过“加法”节点,梯度原样分发给两个输入分支。
- 经过“乘法”节点,对 w*x,梯度分别需要乘以另一个输入值(即局部导数为 xw),传播给 wx

这样一步一步,所有叶子处积累起来的数字,就是它们各自对最终Loss的梯度。因为整个过程严格遵循链式法则,而且每个基本运算的局部导数都非常简单,所以这个传播可以完全自动化——在代码里你只用写一句 loss.backward(),框架就帮你把所有参数的 .grad 属性填好。

重要的是:这个反向传播过程的每一步,依然是底层的张量运算(乘法、加法、求导公式对应的张量操作),都由第0层的逻辑门阵列完成。


1.6 张量视角下的批量梯度与自动化

现实中我们不会一条一条数据去算,而是用批处理。假设有64条数据,输入 x 变成形状 (64, 1) 的张量,w(1, 1)b 是标量。前向传播 y_pred = x @ w + b 就是一个张量矩阵乘法和广播加法,输出 (64, 1)
然后损失 L = mean((y_pred - y_true)²) 给出一个标量。
调用 .backward() 后,框架自动计算出 wb 的梯度,而梯度本身也是张量(这里的 w.grad 是形状 (1,1) 但里面包含了所有64个样本的平均梯度贡献)。

优化器(如SGD、Adam)就是封装了“拿到梯度后如何更新参数”逻辑的组件。最基本的SGD就是 param = param - lr * param.grad。更智能的Adam会为每个参数维持一个自适应学习率,使得训练更平稳。但无论算法多复杂,所有更新的本质都是对浮点数字的加减乘除,即操作0/1


1.7 最终串起来:从0/1到学习引擎

让我们回到物理实现,看一次参数更新到底经过了什么:

  1. 静默的数据:模型参数(万亿个浮点)和输入数据(batch)都以0/1形式安静地躺在显存或内存中。
  2. 前向计算:GPU的指令调度器发出张量乘法和加法的微指令,计算单元(CUDA核/张量核)接收这些指令,从寄存器/内存取操作数,执行浮点乘加,流水输出结果。结果被保存,同时框架偷偷记下了运算操作,构建计算图(即记录下这些运算间的依赖关系)。
  3. 损失产出:所有预测结果汇总后,计算出一个标量Loss,存储在某寄存器中。
  4. 反向传播:框架生成一系列反向指令,按照计算图的依赖倒序,从Loss出发,执行大量向量-矩阵乘法、元素乘等,逐层算出每个参数张量的梯度(同样是一批浮点数)。
  5. 参数更新:优化器按照更新公式,对每个参数张量做元素级操作:读取旧值,减去 lr*梯度,写回新值。这一步完全就是在大规模改写内存里的0/1。
  6. 循环:加载下一批数据,使用已经修改过的参数,重复以上过程。Loss逐渐降低。

经过几十亿次这样的循环,最初随机的那片0/1“荒地”,就被开垦成了能够执行特定任务(识别猫、翻译句子)的“沃土”。


第1层在AI栈中的角色

类比计算机,如果:
- 第0层(张量表示与基本运算)相当于ALU和寄存器,提供了基础的数据操作能力;
- 那么第1层(自动微分与梯度下降)就相当于控制单元与微程序,它制定了“何时运算、如何根据反馈修正”的整套流程,把死板的计算变为目标驱动的迭代优化

正是这一层,让处理0/1的机器从“只会执行固定公式”跨越到“能从数据中发现规律”。所有后续的神经网络架构、预训练、对齐,都是运行在这个学习引擎之上的高级程序。