PyTorch 基础(一文讲透)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在深度学习领域,PyTorch 已经成为开发者最青睐的框架之一。它凭借动态计算图、直观的 API 设计以及强大的社区支持,为初学者和中级开发者提供了友好的学习曲线。本文将以“PyTorch 基础”为核心,通过循序渐进的讲解、形象的比喻和实际案例,帮助读者掌握 PyTorch 的核心概念与操作逻辑。无论你是希望入门深度学习,还是想优化现有项目的开发效率,这篇文章都将为你提供清晰的路径。
一、Tensor:PyTorch 的核心数据结构
在 PyTorch 中,Tensor 是所有操作的基础。可以将其理解为一个“多维数组容器”,但它的运算速度远超普通的 Python 列表,且能够利用 GPU 加速计算。
1.1 Tensor 的创建与基本操作
以下代码展示了如何创建不同维度的 Tensor:
import torch
zero_tensor = torch.zeros(2, 3)
print("Zero Tensor:\n", zero_tensor)
random_tensor = torch.rand(3, 3)
print("\nRandom Tensor:\n", random_tensor)
list_data = [[1, 2, 3], [4, 5, 6]]
tensor_from_list = torch.tensor(list_data)
print("\nTensor from List:\n", tensor_from_list)
1.2 Tensor 与 NumPy 的交互
PyTorch 和 NumPy 的数据结构高度兼容,可通过以下方式互相转换:
import numpy as np
numpy_array = tensor_from_list.numpy()
print("Type of numpy_array:", type(numpy_array))
numpy_data = np.array([[7, 8], [9, 10]])
tensor_from_numpy = torch.from_numpy(numpy_data)
比喻:
想象 Tensor 是一个“智能仓库”,既能存储货物(数值),又能根据需求快速调整货架(维度),甚至与其他仓库(NumPy)无缝对接。
二、自动求导机制:PyTorch 的“自动微分引擎”
深度学习的核心是通过梯度下降优化模型参数。PyTorch 的自动求导(Autograd)系统,可以自动计算任意操作的梯度,无需手动推导公式。
2.1 记录计算历史与梯度计算
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2
y.backward()
print("Gradient of y with respect to x:", x.grad) # 输出:tensor(4.)
比喻:
自动求导就像一个“流水线”,当你定义一个数学表达式时,PyTorch 会自动记录每一步操作,形成一条“计算链”。当调用 .backward()
时,系统会沿着这条链逆向计算梯度,如同流水线上的工人逐层传递零件。
2.2 梯度累积与清除
若多次调用 .backward()
,梯度会累加而非覆盖。因此,需要手动清除缓存:
x.grad.zero_()
y = x ** 3
y.backward()
print("New gradient:", x.grad) # 输出:tensor(12.)
三、构建神经网络:从模块化设计到训练
PyTorch 的 nn.Module
类提供了模块化构建神经网络的接口,类似于“积木拼装”。
3.1 定义一个简单网络
import torch.nn as nn
import torch.nn.functional as F
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc1 = nn.Linear(784, 128) # 全连接层:输入784维,输出128维
self.fc2 = nn.Linear(128, 10) # 输出层:10类分类
def forward(self, x):
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
model = SimpleNet()
print(model)
3.2 模型训练流程
以线性回归为例,展示训练循环的核心步骤:
X = torch.randn(100, 1) * 10
y = 2 * X + 3 + torch.randn(100, 1)
model = nn.Linear(1, 1)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for epoch in range(500):
y_pred = model(X)
loss = criterion(y_pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("Final loss:", loss.item())
比喻:
模型训练如同“调整天平”。每次迭代中,损失函数衡量“偏差”,优化器根据梯度调整“砝码”(权重),逐步使预测值与真实值平衡。
四、实用工具与技巧
4.1 数据加载与预处理
使用 torch.utils.data.DataLoader
可以高效处理大规模数据:
from torch.utils.data import DataLoader, TensorDataset
dataset = TensorDataset(X, y)
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)
for batch_X, batch_y in dataloader:
# 执行训练步骤
4.2 模型保存与加载
torch.save(model.state_dict(), "model.pth")
model = nn.Linear(1, 1)
model.load_state_dict(torch.load("model.pth"))
model.eval()
4.3 可视化与调试
通过 matplotlib
可直观查看训练过程:
import matplotlib.pyplot as plt
losses = []
for epoch in range(500):
# ... 训练代码 ...
losses.append(loss.item())
plt.plot(losses)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.show()
五、常见问题与最佳实践
5.1 GPU 加速
if torch.cuda.is_available():
device = torch.device("cuda")
model.to(device)
X = X.to(device)
y = y.to(device)
5.2 避免梯度爆炸/消失
使用适当的激活函数(如 ReLU)、正则化(如 Dropout)或梯度裁剪(nn.utils.clip_grad_value_
)可缓解这些问题。
5.3 调试技巧
- 使用
print(tensor.shape)
检查维度 - 在关键步骤添加
assert
断言 - 使用
with torch.no_grad():
禁用梯度计算以加速推理
通过本文对 PyTorch 的核心概念、Tensor 操作、自动求导、网络构建及实用工具的讲解,读者已掌握了 PyTorch 的基础框架。PyTorch 的灵活性和强大功能,使其成为探索深度学习的绝佳起点。建议读者通过实际项目(如图像分类、文本生成)进一步实践,逐步深入 CNN、Transformer 等高级主题。记住:代码即理解,动手实践才是掌握 PyTorch 基础的最终路径。