1. PyTorch 是什么?
PyTorch 是一个深度学习框架,主要特点:
- 易用:语法接近 NumPy,适合初学者。
- 动态图计算:运行时构建计算图,调试方便。
- GPU 加速:支持 CUDA,让模型训练更快。
- 社区活跃:有大量教程、模型和工具。
2. 安装 PyTorch
在终端运行:
# CPU 版本
pip install torch torchvision torchaudio
# GPU 版本(以 CUDA 11.8 为例)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
如果不确定 CUDA 版本,可以运行
nvidia-smi查看。
3. PyTorch 核心概念
3.1 张量(Tensor)
张量是 PyTorch 的核心数据结构,类似 NumPy 的多维数组,但可以在 GPU 上运行。
import torch
# 创建张量
x = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
print(x)
# 随机初始化
rand_x = torch.rand((2, 3))
print(rand_x)
# 张量运算
y = torch.ones((2, 2))
print(x + y) # 加法
print(x @ y) # 矩阵乘法
3.2 自动求导(Autograd)
PyTorch 会自动记录运算过程,并计算梯度。
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x + 1
y.backward() # 反向传播
print(x.grad) # dy/dx = 2x + 3 = 7
3.3 GPU 加速
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
x = torch.rand((1000, 1000)).to(device)
y = torch.rand((1000, 1000)).to(device)
z = x @ y
print(z.device) # cuda:0
4. MNIST 手写数字识别实战
4.1 任务介绍
MNIST 数据集包含 70,000 张 28×28 像素的手写数字图片(0-9),目标是训练一个模型识别数字。
4.2 数据加载
import torch
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
# 数据预处理:转为张量并归一化到 [0,1]
transform = transforms.ToTensor()
# 下载训练集和测试集
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
# 数据加载器
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
4.3 构建模型
我们用一个简单的 多层感知机(MLP):
- 输入层:784 个节点(28×28 像素展开)
- 隐藏层:128 个节点
- 输出层:10 个节点(数字 0-9)
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc1 = nn.Linear(28*28, 128) # 输入层 → 隐藏层
self.relu = nn.ReLU()
self.fc2 = nn.Linear(128, 10) # 隐藏层 → 输出层
def forward(self, x):
x = x.view(-1, 28*28) # 展平
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
4.4 定义损失函数和优化器
import torch.optim as optim
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = SimpleNet().to(device)
criterion = nn.CrossEntropyLoss() # 分类任务常用
optimizer = optim.Adam(model.parameters(), lr=0.001)
4.5 训练模型
for epoch in range(5): # 训练 5 轮
model.train()
running_loss = 0.0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad() # 清空梯度
outputs = model(images) # 前向传播
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
running_loss += loss.item()
print(f"Epoch [{epoch+1}/5], Loss: {running_loss/len(train_loader):.4f}")
4.6 测试模型
model.eval()
correct = 0
total = 0
with torch.no_grad(): # 测试时不计算梯度
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs, 1) # 取最大概率的类别
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"Test Accuracy: {100 * correct / total:.2f}%")
4.7 保存与加载模型
# 保存
torch.save(model.state_dict(), "mnist_model.pth")
# 加载
model = SimpleNet()
model.load_state_dict(torch.load("mnist_model.pth"))
model.eval()

3177

被折叠的 条评论
为什么被折叠?



