大数跨境

PyTorch极简入门03:自动梯度与反向传播,看懂模型训练底层逻辑

PyTorch极简入门03:自动梯度与反向传播,看懂模型训练底层逻辑 AI与计算机视觉
2026-07-21
4
导读:哈喽各位小伙伴,欢迎来到《PyTorch计算机视觉零基础实战教程》第三期!

哈喽各位小伙伴,欢迎来到《PyTorch计算机视觉零基础实战教程》第三期!

前两期我们完成环境搭建、吃透Tensor张量,掌握了图像在传统CV与深度学习之间转换的全部操作。

很多粉丝跑完张量代码后提问:张量只是存储数据,模型到底是怎么学会识别图片、修正误差的?

答案就是本期核心:自动求导Autograd + 反向传播

没有复杂高数推导,全部结合图像分类场景举例,学完你就能彻底理解:训练YOLO、分类网络时loss下降背后到底发生了什么。

一、什么是梯度?大白话讲解

梯度可以简单理解为:误差变化的方向与幅度

举个CV场景例子:

模型预测图片里是猫,实际标签是狗,产生预测误差loss

梯度会告诉我们:模型每个参数该增大还是减小,才能让误差变小。

正向传播:输入图片张量,模型输出预测结果(推理过程)

反向传播:根据预测误差计算梯度,更新模型权重(训练过程)

PyTorch最核心的优势就是Autograd自动微分引擎,不用手动求导,代码一行开启自动计算梯度。

关键标记:requires_grad

只有设置requires_grad=True的张量,才会记录运算流程、支持求梯度。

普通图像张量不需要梯度,模型权重参数必须开启梯度

python
import torch

# 1. 普通张量:默认不记录梯度
x = torch.tensor([2.0, 3.0])
print(x.requires_grad)  # False

# 2. 开启梯度记录(模型参数专用)
w = torch.tensor([1.5], requires_grad=True)
print(w.requires_grad)  # True

二、正向传播:构建计算图

所有带梯度的张量运算,PyTorch会自动生成一张计算图,保存完整运算链路,为反向求导做准备。

模拟一个简易图像预测运算:

python
# 模拟图像特征张量
img_feat = torch.tensor([0.8, 0.6])
# 模拟模型权重(可训练参数)
weight = torch.tensor([0.4, 0.7], requires_grad=True)
# 正向计算:简单预测输出
pred = torch.sum(img_feat * weight)
print("预测值:", pred)

此时pred依托weight生成,计算图已经构建完成,等待计算误差梯度。

三、反向传播backward():自动求梯度

我们定义损失loss,调用.backward()PyTorch自动反向计算所有参数梯度,存在.grad属性中。

完整可运行案例:

python
# 权重参数,开启梯度
w = torch.tensor([2.0], requires_grad=True)
# 正向运算
y = w * 3
# 模拟损失函数
loss = (y - 9) ** 2
# 反向传播,自动求导
loss.backward()
# 打印w的梯度
print("w的梯度:", w.grad)

运行后会自动算出梯度,梯度数值代表参数更新方向。

CV场景重点:多张图像批量梯度

训练时一批图片同时计算,梯度会自动累加,这也是DataLoader批量训练的底层逻辑。

四、梯度清零,新手高频踩坑点

PyTorch梯度不会自动覆盖,每次循环训练梯度会持续累加,导致loss不收敛、模型训练失效。

每一轮训练必须手动清零梯度

python
# 优化器梯度清零(标准训练写法)
optimizer.zero_grad()
# 正向传播计算loss
# 反向传播求梯度
loss.backward()
# 更新权重参数
optimizer.step()

90%新手训练分类/YOLO模型不收敛,根源就是忘记清零梯度。

五、with torch.no_grad():推理关闭梯度

图片预测、模型测试阶段,不需要计算梯度,使用torch.no_grad()关闭梯度记录:

1. 大幅节省内存、加快推理速度

2. 避免占用显存,低配置电脑也能实时摄像头检测

python
# 推理阶段禁用梯度
with torch.no_grad():
    img = torch.rand(1, 3, 256, 256)
    output = model(img)  # 无梯度计算,速度更快

后续YOLO摄像头实时推理会高频用到这段代码。

六、CPU/GPU梯度迁移注意事项

张量在GPU上计算梯度时,转回numpy输出必须先执行.cpu().detach()

python
if torch.cuda.is_available():
    w = w.cuda()
    loss = (w * 3 - 9) ** 2
    loss.backward()
    # 提取梯度转numpy,先detach脱离计算图
    grad_np = w.grad.cpu().detach().numpy()

缺少detach会报计算图残留报错,做可视化、绘制loss曲线必备。

七、本期完整总结

1. requires_grad=True:开启张量梯度记录,仅模型权重需要开启;

2. 正向传播搭建计算图,backward()实现自动求导,不用手动推导数学公式;

3. 训练循环四步标准流程:清零梯度前向计算loss→反向求梯度更新参数;

4. 推理阶段使用torch.no_grad()关闭梯度,节约显存提升速度;

5. GPU张量提取数值必须搭配detach(),断开计算图。

下期预告

梯度原理彻底掌握后,下一期进入CV实操模块:DatasetDataLoader数据集加载器,教你自定义图片数据集,搭建深度学习标准数据读取流水线,衔接后续手写数字分类实战项目。

文末福利

本期完整梯度演示代码、标准训练循环模板、no_grad推理工具代码整理完毕

关注【AI与计算机视觉】,跟着系列稳步学习计算机视觉深度学习!

【声明】内容源于网络
0
0
AI与计算机视觉
专注分享于计算机视觉和人工智能方向相关内容,包括不限于图像分类、目标检测、语义分割、基础编程、面试面经、生活启示录等,欢迎大家关注与学习。
内容 78
粉丝 0
AI与计算机视觉 专注分享于计算机视觉和人工智能方向相关内容,包括不限于图像分类、目标检测、语义分割、基础编程、面试面经、生活启示录等,欢迎大家关注与学习。
总阅读356
粉丝0
内容78