【问题标题】:Should dropout be deactivated when training a model with some freezed modules?在训练带有一些冻结模块的模型时是否应该停用 dropout?
【发布时间】:2020-11-18 23:52:40
【问题描述】:

我有一个由多个模块组合而成的深度神经网络,例如编码器、解码器等。在训练之前,我从预训练模型加载其部分参数,仅用于模块子集。例如,我可以加载一个预训练的编码器。然后我想冻结预训练模块的参数,以便它们不会与其余模块一起训练。在 Pytorch 中:

for param in submodel.parameters()
     param.requires_grad = False

现在,我应该在学习时继续对这些冻结的模块应用 dropout 还是应该停用它(参见下面的示例)?为什么?

def MyModel(nn.Module):
    ...
    def forward(x):
        if freeze_submodule:
            self.submodule.eval()  # disable dropout when submodule is frozen
        x = self._forward(x)
        if freeze_submodule:
            self.submodule.train()

【问题讨论】:

  • 我不太明白你的问题。为什么要冻结子模块?你到底想完成什么?
  • @VictorZuanazzi 冻结预训练子模块有助于避免它们的权重被训练非预训练子模块导致的梯度弄乱。参见,例如,Jean et al 2015Zoph et al., 2016

标签: deep-learning transfer-learning dropout


【解决方案1】:

冷冻模块

你可以通过设置requires_grad_(False)来冻结参数,这样更简洁:

submodel.requires_grad_(False)

这将冻结所有submodel 参数。

您也可以使用 with torch.no_grad 上下文管理器而不是 submodel forward 传递,但它确实不太常见。

eval

运行submodule.eval() 会将某些层置于评估模式(BatchNormDropout)。对于Dropout(实际上是倒置的dropout),您可以检查它是如何工作的in this answer

问:是否仍应将 dropout 应用于冻结的参数?

不,因为权重将无法补偿 dropout 的影响,这是它的目标之一(使其更健壮并在更多路径上传播信息流)。他们将无法做到这一点,因为他们无法训练。

另一方面,留下 dropout 会给架构增加更多的噪音和错误,并可能迫使网络的可训练部分对其进行补偿,我会去做实验。

冻结预训练子模块有助于避免它们的权重 被训练产生的梯度搞砸了 非预训练子模块

视情况而定,fastai 社区对预训练模块使用较小的学习率,仍然可以训练它们(参见 this blog post for example),这很直观(任务的分布与你的主干预训练的分布有所不同,因此有理由假设权重需要调整一些量(也可能很小)。

【讨论】:

  • 谢谢@Szymon,我也怀疑过。但是,在 Pytorch 论坛上搜索“冻结参数”时,我唯一地找到了建议使用 requires_grad=False 显式冻结参数的答案。例如,this postthis one。任何直觉为什么?
  • 我上面的问题更笼统:是否仍应将 dropout 应用于冻结参数?如果是这样,为什么?请问你有一些参考资料吗?
  • @Lollo 得到的答案有点混乱。此处已更正,不便之处敬请见谅。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 2020-06-13
  • 2021-02-12
相关资源
最近更新 更多