题目重点:推导inverted dropout前后向与方差,解释保持期望而非保证非线性输出分布相同。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练元素级mask~Bernoulli(1−p),p为丢弃概率0≤p<1,inverted输出m·x/(1−p)。
- 推理关闭随机丢弃,不在eval额外再乘1−p;其他dropout变体需另定义。
解题路线
- 训练用随机mask打断部分通路并使表示不依赖固定共适应组合;不是每次删除网络参数或永久剪枝,梯度仍在保留路径传播。
- 固定x,E[mx/(1−p)]=x,保持每个激活的一阶期望。方差为x²p/(1−p),p>0时不是原来确定值的分布,所以不能说“分布完全相同”。
- 反向对x乘同一保存mask和scale,不能重新抽mask;否则forward和backward不是同一函数梯度。参数p=0或eval时恒等,p=1分母零,本合同拒绝。
- inverted约定在训练放大保留项,推理全保留并不再缩放。另一传统约定训练不放大、推理缩放权重/激活,必须配套,混搭会错误改变尺度。
- 非线性后E[f(random x)]通常不等于f(E[random x]),因此单个推理网络只是某种近似,并非严格平均所有子网络。dropout也不保证降低所有任务验证误差,需要实验。
- 与normalization次序和数据分布互相影响,不能只切model eval而漏掉自定义dropout开关。MC dropout推理保随机用于不确定性是另外的设计,不是基础推理默认。
- 对照枚举小向量所有mask及其精确概率验证期望,固定mask验证梯度;随机采样均值只能给估计误差,不能证明分布相同。
手动走一遍
x=2,p=0.5,训练输出0或4,各半,期望2但方差4;eval输出恒2,分布明显不同。保持mask=1时上游梯度3变6,丢弃时0。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
import random
def dropout_forward(values,p=0.5,training=True,draw=None):
"""Elementwise inverted dropout; returns output and backward context."""
if not 0 <= p < 1:
raise ValueError("p must be in [0,1)")
if not training or p==0:
return list(values),([True]*len(values),1.0)
draw=draw or random.random
mask=[draw() >= p for _ in values]
scale=1/(1-p)
return [value*scale if keep else 0.0 for value,keep in zip(values,mask)],(mask,scale)
def dropout_backward(upstream,context):
mask,scale=context
if len(upstream)!=len(mask):raise ValueError("shape mismatch")
return [grad*scale if keep else 0.0 for grad,keep in zip(upstream,mask)]
复杂度
n元素O(n)前向/反向,保存mask和输出O(n),随机数生成与GPU带宽另计;推理本参考返回副本仍O(n),不是零成本。
易错点与追问
容易失分的边界
- 期望相等说成分布相同。
- 反向重新抽mask。
- eval还乘1−p造成双缩放。
- p=1直接除零。
继续深挖
- attention dropout与activation dropout有何区别?
- MC dropout怎样定义推理?
- dropout与BN次序有什么影响?
技术参考
- Dropout paper:技术语义参考,具体题目按本文约定。
