将Dropout整合到神经网络中涉及使用常用深度学习库。PyTorch和TensorFlow等框架提供了方便的模块或层,可以处理实现细节,包括推理时必要的缩放。在PyTorch中添加Dropout层在PyTorch中,你可以使用torch.nn.Dropout模块添加Dropout。在模型定义中,通常将其插入层之间,通常在全连接层的激活函数之后。提供给nn.Dropout的主要参数是p,它指定了训练期间元素(神经元输出)被归零的概率。请记住,这就是我们之前讨论过的'dropout率',一个你可能需要调整的超参数。这是一个PyTorch中整合了Dropout的简单顺序模型示例:import torch import torch.nn as nn # 定义模型参数 input_size = 784 # 示例:扁平化的MNIST图像 hidden_size1 = 256 hidden_size2 = 128 output_size = 10 # 示例:10个数字类别 dropout_prob = 0.5 # dropout概率 # 定义带有Dropout的模型 model = nn.Sequential( nn.Linear(input_size, hidden_size1), nn.ReLU(), nn.Dropout(p=dropout_prob), # 第一个隐藏层激活后进行Dropout nn.Linear(hidden_size1, hidden_size2), nn.ReLU(), nn.Dropout(p=dropout_prob), # 第二个隐藏层激活后进行Dropout nn.Linear(hidden_size2, output_size) # 注意:通常不在输出层之前直接应用Dropout ) print(model)在这段代码中,nn.Dropout(p=0.5)层被添加在隐藏层的ReLU激活函数之后。这意味着在训练期间,来自前一个ReLU的每个神经元输出对于该特定前向传播有50%的概率被设为零。剩余的活跃神经元的输出会按$1/(1-p)$的比例放大以进行补偿(这是由层自动处理的'反向Dropout'技术)。Dropout层的位置最常见的做法是将Dropout层放置在隐藏层的激活函数之后,如上例所示。在激活之前应用它也能起作用但不太常见。它通常不直接应用于输入层,也通常不直接应用于输出层之前,特别是当输出层代表概率(例如使用Softmax时)或有特定的缩放要求时。对于卷积神经网络(CNNs),Dropout可以应用于卷积层之后(通常在池化层之后),或应用于通常跟随卷积块的全连接层中。存在专门的版本,例如Dropout2d,它将整个特征图而不是单个元素归零,有时对卷积层更有效。我们在上一节中简要提到了这一点。对于循环神经网络(RNNs),在时间步之间天真地应用标准Dropout会阻碍学习;通常更倾向于使用变分Dropout等特定技术,但这些超出了本次介绍的范围。训练模式与评估模式:一个重要区别使用内置Dropout层的一个重要方面是它们自动处理训练与评估(推理/测试)模式。在训练期间 (model.train()): Dropout层会以概率$p$随机将神经元输出归零,并按描述缩放其余部分。这会引入噪声并防止共同适应。在评估期间 (model.eval()): Dropout层变为非活动状态。它只是不加修改地传递所有输入。训练期间应用的缩放(反向Dropout)确保期望的输出量级在训练和评估之间保持一致,消除了在测试时进行单独缩放的需要。在训练循环开始前使用model.train(),并在执行验证或测试前使用model.eval(),明确将你的模型设置为正确的模式非常重要。在推理期间未能设置model.eval()意味着你仍在随机丢弃单元,导致有噪声和次优的预测。让我们可视化在训练期间,激活后应用了Dropout的层内基本流程:digraph G { rankdir=LR; node [shape=box, style=rounded, fontname="sans-serif", margin=0.2]; edge [fontname="sans-serif"]; Input [label="层输入 (z)"]; Linear [label="线性变换\n(Wx + b)"]; Activation [label="激活函数\n(例如,ReLU)"]; Dropout [label="Dropout (p)", style="rounded,filled", fillcolor="#ffc9c9"]; Output [label="层输出 (a')"]; Input -> Linear; Linear -> Activation; Activation -> Dropout [label=" 仅在训练期间\n (随机归零 + 缩放)"]; Activation -> Output [label=" 在评估期间\n (恒等直通)", style=dashed, color="#adb5bd", fontcolor="#adb5bd"]; Dropout -> Output; { rank=same; Dropout; Output } # Align Dropout and Output vertically somewhat subgraph cluster_layer { label = "隐藏层处理"; style=filled; color="#e9ecef"; Linear; Activation; Dropout; } }一个层在激活后整合Dropout的流程。在训练期间,Dropout模块处于活动状态。在评估期间 (model.eval()),它作为恒等函数作用。这是一个PyTorch中的快速演示:# 创建一个dropout层 dropout_layer = nn.Dropout(p=0.5) # 创建一些虚拟输入数据 dummy_input = torch.ones(1, 10) # 全1张量 # 将模型设置为训练模式 dropout_layer.train() output_train = dropout_layer(dummy_input) print("Output (Training Mode):", output_train) # 一些元素将为0,其他元素将按2倍缩放 # 将模型设置为评估模式 dropout_layer.eval() output_eval = dropout_layer(dummy_input) print("Output (Evaluation Mode):", output_eval) # 所有元素将为1(直通)这段代码演示了nn.Dropout层如何根据通过.train()或.eval()设置的模式表现不同。因此,使用标准库函数实现Dropout非常直接。主要的考量是选择dropout概率p,以及决定在你的网络架构中何处策略性地放置Dropout层。接下来的实践环节将为你提供一个机会,将这些层添加到网络中并观察它们的效果。