1. 安装PyTorch及依赖
在Debian系统上进行PyTorch深度学习的第一步是安装必要的依赖和PyTorch本身。首先更新系统包并安装Python、pip等基础工具:
sudo apt update && sudo apt upgrade -y
sudo apt install python3 python3-pip build-essential cmake git libopenblas-dev liblapack-dev -y
根据是否使用GPU选择PyTorch安装方式:
pip3 install torch torchvision torchaudio
/usr/local/cuda目录),然后通过pip安装对应CUDA版本的PyTorch(如CUDA 11.8):pip3 install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118
安装完成后,通过以下命令验证PyTorch是否可用及CUDA支持情况:
import torch
print(torch.__version__) # 查看PyTorch版本
print(torch.cuda.is_available()) # 若为True则表示GPU可用
2. 准备深度学习数据集
使用PyTorch的torchvision.datasets模块加载常用数据集(如MNIST、CIFAR-10),并通过transforms进行数据预处理(如转换为Tensor、归一化):
from torchvision import datasets, transforms
# 定义数据预处理:转换为Tensor并归一化到[-1,1]
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # 均值为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)
# 创建DataLoader(批量加载数据,shuffle=True表示打乱顺序)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
若需使用自定义数据集,可继承torch.utils.data.Dataset类,实现__len__(返回数据集大小)和__getitem__(返回单个样本及标签)方法。
3. 构建深度学习模型
通过继承torch.nn.Module类定义模型结构,forward方法指定前向传播逻辑。以下是一个简单的全连接神经网络(用于MNIST分类)和一个卷积神经网络(CNN,用于CIFAR-10分类)示例:
import torch.nn as nn
import torch.nn.functional as F
class MLP(nn.Module):
def __init__(self):
super(MLP, self).__init__()
self.fc1 = nn.Linear(28*28, 512) # 输入层到隐藏层(28x28=784维)
self.fc2 = nn.Linear(512, 256) # 隐藏层到隐藏层
self.fc3 = nn.Linear(256, 10) # 隐藏层到输出层(10类)
def forward(self, x):
x = x.view(-1, 28*28) # 将图像展平为向量(batch_size, 784)
x = F.relu(self.fc1(x)) # ReLU激活函数
x = F.relu(self.fc2(x))
x = self.fc3(x) # 输出层(无需激活,后续用CrossEntropyLoss自带Softmax)
return x
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1) # 输入通道1(灰度图),输出通道16
self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2) # 最大池化(下采样)
self.fc1 = nn.Linear(32 * 7 * 7, 128) # 全连接层(输入为池化后的特征图尺寸)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x))) # 卷积->ReLU->池化
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 32 * 7 * 7) # 展平特征图
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
4. 训练与验证模型
定义损失函数(如交叉熵损失CrossEntropyLoss,适用于多分类问题)和优化器(如SGD、Adam),然后通过迭代数据集进行训练和验证:
import torch.optim as optim
# 初始化模型、损失函数和优化器
model = MLP() # 或CNN()
criterion = nn.CrossEntropyLoss() # 多分类交叉熵损失
optimizer = optim.SGD(model.parameters(), lr=0.01) # 随机梯度下降(学习率0.01)
# 训练函数
def train_model(model, train_loader, criterion, optimizer, epochs=5):
model.train() # 设置为训练模式(启用Dropout、BatchNorm等层的训练逻辑)
for epoch in range(epochs):
running_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad() # 清空梯度
outputs = model(inputs) # 前向传播
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播(计算梯度)
optimizer.step() # 更新参数
running_loss += loss.item()
print(f'Epoch {epoch+1}/{epochs}, Loss: {running_loss/len(train_loader):.4f}')
# 验证函数
def validate_model(model, test_loader):
model.eval() # 设置为评估模式(禁用Dropout、BatchNorm等层的训练逻辑)
correct = 0
total = 0
with torch.no_grad(): # 禁用梯度计算(节省内存)
for inputs, labels in test_loader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1) # 获取预测类别(概率最大的类别)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Test Accuracy: {100 * correct / total:.2f}%')
# 执行训练和验证
train_model(model, train_loader, criterion, optimizer, epochs=5)
validate_model(model, test_loader)
5. 保存与加载模型
训练完成后,可将模型参数保存到磁盘,后续可直接加载使用(无需重新训练):
# 保存模型(保存整个模型结构和参数)
torch.save(model, 'my_model.pth')
# 加载模型
loaded_model = torch.load('my_model.pth')
loaded_model.eval() # 设置为评估模式
若仅需保存模型参数(更轻量,但需提前定义模型结构):
# 保存参数
torch.save(model.state_dict(), 'my_model_params.pth')
# 加载参数
model = MLP() # 重新创建模型实例
model.load_state_dict(torch.load('my_model_params.pth'))
model.eval()