前向传播是什么

前向传播封面

如果你读过《神经网络是什么》,应该还记得那个分层的识别委员会:数据从输入层进,一道道工序往后传,最后拍板给结论。这一篇就专门回答一个更具体的问题——数据到底是怎么一道道工序流过去的? 这个过程有个正式名字,叫前向传播(forward propagation,也叫 forward pass)。

一句话定义:前向传播就是把输入数据从输入层出发,逐层做"加权求和 + 激活",一路算到输出层得到预测结果的过程。

用你秒懂的话说,它就像工厂的流水线:原料(输入数据)从第一道工序进,每道工序加工一下交给下一道,最后一道产出成品(预测结果)。整条线只往前走、不回头——"前向"二字就是这个意思。对应到委员会类比:意见从基层初审 → 中层复审 → 终审定论,一层层上报,这个"上报"的流程就是前向传播。

拆开看:前向传播就是层层"加权求和 + 激活"的接力

单个神经元干的事,上一篇《神经元是什么》讲过了:把输入按权重加权求和、加偏置、再过激活函数(z=w1x1++wnxn+bz = w_1x_1+\cdots+w_nx_n+ba=f(z)a=f(z))。前向传播,就是把这个动作在每一层重复一遍、层与层接力

一层里通常有多个神经元并排工作。把它们打包成紧凑的矩阵写法("矩阵"你可以理解成"把一堆权重排成一张表,好一次性算完这层的所有神经元"),一层的计算就是:

z(l)=W(l)a(l1)+b(l)z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)}
a(l)=f(z(l))a^{(l)} = f(z^{(l)})

符号逐项解读:

  • z(l)z^{(l)} —— 等号左边,第 ll 层的加权和:这层做完"权重×输入"累加再加偏置后的中间结果,还没过激活函数。
  • a(l1)a^{(l-1)} —— 上一层的输出(也就是这一层的输入)。最开头 a(0)a^{(0)} 就是原始输入数据。
  • W(l)W^{(l)} —— 第 ll 层的权重矩阵:把这层所有神经元对所有输入的"话语权"打包成一张表。
  • b(l)b^{(l)} —— 第 ll 层的偏置,每个神经元一个底数。
  • ff —— 激活函数(ReLU、sigmoid 等),"够强才放行"的开关。
  • a(l)a^{(l)} —— 这层的输出,它会原封不动地变成下一层的输入

关键直觉就一句:上一层的输出,就是下一层的输入。 整张网络,本质上是在把"加权求和 + 激活"这个简单函数一层套一层地复合很多次——第一层的输出喂给第二层,第二层的输出喂给第三层,一直套到输出层。

层与层接力示意

图 1:每一层都把上一层的输出原封不动当作输入,同一套「加权求和 + 激活」动作层层接力。

用 PyTorch 写,这个"接力"一目了然:

python
a1 = torch.relu(self.layer1(x))        # 第一层:a⁽¹⁾ = f(W⁽¹⁾x + b⁽¹⁾)
out = torch.sigmoid(self.layer2(a1))   # 第二层:把 a⁽¹⁾ 当输入再算一遍

手算一遍:数据怎么从输入流到输出

公式看着抽象,我们用一个迷你网络实际走一遍:2 个输入、1 个隐藏层(2 个神经元)、1 个输出。

已知(权重假装是训练后学出来的定值):

  • 输入 a(0)=[10]a^{(0)} = \begin{bmatrix}1 \\ 0\end{bmatrix}(比如"有尖耳朵"、"没长胡须"两个特征)
  • 第一层 W(1)=[0.70.50.30.8]W^{(1)} = \begin{bmatrix}0.7 & 0.5 \\ -0.3 & 0.8\end{bmatrix}b(1)=[00]b^{(1)} = \begin{bmatrix}0 \\ 0\end{bmatrix},激活用 ReLU
  • 第二层 W(2)=[0.60.4]W^{(2)} = \begin{bmatrix}0.6 & -0.4\end{bmatrix}b(2)=[0]b^{(2)} = [0],激活用 sigmoid

先理清这两层各扮演什么角色(带着这个看下面的数字就不晕):

第一层 W(1)W^{(1)} 是个 2×22\times2 的表,每一行 = 一个神经元对"耳朵、胡须"这两条输入各给的话语权。具体到每个数:第一行 [0.7, 0.5][0.7,\ 0.5] 是神经元①的——对耳朵的话语权 0.70.7、对胡须 0.50.5;第二行 [0.3, 0.8][-0.3,\ 0.8] 是神经元②的——对耳朵 0.3-0.3(负号是反向话语权:耳朵越尖它越反对)、对胡须 0.80.8。两个神经元并排分头把输入揉成两个"初步印象",像流水线上两道粗加工。第二层 W(2)W^{(2)} 只剩 1×21\times2 一行,即一个神经元,它把第一层的两个初步印象综合成一个数来拍板。一句话概括分工:

  • 第一层负责"特征提取":把原始线索揉成几个初步印象;
  • 第二层负责"综合决策":把初步印象合成最终判断。

至于每个神经元具体"更看重耳朵还是胡须",是训练从数据里学出来的——上面这组权重只是占位,用来演示矩阵怎么相乘,不代表真实学到的含义。

第一层(加权求和 → 激活):

z(1)=W(1)a(0)=[0.70.50.30.8][10]=[0.70.3]  ReLU  a(1)=[0.70]z^{(1)} = W^{(1)}a^{(0)} = \begin{bmatrix}0.7 & 0.5 \\ -0.3 & 0.8\end{bmatrix}\begin{bmatrix}1 \\ 0\end{bmatrix} = \begin{bmatrix}0.7 \\ -0.3\end{bmatrix} \;\xrightarrow{\text{ReLU}}\; a^{(1)} = \begin{bmatrix}0.7 \\ 0\end{bmatrix}

(ReLU 把负的 0.3-0.3 归零。)

第二层(拿 a(1)a^{(1)} 当输入,再来一次):

z(2)=W(2)a(1)=[0.60.4][0.70]=0.42  sigmoid  a(2)=11+e0.420.60z^{(2)} = W^{(2)}a^{(1)} = \begin{bmatrix}0.6 & -0.4\end{bmatrix}\begin{bmatrix}0.7 \\ 0\end{bmatrix} = 0.42 \;\xrightarrow{\text{sigmoid}}\; a^{(2)} = \frac{1}{1+e^{-0.42}} \approx 0.60

(式中的 ee 是自然对数的底,约等于 2.718,是一个数学常数。)

自检: sigmoid 的输出必须落在 (0,1)(0,1) 区间,0.600.60 在范围内 ✅;它表示"略倾向于'是猫'"——方向也合理 ✅。

这个 0.600.60 就是这次前向传播的最终预测。注意 a(1)a^{(1)} 怎么从"第一层的输出"变成"第二层的输入",这就是"接力"的真实模样。

对照这次的结果看:输入是"有尖耳朵、没长胡须",也就是 [1, 0][1,\ 0]。第一层算的时候,那两个对"胡须"的话语权 0.50.50.80.8 因为胡须输入是 00、乘出来还是 00,这次没派上用场——真正起作用的只有对"耳朵"的 0.70.70.3-0.3。于是第一层把这条输入揉成初步印象 [0.7, 0.3][0.7,\ -0.3],ReLU 后变 [0.7, 0][0.7,\ 0](第二个被打成负分、压住不发话);第二层再综合成 0.600.60,意思是"略微像猫"。这也点出权重的一个性质:权重是"潜在的话语权",得看输入给不给它发挥的机会——某条线索的输入若是 00,它的话语权再大也使不上劲。具体数字会随训练变化,但"第一层提取、第二层综合"这套分工不变。

迷你网络手算数据流

图 2:迷你网络手算全过程,数据从 [1, 0] 一路变形到预测值 0.60。

前向 vs 反向:答题 与 对答案

训练循环四步

图 3:训练循环的四个步骤,前向传播站在第一个位置。

前向传播从不单独存在——它是训练循环里的第一步。完整的训练循环是四步:

  1. 前向传播(答题):数据流过网络,得到预测。
  2. 算损失(批改):预测和正确答案一比,差多少(这个差叫损失 / loss)。
  3. 反向传播(找错):从输出往回算,揪出每个权重该为误差负多少责任。
  4. 更新权重(改正):真的把权重挪一点点。

所以前向和反向是一对:前向是"答题"、反向是"对答案并改话语权"。但有件事要划清——模型训练好之后,预测新数据时只跑前向传播,不需要反向。前向是"用"网络,反向是"改"网络。

前向传播在 AI 里的位置

  • 推理(inference)的全部:模型训练好、部署出去之后,每来一条新数据,就是跑一次前向传播。你用人脸解锁手机、相册自动识猫,背后都是一次毫秒级的前向传播。
  • 大模型也一样:你给 ChatGPT 打一句话、它吐出回答,核心就是一次(超大规模的)前向传播——只是层数和参数量大到惊人。
  • 它是理解反向传播的前提:反向传播要沿着前向走过的路"原路返回"算账,所以不懂前向,就没法懂反向。

小结

前向传播是神经网络做预测时数据流动的方式:从输入层开始,每一层做一次"加权求和 Wa+bW a + b + 激活 f(z)f(z)",把结果交给下一层当输入,一路算到输出层得到预测值。它是"答题",和"对答案、改权重"的反向传播是一对;模型训练好之后,每一次预测都只跑前向——从手机识猫到 ChatGPT 回话,骨子里都是它。

完整代码

下面这个最小网络演示一次完整的前向传播:数据从输入层流过隐藏层、再到输出层,每层都是"加权求和 + 激活"。重点看 TinyNet.forward 里每一行注释,和上面的公式逐条对应。代码末尾还接了一个训练步,让你看清前向传播在"预测 → 算损失 → 反向 → 更新"这个循环里站在第一个位置。

python
import torch
import torch.nn as nn

# ===== 定义一个两层小网络,演示前向传播 =====
class TinyNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer1 = nn.Linear(2, 2)   # 输入层(2) → 隐藏层(2):内部自带 W⁽¹⁾ 和 b⁽¹⁾
        self.layer2 = nn.Linear(2, 1)   # 隐藏层(2) → 输出层(1):内部自带 W⁽²⁾ 和 b⁽²⁾

    # forward 方法定义"数据怎么从输入流到输出",调用模型时 PyTorch 会自动执行它
    def forward(self, x):
        z1 = self.layer1(x)             # 第一层加权求和 z⁽¹⁾ = W⁽¹⁾x + b⁽¹⁾
        a1 = torch.relu(z1)             # 第一层激活 a⁽¹⁾ = f(z⁽¹⁾)
        z2 = self.layer2(a1)            # 第二层加权求和(注意输入是上一层的输出 a⁽¹⁾)
        a2 = torch.sigmoid(z2)          # 第二层激活 → 这就是最终的预测值
        return a2

# ===== 准备数据 + 实例化网络 =====
torch.manual_seed(42)
net = TinyNet()
X = torch.tensor([[1., 0.],   # 一条样本:2 个特征
                  [0., 1.]])  # 另一条样本(一次前向传播能同时处理多条数据)

# ===== 前向传播:把数据流过网络,得到预测 =====
pred = net(X)
print("前向传播得到的预测值:")
print(pred)

# ===== 演示前向在训练循环里的位置(前向是第 1 步)=====
target = torch.tensor([[1.], [0.]])     # 假装正确的标签
loss_fn = nn.MSELoss()
opt = torch.optim.SGD(net.parameters(), lr=0.1)

loss = loss_fn(pred, target)            # 第 2 步:算损失
opt.zero_grad()
loss.backward()                         # 第 3 步:反向传播(沿前向的路原路返回算账)
opt.step()                              # 第 4 步:更新权重
print(f"训练一步后的 loss: {loss.item():.4f}")

运行后,pred 就是网络对两条样本各做一次前向传播得到的预测值;后面几行则演示了前向传播作为训练循环第一步之后,紧接着会发生什么。

参考资料

  1. 前向传播、反向传播和计算图 - 《动手学深度学习》 https://zh.d2l.ai/chapter_multilayer-perceptrons/backprop.html
  2. Forwardpropagation - ML Glossary https://ml-cheatsheet.readthedocs.io/en/latest/forwardpropagation.html
  3. 什么是反向传播(含前向传递说明)- IBM https://www.ibm.com/cn-zh/think/topics/backpropagation