跳转至

PyTorch 从入门到精通:详细教程

1. PyTorch 简介

PyTorch 是一个开源的深度学习框架,提供了灵活的自动微分动态图计算功能,尤其适用于研究和生产。它的张量(Tensor)计算与自动求导功能十分强大,在神经网络的实现与优化中起到核心作用。

2. 环境安装与配置

2.1 安装 PyTorch

可以通过以下命令安装 PyTorch:

pip install torch torchvision torchaudio

选择合适的安装命令:你可以根据是否使用 GPU 在 PyTorch 官方页面找到合适的安装指令:PyTorch 安装页面

3. 张量基础(Tensor Basics)

3.1 创建张量

张量(Tensor)是 PyTorch 的基础数据结构,类似于 NumPy 数组,但支持 GPU 加速运算。

import torch

# 创建一个未初始化的5x3张量
x = torch.empty(5, 3)
print(x)

# 创建随机初始化的张量
x = torch.rand(5, 3)
print(x)

# 全零张量,并指定数据类型为 long
x = torch.zeros(5, 3, dtype=torch.long)
print(x)

# 通过数据创建张量
x = torch.tensor([5.5, 3])
print(x)

3.2 张量的运算

张量支持多种基本运算操作,如加法、矩阵乘法、索引操作等。

# 张量加法
y = torch.rand(5, 3)
print(x + y)

# 使用函数实现加法
print(torch.add(x, y))

# 原地加法操作
y.add_(x)
print(y)

3.3 张量与 NumPy 的互操作性

PyTorch 张量可以与 NumPy 数组无缝转换。

# 张量转 NumPy
a = torch.ones(5)
b = a.numpy()
print(b)

# NumPy 转张量
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
print(b)

4. 自动求导机制(Autograd)

PyTorch 的 autograd 模块提供了自动求导功能,能够高效地实现反向传播,构建神经网络时非常重要。

4.1 自动求导基本概念

在计算中设置 requires_grad=True 后,PyTorch 会追踪每个操作并构建一个计算图,从而在调用 backward() 时自动计算梯度。

x = torch.ones(2, 2, requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()

# 反向传播
out.backward()
print(x.grad)  # 输出 x 的梯度

4.2 停止自动求导

可以使用 torch.no_grad() 关闭自动求导以节省计算资源,特别是推理阶段。

with torch.no_grad():
    print((x ** 2).requires_grad)  # 输出:False

5. 深度学习基础:构建神经网络

PyTorch 提供了 torch.nn 模块来简化神经网络的构建,神经网络中的每一层都被封装为一个类。

5.1 定义一个简单的神经网络

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        # 定义三层全连接层
        self.fc1 = nn.Linear(784, 128)  # 输入层(28x28像素展开为784)
        self.fc2 = nn.Linear(128, 64)   # 隐藏层
        self.fc3 = nn.Linear(64, 10)    # 输出层

    def forward(self, x):
        # 定义前向传播
        x = F.relu(self.fc1(x))  # 使用 ReLU 激活函数
        x = F.relu(self.fc2(x))
        x = self.fc3(x)  # 输出层无激活函数
        return x

net = Net()
print(net)

5.2 激活函数

在神经网络中,激活函数帮助网络引入非线性能力,常见的激活函数包括 ReLUSigmoidTanh 等。

x = torch.randn(1, 784)
output = F.relu(net.fc1(x))  # ReLU 激活函数

5.3 反向传播与优化器

模型训练中,损失函数用于计算预测值与真实值的差异,优化器则根据误差更新网络权重。

criterion = nn.CrossEntropyLoss()  # 使用交叉熵损失

# 定义优化器:使用 SGD 优化器
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.9)

6. 训练神经网络

神经网络的训练通常包含以下步骤: 1. 前向传播:通过网络计算输出。 2. 损失计算:通过损失函数计算输出与真实标签之间的差异。 3. 反向传播:通过自动求导机制计算梯度。 4. 权重更新:使用优化器更新网络的权重。

6.1 训练循环

for epoch in range(10):  # 训练10个周期
    running_loss = 0.0
    for inputs, labels in trainloader:
        optimizer.zero_grad()  # 清除前一次的梯度
        outputs = net(inputs)  # 前向传播
        loss = criterion(outputs, labels)  # 计算损失
        loss.backward()  # 反向传播
        optimizer.step()  # 更新权重

        running_loss += loss.item()
    print(f'Epoch {epoch+1}, Loss: {running_loss/len(trainloader)}')

7. 数据加载与处理

处理大规模数据时,PyTorch 提供了 torch.utils.data 模块,可以很方便地加载数据集并进行批处理。

7.1 使用内置数据集

from torchvision import datasets, transforms

# 定义数据的预处理
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

# 加载 MNIST 数据集
trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

7.2 自定义数据集

可以通过继承 Dataset 类来创建自定义数据集。

from torch.utils.data import Dataset

class CustomDataset(Dataset):
    def __init__(self, data, labels):
        self.data = data
        self.labels = labels

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        return self.data[idx], self.labels[idx]

dataset = CustomDataset(data, labels)
loader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)

8. 模型评估与测试

8.1 评估模型准确率

训练完成后,模型的评估是不可或缺的,可以通过关闭梯度计算来加速推理。

correct = 0
total = 0
with torch.no_grad():  # 关闭梯度计算
    for inputs, labels in testloader:
        outputs = net(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy: {100 * correct / total} %')

9. 模型保存与加载

PyTorch 提供了方便的模型保存与加载方法。保存模型可以在训练后使用,或者在模型部署时进行使用。

# 保存模型参数
torch.save(net.state_dict(), 'model.pth')

# 加载模型参数
net.load_state_dict(torch.load('model.pth'))

10. GPU 加速

PyTorch 提供了对 GPU 的支持,使得在大型模型的训练中显著加速。

# 检查 GPU 是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 将模型和数据移到 GPU 上
net.to(device)
inputs, labels = inputs.to(device), labels.to(device)

11. 高级模型与应用

11.1 循环神经网络(RNN)

RNN 能够处理序列数据,常用于时间序列和 NLP 任务。

rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=2)
input = torch.randn(5, 3, 10)  # 序列长度为5,batch size 为 3,输入维度为 10
h0 = torch.randn(2, 3, 20)  # 初始隐藏状态
output, hn = rnn(input, h0)

11.2 长短期记忆网络(LSTM)

LSTM 是 RNN 的改进版,解决了传统 RNN 的梯度消失问题,适合处理长序列。

lstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
input = torch.randn(5, 3, 10)
h0 = torch.randn(2, 3, 20)
c0 = torch.randn(2, 3, 20)
output, (hn, cn) = lstm(input, (h0, c0))

11.3 Transformer

Transformer 是现代 NLP 任务中的核心模型,PyTorch 提供了 nn.Transformer 的实现。

transformer = nn.Transformer(d_model=512, nhead=8)
src = torch.rand((10, 32, 512))  # 序列长度为 10,batch size 为 32,特征维度为 512
tgt = torch.rand((20, 32, 512))  # 目标序列
out = transformer(src, tgt)

12. 深度学习模型优化技巧

12.1 权重初始化

权重初始化对训练的收敛速度和稳定性有很大的影响,可以使用 torch.nn.init 模块进行初始化。

import torch.nn.init as init
init.xavier_uniform_(net.fc1.weight)

12.2 学习率调度

使用 torch.optim.lr_scheduler 可以在训练过程中动态调整学习率,提升模型性能。

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
for epoch in range(100):
    train(...)
    scheduler.step()

12.3 正则化

通过添加正则化策略,如 Dropout 和 L2 正则化,可以有效防止模型过拟合。

# Dropout
self.dropout = nn.Dropout(p=0.5)

# L2 正则化
optimizer = torch.optim.SGD(net.parameters(), lr=0.01, weight_decay=0.01)

13. 部署与推理优化

13.1 导出为 TorchScript

可以将模型导出为 TorchScript 以用于生产部署。

# 使用 TorchScript 导出模型
traced_model = torch.jit.trace(net, torch.rand(1, 784))
traced_model.save("model_scripted.pt")

13.2 ONNX 模型导出

PyTorch 支持将模型导出为 ONNX 格式,以便在其他深度学习框架中进行推理。

torch.onnx.export(net, torch.randn(1, 784), "model.onnx")

14. 资源与学习途径

  • 官方文档PyTorch 官方文档
  • 实战书籍:《深度学习实战:用 PyTorch 实现》
  • 开源项目:访问 GitHub 上的 PyTorch 项目学习实战代码