作者:elfin
Top --- Bottom
DropPath是将深度学习模型中的多分支结构随机”删除“
https://github.com/yueatsprograms/Stochastic_Depth
def drop_path(x, drop_prob: float = 0., training: bool = False): if drop_prob == 0. or not training: return x keep_prob = 1 - drop_prob shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device) random_tensor.floor_() # binarize output = x.div(keep_prob) * random_tensor return output class DropPath(nn.Module): """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). """ def __init__(self, drop_prob=None): super(DropPath, self).__init__() self.drop_prob = drop_prob def forward(self, x): return drop_path(x, self.drop_prob, self.training)
Top --- Bottom
假设在前向传播中有如下的代码:
x = x + self.drop_path(self.mlp(self.norm2(x)))
那么在drop_path分支中,每个batch有drop_prob的概率样本在self.mlp(self.norm2(x))不会”执行“,会以0直接传递。
对应到上面的代码,先对传入的x进行了x.div(keep_prob)的放缩,这是为什么?
在Dropout中我们比较好理解,对权值放缩是为了获得输出的一致性,即期望不变,但是这里实际上是对某个样本进行随机Dropout某一部分结构。这一样吗?
首先我们看常规的Dropout解释:
参考资料:https://www.imooc.com/article/30129
假设一个神经元的输出激活值为a,在不使用dropout的情况下,其输出期望值为a,如果使用了dropout,神经元就可能有保留和关闭两种状态,把它看作一个离散型随机变量,它就符合概率论中的0-1分布,其输出激活值的期望变为 p*a+(1-p)*0=pa,此时若要保持期望和不使用dropout时一致,就要除以p。 原文链接:https://blog.csdn.net/qbyqby7628/article/details/103449196
应该注意到在batch中,计算期望,我们的公式仍然满足上面的关系,也即要除以keep_prob。
完!