PyTorch 基础(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 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 基础的最终路径。

最新发布