跳转至

PyTorch 入门教程

概述

PyTorch是Facebook开发的深度学习框架,以动态计算图和Pythonic风格著称,是学术界和工业界最流行的深度学习框架之一。

安装配置

# CPU版本
pip install torch torchvision torchaudio

# GPU版本(CUDA 11.8)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# 验证安装
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"

张量基础

创建张量

import torch

# 从列表创建
x = torch.tensor([1, 2, 3])

# 创建特殊张量
zeros = torch.zeros(3, 3)      # 全零
ones = torch.ones(3, 3)        # 全一
rand = torch.rand(3, 3)        # 随机[0,1)
randn = torch.randn(3, 3)      # 标准正态分布
eye = torch.eye(3)             # 单位矩阵

# 指定类型
x_float = torch.tensor([1, 2, 3], dtype=torch.float32)

张量操作

# 基本运算
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])

# 逐元素运算
c = a + b      # 加法
d = a * b      # 乘法
e = torch.dot(a, b)  # 点积

# 矩阵运算
mat1 = torch.randn(3, 4)
mat2 = torch.randn(4, 5)
result = torch.matmul(mat1, mat2)  # 矩阵乘法

# 形状操作
x = torch.randn(2, 3, 4)
y = x.reshape(2, 12)     # 重塑
z = x.permute(1, 0, 2)   # 转置

GPU加速

# 检查GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 移动到GPU
x = torch.randn(1000, 1000)
x_gpu = x.to(device)

# 在GPU上运算
y_gpu = torch.matmul(x_gpu, x_gpu.T)

自动微分

autograd机制

# requires_grad=True 开启梯度追踪
x = torch.tensor(2.0, requires_grad=True)

# 前向传播
y = x ** 2 + 3 * x + 1

# 反向传播
y.backward()

# 查看梯度 dy/dx = 2x + 3
print(x.grad)  # tensor(7.)

梯度计算示例

# 多变量函数
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
w = torch.tensor([0.5, 0.5, 0.5], requires_grad=True)

# 前向传播
y = torch.sum(x * w) + 2

# 反向传播
y.backward()

print(x.grad)  # [0.5, 0.5, 0.5]
print(w.grad)  # [1., 2., 3.]

神经网络

nn.Module基础

import torch.nn as nn

class SimpleNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleNet, self).__init__()
        self.layer1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.layer2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        x = self.layer1(x)
        x = self.relu(x)
        x = self.layer2(x)
        return x

# 创建模型
model = SimpleNet(784, 256, 10)
print(model)

常用层

# 全连接层
linear = nn.Linear(10, 5)

# 卷积层
conv2d = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1)

# 池化层
pool = nn.MaxPool2d(kernel_size=2)

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

# BatchNorm
batchnorm = nn.BatchNorm1d(128)

# 激活函数
relu = nn.ReLU()
sigmoid = nn.Sigmoid()
tanh = nn.Tanh()

CNN示例

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2)
        )
        self.classifier = nn.Sequential(
            nn.Linear(64 * 7 * 7, 128),
            nn.ReLU(),
            nn.Dropout(0.5),
            nn.Linear(128, 10)
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

数据处理

Dataset与DataLoader

from torch.utils.data import Dataset, DataLoader

# 自定义数据集
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)
dataloader = DataLoader(
    dataset, 
    batch_size=32, 
    shuffle=True,
    num_workers=2
)

数据增强

from torchvision import transforms

transform = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(10),
    transforms.ColorJitter(brightness=0.2),
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

模型训练

完整训练流程

import torch.optim as optim
from torch.utils.data import DataLoader

# 1. 准备数据
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32)

# 2. 定义模型
model = CNN().to(device)

# 3. 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 4. 训练循环
for epoch in range(num_epochs):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

    # 5. 测试评估
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            _, predicted = torch.max(output.data, 1)
            total += target.size(0)
            correct += (predicted == target).sum().item()

    accuracy = 100 * correct / total
    print(f'Epoch [{epoch+1}/{num_epochs}], Accuracy: {accuracy:.2f}%')

学习率调度

# StepLR
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)

# CosineAnnealing
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50)

# OneCycleLR
scheduler = optim.lr_scheduler.OneCycleLR(
    optimizer, max_lr=0.01, steps_per_epoch=len(train_loader), epochs=num_epochs
)

模型保存与加载

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

# 保存完整模型
torch.save(model, 'model_full.pth')

# 加载模型
model = CNN()
model.load_state_dict(torch.load('model.pth'))
model.eval()

# 保存检查点
torch.save({
    'epoch': epoch,
    'model_state_dict': model.state_dict(),
    'optimizer_state_dict': optimizer.state_dict(),
    'loss': loss,
}, 'checkpoint.pth')

实战示例:MNIST手写数字识别

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 数据准备
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('./data', train=False, transform=transform)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000)

# 模型定义
class MNISTNet(nn.Module):
    def __init__(self):
        super(MNISTNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = torch.relu(self.conv1(x))
        x = torch.relu(self.conv2(x))
        x = torch.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = torch.relu(self.fc1(x))
        x = self.dropout2(x)
        x = self.fc2(x)
        return torch.log_softmax(x, dim=1)

# 训练
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MNISTNet().to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.NLLLoss()

for epoch in range(1, 11):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

    # 测试
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += criterion(output, target).item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()

    accuracy = 100. * correct / len(test_dataset)
    print(f'Epoch {epoch}: Accuracy {accuracy:.2f}%')

学习资源

# 官方资源
- PyTorch官网:https://pytorch.org
- PyTorch tutorials:https://pytorch.org/tutorials
- PyTorch文档:https://pytorch.org/docs

# 推荐课程
- fast.ai Practical Deep Learning
- Stanford CS231n Computer Vision
- Stanford CS224n NLP

下一步学习

  1. TensorFlow入门教程 - 对比学习另一个框架
  2. 深度学习教程 - 深入理论知识
  3. 计算机视觉 - CV实战应用