Pytorch 三小时极限入门教程
一、引言
在当今的人工智能领域,深度学习占据了举足轻重的地位。而 Pytorch 作为一款广受欢迎的深度学习框架,以其简洁、灵活的特性,吸引了大量开发者投身其中。无论是科研人员探索前沿的神经网络架构,还是工程师将深度学习技术落地到实际项目,Pytorch 都提供了强大的支持。本教程将带你从零基础开始,一步步深入了解 Pytorch 的核心知识,助你顺利踏上深度学习的征程。
二、Pytorch 基础环境搭建
安装 Anaconda
Anaconda 是一个强大的 Python 包管理器和环境管理器,方便我们创建独立的 Python 开发环境。首先,从 Anaconda 官方网站下载对应操作系统的安装包,一路默认安装即可。安装完成后,打开终端(Linux/Mac)或命令提示符(Windows),输入 conda --version 验证是否安装成功。
创建虚拟环境
使用 conda create -n pytorch_env python=3.8 创建一个名为 pytorch_env 的虚拟环境,这里指定 Python 版本为 3.8,你可以根据实际需求调整。激活虚拟环境,在 Linux/Mac 下使用 source activate pytorch_env,Windows 下使用 activate pytorch_env。
安装 Pytorch
访问 Pytorch 官方网站,根据你的系统配置(如 CUDA 是否可用)选择合适的安装命令。例如,如果你的电脑有 NVIDIA GPU 且支持 CUDA 11.3,安装命令可能为 conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch。如果没有 GPU,则选择 CPU 版本的安装命令,如 conda install pytorch torchvision torchaudio cpuonly -c pytorch。安装完成后,在 Python 交互式环境中输入 import torch,没有报错则说明安装成功。
三、张量(Tensor):深度学习的基石
张量的定义与创建
张量是 Pytorch 中最基本的数据结构,类似于 NumPy 中的数组,但具有更强的功能。可以使用 torch.tensor() 函数从 Python 列表或 NumPy 数组创建张量,例如:
import torch
import numpy as np
# 从列表创建张量
data_list = [1, 2, 3, 4]
tensor_from_list = torch.tensor(data_list)
# 从 NumPy 数组创建张量
np_array = np.array([5, 6, 7, 8])
tensor_from_numpy = torch.from_numpy(np_array)
还可以使用 torch.zeros()、torch.ones()、torch.rand() 等函数创建具有特定形状的全 0、全 1 或随机值张量。
张量的属性与操作
张量具有形状(shape)、数据类型(dtype)等属性。可以通过 .shape 和 .dtype 来访问,例如:
tensor = torch.rand(3, 4)
print(tensor.shape)
print(tensor.dtype)
张量支持丰富的数学运算,如加法、减法、乘法、除法等,操作符重载使得代码简洁直观:
a = torch.rand(2, 3)
b = torch.rand(2, 3)
c = a + b
d = a * b
同时,也有大量的函数可供调用,像 torch.sum()、torch.mean() 等用于统计计算。
四、自动求导(Autograd):神经网络训练的关键
自动求导原理简介
在深度学习中,模型训练的核心是反向传播算法,而 Pytorch 的自动求导机制极大地简化了这一过程。当创建一个张量时,如果设置 requires_grad=True,Pytorch 会记录该张量上的所有操作,构建一个计算图。在反向传播时,利用这个计算图自动计算梯度。
示例:简单函数求导
x = torch.tensor([2.], requires_grad=True)
y = x ** 2 + 3 * x
y.backward()
print(x.grad)
这里定义了一个简单的函数 ,对 x 求导后,x.grad 存储了梯度值,即 在 时的值 7。
复杂模型中的应用
在构建神经网络时,模型参数都设置为 requires_grad=True。在每一次前向传播计算损失后,通过 loss.backward() 反向传播梯度,然后使用优化器(如 SGD、Adam 等)根据梯度更新参数,实现模型的训练。
五、神经网络模块(nn.Module):构建模型的利器
自定义神经网络
继承 nn.Module 类可以方便地自定义神经网络。首先在 __init__() 函数中定义模型的层结构,如全连接层 nn.Linear,卷积层 nn.Conv2d 等,然后在 forward() 函数中定义数据的前向传播路径。
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc1 = nn.Linear(10, 20)
self.fc2 = nn.Linear(20, 1)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
这里定义了一个简单的两层全连接神经网络,输入维度为 10,中间层维度为 20,输出维度为 1,中间使用 ReLU 作为激活函数。
预训练模型的使用与微调
Pytorch 提供了丰富的预训练模型,如 ResNet、VGG 等经典的图像分类模型。可以通过 torchvision.models 模块加载预训练模型,然后根据自己的任务需求,修改最后几层的结构并进行微调。例如:
import torchvision.models as models
resnet = models.resnet18(pretrained=True)
# 修改最后一层输出维度为自定义类别数
resnet.fc = nn.Linear(resnet.fc.in_features, 10)
这使得在数据量有限的情况下,也能利用预训练模型的强大特征提取能力,快速搭建高性能模型。
六、数据加载与预处理(DataLoader)
数据集类的构建
要使用自己的数据训练模型,需要构建自定义数据集类,继承 torch.utils.data.Dataset。在类中实现 __getitem__() 方法用于获取单个样本及其标签,__len__() 方法返回数据集的大小。例如,对于图像分类数据集:
from torch.utils.data import Dataset
import os
import cv2
class ImageDataset(Dataset):
def __init__(self, root_dir, transform=None):
self.root_dir = root_dir
self.image_files = os.listdir(root_dir)
self.transform = transform
def __getitem__(self, index):
image_path = os.path.join(self.root_dir, self.image_files[index])
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
label = int(self.image_files[index].split('.')[0])
if self.transform:
image = self.transform(image)
return image, label
def __len__(self):
return len(self.image_files)
数据加载器的使用
使用 torch.utils.data.DataLoader 将数据集封装成可迭代的数据加载器,方便在训练过程中批量获取数据。可以设置批量大小(batch_size)、是否打乱数据(shuffle)等参数,例如:
from torch.utils.data import DataLoader
dataset = ImageDataset(root_dir='data/images', transform=transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
在训练循环中,通过遍历数据加载器获取批量数据,送入模型进行训练。
七、模型训练与评估
训练循环
模型训练通常包括多个 epoch,每个 epoch 遍历一遍整个数据集。在每个 epoch 内,按批次获取数据,前向传播计算损失,反向传播更新参数。以下是一个简单的训练循环示例:
model = SimpleNet()
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for epoch in range(10):
running_loss = 0.0
for i, (inputs, labels) in enumerate(dataloader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch + 1}, Loss: {running_loss / len(dataloader)}')
评估指标与方法
根据任务不同,评估指标各异。对于分类任务,常用准确率(Accuracy),可以通过比较模型预测结果与真实标签计算得出:
correct = 0
total = 0
with torch.no_grad():
for inputs, labels in dataloader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = correct / total
print(f'Accuracy: {accuracy}')
对于回归任务,可能使用均方误差(MSE)、平均绝对误差(MAE)等指标。
八、模型保存与加载
保存模型
可以使用 torch.save() 保存模型的参数或整个模型结构,例如保存模型参数:
torch.save(model.state_dict(), 'model.pth')
若要保存整个模型,包括结构和参数:
torch.save(model, 'whole_model.pth')
加载模型
加载模型参数时,先创建模型实例,再使用 model.load_state_dict(torch.load('model.pth')) 加载。若加载整个模型,则直接 model = torch.load('whole_model.pth')。加载后,模型即可用于预测或继续训练。
九、可视化工具(TensorBoard)
安装与配置
TensorBoard 是一个强大的可视化工具,用于监控模型训练过程。使用 pip install tensorboard 安装,在 Pytorch 代码中引入相关模块:
from torch.utils.tensorboard import SummaryWriter
创建一个 SummaryWriter 实例,指定日志目录,如 writer = SummaryWriter('logs')。
可视化训练过程
在训练过程中,可以使用 writer.add_scalar() 记录损失、准确率等指标随 epoch 的变化:
for epoch in range(10):
# 训练代码...
writer.add_scalar('Loss', running_loss / len(dataloader), epoch)
writer.add_scalar('Accuracy', accuracy, epoch)
writer.close()
运行 tensorboard --logdir=logs 命令后,在浏览器中打开相应地址,即可查看可视化图表,直观了解模型训练动态。