Skip to content

神经网络到功能块

PyTorch - 将神经网络构建为可组合的功能模块

Section titled “PyTorch - 将神经网络构建为可组合的功能模块”

训练任何深度学习模型,无论其复杂程度如何,都涉及一个结构化的工作流程。这个工作流程可以分解为几个关键的功能模块 functional blocks,每个模块都可以通过 PyTorch 的生态系统 ecosystem 有效处理。理解这些模块对于构建、训练和部署神经网络至关重要。

典型的深度学习训练过程中的核心步骤是:

  • 构建高效的数据管道 data pipeline。
  • 定义神经网络架构 architecture。
  • 选择并实现一个损失函数 loss function 来评估模型。
  • 选择并应用一个优化算法 optimization algorithm 来更新模型权重 weights。

让我们在 PyTorch 的上下文中探索这些功能模块。

1. 使用 Dataset 和 DataLoader 构建数据管道

Section titled “1. 使用 Dataset 和 DataLoader 构建数据管道”

高效的深度学习始于精心准备的数据。PyTorch 为此提供了两个关键的工具:torch.utils.data.Dataset 和 torch.utils.data.DataLoader。

  • Dataset: 一个表示数据集的抽象类 abstract class。你通常会创建一个继承自 Dataset 的自定义类,并实现 __len__ 方法(返回数据集的大小)和 __getitem__ 方法(根据给定的索引检索单个数据样本)。这使得你可以灵活地从各种来源(文件、数据库等)加载数据,并实现自定义的预处理逻辑。
  • DataLoader: 封装了 Dataset 并提供一个可迭代对象 iterable。DataLoader 处理批处理 batching(将多个样本分组)、数据洗牌 shuffling(防止模型偏见和提高泛化能力),以及使用多进程 multiprocessing 进行并行数据加载(在 GPU 忙于计算时,通过在 CPU 上准备数据来加速训练)。

对于像 MNIST 或 CIFAR-10 这样的常用数据集,torchvision.datasets 提供了预构建的 Dataset 类。torchvision.transforms 提供了用于常见图像转换(例如,调整大小 resizing、归一化 normalization、数据增强 data augmentation)的工具。

PyTorch 中神经网络架构的定义是通过创建继承自 torch.nn.Module 的类来完成的。这是所有神经网络模块的基类 base class。

  • 层 Layers: nn.Module 作为各种层的容器 container,例如卷积层 convolutional layers (nn.Conv2d, nn.Conv1d)、循环层 recurrent layers (nn.LSTM, nn.GRU)、线性(全连接)层 linear (fully connected) layers (nn.Linear)、激活函数 activation functions (nn.ReLU, nn.Sigmoid, nn.Tanh)、池化层 pooling layers (nn.MaxPool2d) 和归一化层 normalization layers (nn.BatchNorm2d)。
  • __init__ 方法: 在自定义模块的构造函数 constructor 中,你定义并初始化网络将使用的所有层。
  • forward 方法: 此方法定义了每次调用时执行的计算。它接收输入数据,并将其通过定义的层传递以产生输出。PyTorch 的动态计算图 dynamic computation graph (autograd) 会自动跟踪 forward pass 中的操作,以便在反向传播 backpropagation 期间计算梯度 gradients。
  • 嵌套模块 Nested Modules: nn.Module 可以包含其他 nn.Module,允许你分层构建复杂的架构。

nn.Sequential 是一个特殊的 nn.Module,可用于快速串联一系列层。

3. 使用 torch.nn 中的损失函数进行评估

Section titled “3. 使用 torch.nn 中的损失函数进行评估”

损失函数(或称为衡量标准 criterion)用于量化模型预测与真实目标值匹配的程度。训练的目标是最小化这个损失。

  • 目的: 它提供了一种错误度量,优化算法将尝试减少它。
  • 常用损失函数: PyTorch 在 torch.nn 中提供了各种内置损失函数:
  • 计算: 损失通常通过比较模型的输出(预测 predictions)与真实标签 ground truth labels 来计算。

优化算法调整模型的参数(权重 weights 和偏差 biases)以最小化损失函数。这是学习过程的核心。

  • 梯度计算: 计算损失后,调用 loss.backward()。这会触发 PyTorch 的 Autograd 引擎,计算损失相对于所有 requires_grad=True 并对此有贡献的模型参数的梯度。这些梯度累积在其 .grad 属性中。此机制是通过反向传播训练神经网络的基础。
  • 优化器 Optimizers: torch.optim 包提供了各种优化算法的实现。常见的选择包括:
  • 参数更新: 计算完梯度后,调用 optimizer.step(),根据选择的算法和计算出的梯度来更新模型参数。
  • 梯度归零: 关键在于每次调用 loss.backward() 之前都要调用 optimizer.zero_grad()。这是因为 PyTorch 默认会累积梯度;不将它们归零会导致后续迭代中的梯度计算不正确。

训练深度学习模型是一个迭代过程 iterative process。你重复地将批量数据馈送给模型,计算损失,计算梯度,并更新权重。这个循环会进行多个 epoch(通过整个数据集的次数),直到模型在验证集 validation set 上的性能收敛或达到期望的标准。

PyTorch 无缝支持 GPU 加速以加快训练速度。你可以使用 .to(device) 将模型和张量 tensors 移动到支持 CUDA 的 GPU 上,其中 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')。这显著加速了深度学习中常见的矩阵运算 matrix operations。