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 激活函数
在神经网络中,激活函数帮助网络引入非线性能力,常见的激活函数包括 ReLU
、Sigmoid
、Tanh
等。
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 项目学习实战代码