详解pytorch
PyTorch 是一个基于 Python 的开源深度学习框架,由 Facebook 的 AI 研究团队(现 Meta AI)开发并维护。它以动态计算图(动态图)、直观的 API 设计、强大的 GPU 加速支持以及活跃的社区而著称,已成为学术界和研究领域的事实标准,并在工业界应用日益广泛。
以下详细讲解 PyTorch 的核心概念、重要包(模块)及其功能:
一、PyTorch 的核心设计理念
- Tensor 为中心:
- 所有数据(输入、模型参数、中间结果)都用
torch.Tensor
表示(类似于 NumPy 的ndarray
,但支持 GPU 计算和自动求导)。 - 是构建和操作计算图的基础单元。
- 所有数据(输入、模型参数、中间结果)都用
- 动态计算图(Define-by-Run):
- 核心优势! 计算图在执行过程中动态构建。
- 更符合 Python 的编程习惯(像写普通 Python 代码一样写神经网络)。
- 调试极其方便: 可以使用 Python 的标准调试工具(如 pdb, ipdb)逐行调试。
- 灵活性高: 易于实现条件分支、循环等复杂控制流(如 RNNs, Tree-RNNs)。
- 无缝 GPU/CPU 切换:
- 使用
.to('device')
(如.to('cuda')
,.to('cpu')
)即可将 Tensor 或模型在设备间轻松移动。 - 底层自动处理 CUDA 调用。
- 使用
- 强大的自动微分引擎(Autograd):
- 自动计算
Tensor
操作的梯度,是神经网络训练(反向传播)的基础。
- 自动计算
- 模块化设计:
- 通过
torch.nn.Module
构建模型,支持模块化、可复用和层级化的结构定义。
- 通过
二、PyTorch 最重要的包(模块)详解
1. torch
- 核心张量库
- 功能: 定义了
Tensor
数据类型及其基本操作(创建、索引、切片、数学运算、线性代数、随机数生成等)。 - 关键内容:
torch.Tensor
: 核心数据结构。支持多种数据类型 (dtype
:float32
,int64
,bool
等)和设备 (device
:'cpu'
,'cuda:0'
)。- 张量创建:
torch.tensor(data)
: 从数据(列表、NumPy 数组等)创建。torch.zeros/ones/empty(shape)
: 创建指定形状的填充张量。torch.rand/randn(shape)
: 创建均匀分布/标准正态分布的随机张量。torch.arange/linspace
: 创建序列张量。torch.from_numpy(ndarray)
: 从 NumPy 数组创建 Tensor(共享内存)。
- 张量操作:
- 数学运算:
+
,-
,*
,/
,**
,@
(矩阵乘),torch.matmul
,torch.sum
,torch.mean
,torch.exp
,torch.log
等。 - 索引/切片:
tensor[i, j]
,tensor[:, 1:5]
,tensor[mask]
。 - 形状操作:
tensor.view(shape)
/tensor.reshape(shape)
(改变形状,注意内存连续性),tensor.permute(dims)
(维度置换),tensor.squeeze()
/tensor.unsqueeze()
(压缩/增加维度为 1 的维度)。 - 连接/分割:
torch.cat(tensors, dim)
,torch.stack(tensors, dim)
,torch.split(tensor, split_size, dim)
,torch.chunk(tensor, chunks, dim)
。
- 数学运算:
- 与 NumPy 互操作:
tensor.numpy()
: 将 Tensor (cpu
上的) 转换为 NumPyndarray
(共享内存)。torch.from_numpy(ndarray)
: 如上所述。
2. torch.nn
- 神经网络构建模块
- 功能: 提供了构建神经网络所需的所有层、激活函数、损失函数和容器。核心是
nn.Module
。 - 关键内容:
nn.Module
:- 所有神经网络模块(层、模型)的基类。
- 必须重写
__init__
(定义子模块和参数)和forward
(定义前向传播逻辑)方法。 - 自动跟踪其内部的
nn.Parameter
对象(可学习参数)。 - 支持层级结构:
Module
可以包含其他Module
。 - 提供
.to(device)
,.train()
,.eval()
,.parameters()
,.state_dict()
,.load_state_dict()
等实用方法。
- 层 (Layers):
nn.Linear(in_features, out_features)
: 全连接层(线性层)。nn.Conv1d/2d/3d(in_channels, out_channels, kernel_size, ...)
: 一维/二维/三维卷积层(CNN 核心)。nn.MaxPool1d/2d/3d(kernel_size, ...)
,nn.AvgPool1d/2d/3d(kernel_size, ...)
: 最大/平均池化层。nn.BatchNorm1d/2d/3d(num_features)
: 批标准化层(加速训练、提高稳定性)。nn.Dropout(p=dropout_prob)
: Dropout 层(防止过拟合)。nn.Embedding(num_embeddings, embedding_dim)
: 嵌入层(用于离散特征、NLP)。nn.RNN/LSTM/GRU(input_size, hidden_size, ...)
: 循环神经网络层(用于序列数据)。nn.Transformer(...)
: Transformer 层(NLP、CV 新星)。
- 激活函数 (Activation Functions):
nn.ReLU()
,nn.Sigmoid()
,nn.Tanh()
,nn.LeakyReLU(negative_slope)
,nn.Softmax(dim)
,nn.LogSoftmax(dim)
。通常作为forward
中的函数使用。
- 损失函数 (Loss Functions):
nn.MSELoss()
: 均方误差损失(回归)。nn.CrossEntropyLoss()
: 交叉熵损失(分类,常用,内部包含LogSoftmax
)。nn.BCELoss()
,nn.BCEWithLogitsLoss()
: 二值交叉熵损失(二分类,后者更稳定)。nn.NLLLoss()
: 负对数似然损失(需配合LogSoftmax
使用)。nn.L1Loss()
: L1 损失(回归)。nn.HuberLoss()
: Huber 损失(回归,鲁棒性更好)。
- 容器 (Containers):
nn.Sequential(*modules)
: 顺序容器,按顺序执行多个模块。快速构建简单模型。nn.ModuleList(modules)
: 将子模块存储在列表中(需手动定义forward
)。nn.ModuleDict(modules)
: 将子模块存储在字典中(需手动定义forward
)。
- 实用函数:
nn.Flatten()
: 将张量展平(常用于全连接层之前)。nn.Identity()
: 恒等映射(占位符或跳过连接)。
3. torch.optim
- 优化算法
- 功能: 提供了各种基于梯度下降的优化器,用于更新模型参数以最小化损失函数。
- 关键内容:
- 优化器类: 都需要传入待优化的参数(通常通过
model.parameters()
获取)和学习率lr
等超参数。optim.SGD(params, lr, momentum=0, dampening=0, weight_decay=0, nesterov=False)
: 随机梯度下降(可带动量)。optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
: 自适应矩估计(最常用,速度快,效果好)。optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0, eps=1e-10)
optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)
optim.AdamW(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0.01, amsgrad=False)
: Adam 的改进版,更好地处理权重衰减(L2 正则化)。
- 核心方法:
optimizer.zero_grad()
: 至关重要! 在每次参数更新前,将模型参数的梯度清零。防止梯度累积。optimizer.step()
: 执行一次参数更新步骤(使用当前存储的梯度)。optimizer.add_param_group()
: 添加新的参数组(例如微调时添加新层)。optimizer.state_dict()
,optimizer.load_state_dict()
: 保存/加载优化器状态(包括学习率调度状态)。
- 优化器类: 都需要传入待优化的参数(通常通过
4. torch.autograd
- 自动微分引擎
- 功能: 提供自动计算张量操作梯度的功能(反向传播的核心)。
- 关键概念:
requires_grad
属性:- 当
Tensor
的.requires_grad=True
时,PyTorch 会跟踪所有作用在其上的操作。 - 用于创建需要计算梯度的参数或输入。
- 当
- 计算图:
- 当对
requires_grad=True
的 Tensor 进行操作时,PyTorch 在后台动态构建一个计算图。 - 图节点是
Tensor
,边是产生该Tensor
的函数(Function
对象)。
- 当对
- 梯度计算:
- 在完成前向计算后,在最终的标量
Tensor
(通常是损失loss
)上调用.backward()
。 autograd
沿着计算图反向传播,计算图中每个具有requires_grad=True
的Tensor
的梯度(.grad
属性)。
- 在完成前向计算后,在最终的标量
backward(gradient=None)
方法:- 在
loss
(一个标量)上调用loss.backward()
是标准用法。 - 如果
loss
是一个向量(非标量),需要传入一个与loss
形状相同的gradient
张量作为权重(指定每个分量在反向传播中的“重要性”)。
- 在
with torch.no_grad():
上下文管理器:- 在这个块内的操作不会被
autograd
跟踪。用于推理(预测)、评估指标计算或冻结参数(不需要计算梯度)的场景,节省内存和计算资源。
- 在这个块内的操作不会被
detach()
方法:- 返回一个新的
Tensor
,从当前计算图中分离出来,requires_grad=False
(内容共享)。 - 常用于截断梯度流或获取不需要梯度的中间值。
- 返回一个新的
torch.autograd.grad(outputs, inputs, grad_outputs=None, ...)
:- 更灵活地计算梯度(不一定需要从标量
loss
开始)。
- 更灵活地计算梯度(不一定需要从标量
5. torch.utils.data
- 数据加载与处理
- 功能: 提供了处理数据集和加载数据的工具类。
- 关键内容:
Dataset
抽象类:- 表示数据集。自定义数据集必须继承
Dataset
并实现两个方法:__len__()
: 返回数据集大小。__getitem__(idx)
: 根据索引idx
返回一个样本(特征,标签)。
- 表示数据集。自定义数据集必须继承
DataLoader
:- 核心工具! 围绕
Dataset
的迭代器,提供:- 批处理 (Batching):
batch_size
。 - 打乱数据 (Shuffling):
shuffle=True
(通常在训练时开启)。 - 多进程数据加载 (Multiprocessing):
num_workers > 0
(加速数据加载)。 - 采样 (Sampling): 支持自定义采样策略 (
sampler
,batch_sampler
)。 - 内存锁页 (Pinned Memory):
pin_memory=True
(加速 GPU 数据传输)。
- 批处理 (Batching):
- 用法:
dataloader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4)
- 遍历:
for batch_data, batch_labels in dataloader: ...
- 核心工具! 围绕
TensorDataset
:- 一个包装多个张量(特征张量、标签张量)的简单
Dataset
。要求所有张量的第一维(样本维度)大小相同。 - 用法:
dataset = TensorDataset(features_tensor, labels_tensor)
- 一个包装多个张量(特征张量、标签张量)的简单
- 采样器 (
Sampler
):RandomSampler
(随机采样),SequentialSampler
(顺序采样),WeightedRandomSampler
(加权随机采样) 等。
- 变换 (
Transform
):- 虽然变换逻辑通常定义在
__getitem__
中或使用torchvision.transforms
,但DataLoader
的collate_fn
参数可用于自定义如何将多个样本组合成一个 batch。
- 虽然变换逻辑通常定义在
6. torchvision
(独立包,但极度重要)
- 功能: PyTorch 生态中专用于计算机视觉 (CV) 的包。提供:
- 流行的预训练模型 (Models)。
- 常用图像数据集 (Datasets)。
- 图像变换和增强操作 (Transforms)。
- 实用工具函数 (Utils)。
- 关键子模块:
torchvision.models
:- 提供预训练好的经典和现代 CV 模型:
alexnet
,vgg
,resnet
,squeezenet
,densenet
,inception
,googlenet
,shufflenet
,mobilenet
,resnext
,wide_resnet
,mnasnet
,efficientnet
,vit
(Vision Transformer),swin_transformer
,regnet
,convnext
等。 - 用法:
model = torchvision.models.resnet18(pretrained=True) # 加载预训练权重
- 可以方便地用于迁移学习或特征提取。
- 提供预训练好的经典和现代 CV 模型:
torchvision.datasets
:- 提供常用 CV 数据集下载和加载接口:
MNIST
,FashionMNIST
,CIFAR10
,CIFAR100
,ImageFolder
(通用图像文件夹),DatasetFolder
,COCO
,VOCDetection
,VOCSegmentation
,Cityscapes
,STL10
,SVHN
,PhotoTour
,SBU
,Flickr
,KMNIST
,EMNIST
,QMNIST
,Omniglot
,LSUN
,LSUNClass
,ImageNet
,Places365
,Kinetics-400/600/700
,UCF101
,HMDB51
等。 - 通常与
torchvision.transforms
结合使用。
- 提供常用 CV 数据集下载和加载接口:
torchvision.transforms
:- 图像预处理和增强的利器! 提供了大量可组合的图像变换函数:
- 几何变换:
Resize
,CenterCrop
,RandomCrop
,RandomResizedCrop
,FiveCrop
,TenCrop
,Pad
,RandomHorizontalFlip
,RandomVerticalFlip
,RandomRotation
. - 颜色/亮度/对比度变换:
ColorJitter
,RandomGrayscale
,RandomAdjustSharpness
,RandomAutocontrast
,RandomInvert
,GaussianBlur
. - 转换:
ToTensor
(将 PIL Image 或 ndarray 转成(C, H, W)
范围的[0.0, 1.0]
的 FloatTensor),ToPILImage
,Normalize
(用均值和标准差标准化:output = (input - mean) / std
),ConvertImageDtype
(转换数据类型)。 - 组合:
Compose([transforms...])
将多个变换组合成一个。
- 几何变换:
- 用法示例:
transform = transforms.Compose([transforms.RandomResizedCrop(224),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.
- 图像预处理和增强的利器! 提供了大量可组合的图像变换函数: