1. 理解loss.backward()的核心机制
在PyTorch训练神经网络时,我们经常看到这样的代码片段:
python复制loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
这三行代码构成了深度学习训练的核心循环,而loss.backward()正是其中最神秘的环节。很多人知道这是在进行反向传播,但对其内部运作机制却一知半解。
1.1 loss对象的本质特性
首先需要明确的是,loss确实是一个标量值(单个数值),但在PyTorch的实现中,它被封装成了一个特殊的Tensor对象。这个Tensor不仅仅包含数值本身,还携带了完整的计算图信息。当你执行前向计算时,PyTorch会自动构建一个动态计算图(Dynamic Computation Graph),记录所有参与计算的Tensor及其运算关系。
关键点:PyTorch中的Tensor是"活的"数据结构,它不仅存储数据,还知道它是如何被计算出来的(通过grad_fn属性)。
1.2 反向传播的触发机制
调用loss.backward()时,实际上是在说:"请从这个loss值出发,沿着计算图反向传播,计算所有requires_grad=True的参数的梯度"。这个过程可以分解为:
- 从loss这个Tensor节点开始,回溯整个计算图
- 对每个参与计算的Tensor,应用链式法则(Chain Rule)计算其梯度
- 将计算结果累加到各个参数的.grad属性中
值得注意的是,PyTorch会自动处理中间结果的释放,避免内存泄漏。这也是为什么我们通常需要在训练循环中调用optimizer.zero_grad()的原因——清除上一轮计算的梯度,防止梯度累积。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 计算图与自动微分原理
2.1 动态计算图的构建过程
PyTorch的动态计算图是即时构建的,这意味着图的构造与代码执行同步进行。例如:
python复制a = torch.tensor([2.], requires_grad=True)
b = torch.tensor([3.], requires_grad=True)
c = a * b # 乘法操作被记录到计
