趋近智
Dropout 是常规深度学习中广泛使用的正则化方法,旨在通过在每次训练更新时随机将部分神经元激活值设为零来防止过拟合。它最初作为一种启发式方法提出,在实践中证明非常有效。然而,Dropout 与贝叶斯推断之间存在一种引人入胜的关联,这提供了对其机制更具原则性的理解,并促成从常规神经网络获取不确定性估计,且只需很少的改动。
这一见解,主要由 Gal 和 Ghahramani (2016) 提出,表明了在特定条件下,在每个权重层之前应用 Dropout 训练神经网络,在数学上等同于对一个特定的深度高斯过程模型执行近似贝叶斯推断。更普遍地说,不仅在训练期间,而且在测试时也执行 Dropout,可以被解释为深度神经网络的一种贝叶斯近似形式,通常被称为 MC Dropout (蒙特卡洛 Dropout)。
我们考虑一个具有 层、权重 和偏置 的神经网络。在常规网络中,我们通过最小化损失函数(例如交叉熵或均方误差)来寻求 和 的点估计,可能还会附带 L2 权重衰减等正则化。
Dropout 为层 中的每个单元 引入二元随机变量 。在训练期间,每个 都从概率为 的伯努利分布中采样,即 ,其中 是层 的 Dropout 概率。层 的输出 通过与 Dropout 掩码 进行元素乘法计算,然后再应用激活函数 :
(注意:Dropout 的具体放置位置,即在激活函数之前或之后,可以有所不同,这会影响具体的贝叶斯解释。对于这种解释,将其应用于权重乘法之前的输入很常见)。
核心思想是,训练带有 Dropout 和 L2 正则化的网络,可以被视为近似最小化近似分布 与真实贝叶斯后验 之间的 Kullback-Leibler (KL) 散度,这适用于对权重具有特定先验的网络。Dropout 隐式施加的先验通常与高斯或其它重尾分布的尺度混合有关,这促使稀疏性。
近似变分分布 由 Dropout 机制本身定义。具体来说,权重是共享的,但在每次前向传播时,会随机屏蔽掉一组不同的单元(以及与它们连接的权重)。在训练期间随机选择子网络的过程,起到了隐式变分推断的作用。
Dropout 的常规做法是在测试时禁用它,并将权重按 进行缩放,以考虑所有单元现在都已激活的情况。这会产生一个单点预测。
MC Dropout 修改了这一过程:
这种不确定性估计主要捕获认知不确定性——源自模型参数的不确定性。因为不同的 Dropout 掩码有效地从近似后验 中采样不同的模型,所以其输出的变化反映了对最佳权重配置的不确定性。如果模型输出表示分布的参数(例如,回归的均值和方差),它也可以隐式捕获一些偶然不确定性。
下面是 MC Dropout 预测在 PyTorch 或 TensorFlow 等框架中如何实现的示例。主要步骤是确保 Dropout 层在推断期间保持激活状态。
# MC Dropout 预测循环代码
def get_mc_predictions(model, X_input, num_samples):
""" 执行 T 次随机前向传播以获取 MC 预测。 """
# 确保模型处于评估模式,但 Dropout 处于激活状态
# 在 PyTorch 中,手动将 Dropout 层设置为训练模式:
# for module in model.modules():
# if module.__class__.__name__.startswith('Dropout'):
# module.train()
# 在 TensorFlow/Keras 中,将 training=True 传递给 Dropout 层/模型调用
all_outputs = []
# 在推断期间禁用梯度计算以提高效率
# PyTorch 上下文管理器的示例:
# with torch.no_grad():
for _ in range(num_samples):
# 假设模型前向传播需要为 Dropout 启用训练模式
# 在 Keras 中:output = model(X_input, training=True)
# 在 PyTorch 中:参阅上面关于设置 Dropout 模块为 train() 的注释
# 执行前向传播(具体调用取决于框架)
current_output = model(X_input) # 确保内部 Dropout 处于激活状态
all_outputs.append(current_output)
# 堆叠输出(根据需要调整维度,例如使用 torch.stack 或 tf.stack)
# 示例:stacked_outputs 的形状可能是 [num_samples, batch_size, output_dim]
stacked_outputs = stack_operation(all_outputs)
# 沿着样本维度(axis=0)计算均值和方差
prediction_mean = calculate_mean(stacked_outputs, axis=0)
prediction_variance = calculate_variance(stacked_outputs, axis=0)
return prediction_mean, prediction_variance
# --- 辅助函数(替换为实际框架函数) ---
import numpy as np
# 假设 stack_operation, calculate_mean, calculate_variance 是框架特定的
def stack_operation(outputs): return np.stack(outputs)
def calculate_mean(data, axis): return np.mean(data, axis=axis)
def calculate_variance(data, axis): return np.var(data, axis=axis)
# --- 使用示例 ---
# trained_model = load_my_model() # 加载您使用 Dropout 训练的模型
# X_new = load_new_data()
# num_mc_samples = 100
# mean_preds, uncertainty_variance = get_mc_predictions(trained_model, X_new, num_mc_samples)
# print("平均预测:", mean_preds)
# print("预测方差(不确定性):", uncertainty_variance)
呈现蒙特卡洛 Dropout 预测过程的 Python 代码。请注意,在推断时的多次前向传播中,确保 Dropout 层处于激活状态是重要步骤。具体机制取决于所使用的深度学习框架。
优点:
局限:
Dropout 与近似贝叶斯推断之间的联系,为一种常见的正则化方法提供了有力的理论依据。MC Dropout 通过在测试时使用随机前向传播来估计预测不确定性,从而扩展了这一点。虽然它是一种近似方法,但其简洁性和可扩展性使其成为将不确定性感知引入深度学习模型的一种极具吸引力且广泛使用的方法,而无需借助像 MCMC 或前面讨论的显式变分推断公式那样复杂的贝叶斯机制。它代表了传统深度学习与贝叶斯视角之间的一座实用桥梁。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造