前言

PyTorch 作为当前最受欢迎的深度学习框架之一,以其直观的接口和灵活的设计成为了许多研究人员和开发者的首选。但面对众多的功能和概念,初学者往往不知道从哪里开始。

本文专为 PyTorch 新手设计,将带你一步步掌握最核心、最实用的基础技巧。我们不会涉及复杂的高级特性,而是聚焦于那些能让你快速上手、建立信心的基础操作。从环境配置到第一个神经网络训练,你将学会如何用 PyTorch 完成深度学习项目中的基本任务。!

一、环境配置与验证

1. 安装 PyTorch

访问 PyTorch 官网 获取最适合你系统的安装命令:

# 使用 conda 安装(推荐初学者)
conda install pytorch torchvision torchaudio cpuonly -c pytorch

# 或者使用 pip 安装
pip install torch torchvision torchaudio

2. 验证安装

安装完成后,创建一个 Python 文件或打开 Jupyter Notebook,运行以下代码验证安装:

import torch

# 检查 PyTorch 版本
print(f"PyTorch 版本: {torch.__version__}")

# 检查 GPU 是否可用(如果使用 GPU 版本)
print(f"GPU 可用: {torch.cuda.is_available()}")

# 如果是 Apple Silicon Mac
if hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():
    print("MPS 可用: True")
else:
    print("MPS 可用: False")

二、张量基础操作

1. 创建张量

张量(Tensor)是 PyTorch 中最基本的数据结构,类似于 NumPy 的数组:

# 创建张量的多种方式
import torch

# 从列表创建
x = torch.tensor([1, 2, 3, 4])
print(f"从列表创建: {x}")

# 创建全零张量
zeros = torch.zeros(2, 3)  # 2行3列
print(f"全零张量:\n{zeros}")

# 创建全一张量
ones = torch.ones(2, 3)
print(f"全一张量:\n{ones}")

# 创建随机张量
rand_tensor = torch.rand(2, 3)  # 值在 0-1 之间
print(f"随机张量:\n{rand_tensor}")

# 创建范围张量
range_tensor = torch.arange(0, 10, 2)  # 从0开始,到10结束(不含),步长为2
print(f"范围张量: {range_tensor}")

2. 张量运算

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

print(f"加法: {a + b}")        # 或者 torch.add(a, b)
print(f"减法: {a - b}")        # 或者 torch.sub(a, b)
print(f"乘法: {a * b}")        # 或者 torch.mul(a, b) - 逐元素相乘
print(f"除法: {a / b}")        # 或者 torch.div(a, b) - 逐元素相除

# 矩阵乘法
matrix_a = torch.rand(2, 3)
matrix_b = torch.rand(3, 2)
matrix_product = torch.matmul(matrix_a, matrix_b)  # 或者使用 @ 运算符
print(f"矩阵乘法结果形状: {matrix_product.shape}")

# 改变张量形状
original = torch.arange(6)  # [0, 1, 2, 3, 4, 5]
reshaped = original.reshape(2, 3)  # 改为 2x3 矩阵
print(f"重塑后的张量:\n{reshaped}")

三、自动求导机制

PyTorch 的自动求导(Autograd)是其核心特性之一,可以自动计算梯度:

# requires_grad=True 告诉 PyTorch 需要跟踪计算梯度
x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(3.0, requires_grad=True)

# 定义一个计算
z = x**2 + y**3 + x*y

# 自动计算梯度
z.backward()

print(f"z 对 x 的梯度: {x.grad}")  # dz/dx = 2x + y = 2*2 + 3 = 7
print(f"z 对 y 的梯度: {y.grad}")  # dz/dy = 3y² + x = 3*9 + 2 = 29

四、构建第一个神经网络

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(28*28, 128)  # 输入层到隐藏层
        self.fc2 = nn.Linear(128, 64)     # 隐藏层到隐藏层
        self.fc3 = nn.Linear(64, 10)      # 隐藏层到输出层
        
    def forward(self, x):
        # 定义前向传播
        x = x.view(-1, 28*28)  # 展平输入
        x = F.relu(self.fc1(x))  # 第一层 + ReLU激活
        x = F.relu(self.fc2(x))  # 第二层 + ReLU激活
        x = self.fc3(x)          # 输出层
        return x

# 创建模型实例
model = SimpleNet()
print(model)

2. 选择损失函数和优化器

import torch.optim as optim

# 定义损失函数 - 对于分类问题常用交叉熵损失
criterion = nn.CrossEntropyLoss()

# 定义优化器 - 随机梯度下降
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 或者使用 Adam 优化器
# optimizer = optim.Adam(model.parameters(), lr=0.001)

五、数据处理与加载

1. 使用内置数据集

from torchvision import datasets, transforms

# 定义数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),  # 转换为张量
    transforms.Normalize((0.5,), (0.5,))  # 标准化
])

# 加载 MNIST 数据集
train_dataset = datasets.MNIST(
    root='./data', 
    train=True, 
    download=True, 
    transform=transform
)

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

2. 创建数据加载器

from torch.utils.data import DataLoader

# 创建数据加载器
train_loader = DataLoader(
    train_dataset, 
    batch_size=32, 
    shuffle=True  # 训练时打乱数据
)

test_loader = DataLoader(
    test_dataset, 
    batch_size=32, 
    shuffle=False  # 测试时不打乱
)

# 查看一个批次的数据
for images, labels in train_loader:
    print(f"图像形状: {images.shape}")  # [32, 1, 28, 28]
    print(f"标签形状: {labels.shape}")  # [32]
    break

六、训练你的第一个模型

1. 训练循环

# 设置训练轮数
num_epochs = 5

for epoch in range(num_epochs):
    # 训练模式
    model.train()
    running_loss = 0.0
    
    for i, (images, labels) in enumerate(train_loader):
        # 清零梯度
        optimizer.zero_grad()
        
        # 前向传播
        outputs = model(images)
        
        # 计算损失
        loss = criterion(outputs, labels)
        
        # 反向传播
        loss.backward()
        
        # 更新参数
        optimizer.step()
        
        running_loss += loss.item()
        
        # 每100个批次打印一次损失
        if (i + 1) % 100 == 0:
            print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
    
    # 每个epoch打印平均损失
    print(f'Epoch [{epoch+1}/{num_epochs}], Average Loss: {running_loss/len(train_loader):.4f}')

2. 模型评估

# 评估模式
model.eval()
correct = 0
total = 0

# 在测试集上评估
with torch.no_grad():  # 不需要计算梯度
    for images, labels in test_loader:
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)  # 获取预测结果
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'测试准确率: {100 * correct / total:.2f}%')

七、实用小技巧

1. 设备管理

# 自动选择设备(CPU 或 GPU)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'使用设备: {device}')

# 将模型和数据移动到设备
model = model.to(device)

# 在训练时记得将数据也移动到设备
for images, labels in train_loader:
    images = images.to(device)
    labels = labels.to(device)
    # ... 训练代码 ...

2. 保存和加载模型

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

# 加载模型
loaded_model = SimpleNet()
loaded_model.load_state_dict(torch.load('model.pth'))
loaded_model.eval()  # 设置为评估模式

总结

通过本文的学习,你已经掌握了 PyTorch 的基础使用技巧。让我们回顾一下今天学到的核心内容:

  1. 环境搭建:学会了如何安装和验证 PyTorch,这是所有工作的基础
  2. 张量操作:理解了 PyTorch 中基本的数据结构 - 张量,以及如何进行各种数学运算
  3. 自动求导:了解了 PyTorch 强大的自动梯度计算能力,这是训练神经网络的核心
  4. 网络构建:学会了如何定义自己的神经网络模型
  5. 数据处理:掌握了如何加载和处理训练数据
  6. 模型训练:完成了第一个神经网络的训练和评估流程
  7. 实用技巧:了解了一些提高效率的小技巧

记住,学习 PyTorch 是一个循序渐进的过程。不要急于求成,多动手实践是最好的学习方法。建议你:

  • 尝试修改网络结构(增加/减少层数、改变神经元数量)
  • 调整超参数(学习率、批大小、优化器等)
  • 在不同的数据集上测试你的模型
  • 加入正则化技术(如 Dropout)来防止过拟合

PyTorch 社区非常活跃,有大量的教程和资源可供学习。当你遇到问题时,不要犹豫去查阅官方文档或在论坛上寻求帮助。

更多推荐