核心要点
能描述 loss.backward() 触发 Autograd 反向求导
理解计算图从叶子节点向根累积 .grad
知道 zero_grad() 与 optimizer.step() 的配合顺序
能解释 requires_grad 与 detach 的作用
标准回答
PyTorch 的 反向传播 由 Autograd 自动完成,典型训练步如下:
1. 前向传播:输入 x 经 model(x) 得预测,与标签算 loss = criterion(output, target)。前向中每个可微操作在计算图上记录依赖。
2. 清零梯度:optimizer.zero_grad()(或 model.zero_grad())——PyTorch 默认梯度累加,不清零会导致多步梯度叠加。
3. 反向传播:loss.backward() 从 loss 节点出发,按链式法则向叶子参数传播,将 ∂loss/∂param 累加到 param.grad。
4. 参数更新:optimizer.step() 按优化器规则(SGD、Adam 等)用 .grad 更新 param.data。
for x, y in loader:
optimizer.zero_grad()
loss = criterion(model(x), y)
loss.backward()
optimizer.step()关键机制:requires_grad=True 的张量参与建图;with torch.no_grad() 推理时跳过建图省显存;retain_graph=True 可对同一图多次 backward。详见 反向传播原理。
常见误区
⚠️ 常见踩坑
忘记 zero_grad 导致梯度累加;在 backward 后仍用计算图做第二次 backward 未设 retain_graph;混淆 .data 与 .detach() 导致梯度泄漏到不该训练的参数。
追问
追问 1:为什么需要 zero_grad?不设会怎样?
题库专题:什么是 K 折交叉验证?为什么需要它?PyTorch 的 .grad 是累加缓冲区。若不清零,第二步的梯度会叠在第一步之上,等价于增大 batch size 或错误的学习率,训练发散或行为异常。梯度累积场景则有意隔 N 步才 step 一次。
题库延伸:与本追问相关的专题题 → 什么是 K 折交叉验证?为什么需要它?
追问 2:loss.backward() 后 .grad 存的是什么?
每个 requires_grad 参数的 .grad 是与参数同 shape 的张量,存储 ∂loss/∂param。optimizer.step() 读取 .grad 执行更新;手动调试可用 param.grad.norm() 检查梯度爆炸/消失。
追问 3:非标量 loss 如何 backward?
backward() 默认要求 loss 是标量。若输出是向量,需传入 grad_tensors 权重(如 torch.ones_like(output))指定各分量对梯度的贡献,等价于加权求和后再反传。
延伸学习
与本题相关的知识库文章、术语、工具与行业资讯。
📰 AI 资讯
🛠️ AI 工具
- Pytorch
Meta 开源的深度学习框架,100K+ stars。以动态计算图和 Pythonic 风格著称,在学术界和工业界都有广泛应用,支持分布式训练、移动端部署和 ONNX 导出
- Tensorflow
全球最流行的机器学习框架之一,195K+ stars。Google 开源的端到端 ML 平台,支持 TensorFlow、Keras 等多种 API,覆盖深度学习、强化学习、移动端部署等全场景,是 AI 工程师的必备工具