在Pytorch中使用Dropout:nn.Dropout与F.dropout有什么区别?
0 577
0

通过使用pyTorch,有两种方法可以 dropout torch.nn.Dropout和torch.nn.functional.Dropout。 我很难看到它们之间的区别: 1.什么时候使用哪一种? 2.有什么不同吗?

收藏
2021-02-23 10:49 更新 anna •  5042
共 1 个回答
高赞 时间
0

主要的区别在于,nn.Dropout torch 模块本身有一些便利: 一个简短的例子来说明一些差异:

def forward(self, inputs):
        return nn.functional.dropout(inputs, p=self.p, training=True)class Model2(nn.Module):
    # Model 2 using dropout module
    def __init__(self, p=0.0):
        super().__init__()
        self.drop_layer = nn.Dropout(p=p)
    def forward(self, inputs):
        return self.drop_layer(inputs)
model1 = Model1(p=0.5) # functional dropout 
model2 = Model2(p=0.5) # dropout module# creating inputs
inputs = torch.rand(10)# forwarding inputs in train mode
print('Normal (train) model:')
print('Model 1', model1(inputs))
print('Model 2', model2(inputs))
print()# switching to eval mode
model1.eval()
model2.eval()# forwarding inputs in evaluation mode
print('Evaluation mode:')
print('Model 1', model1(inputs))
print('Model 2', model2(inputs))# show model summary
print('Print summary:')
print(model1)
print(model2)

输出:

Normal (train) model:
Model 1 tensor([ 1.5040,  0.0000,  0.0000,  0.8563,  0.0000,  0.0000,  1.5951,
         0.0000,  0.0000,  0.0946])
Model 2 tensor([ 0.0000,  0.3713,  1.9303,  0.0000,  0.0000,  0.3574,  0.0000,
         1.1273,  1.5818,  0.0946])
Evaluation mode:
Model 1 tensor([ 0.0000,  0.3713,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
         0.0000,  0.0000,  0.0000])
Model 2 tensor([ 0.7520,  0.1857,  0.9651,  0.4281,  0.7883,  0.1787,  0.7975,
         0.5636,  0.7909,  0.0473])
Print summary:
Model1()
Model2(
  (drop_layer): Dropout(p=0.5)
)

那么应该用哪种呢?

两者在申请dropout方面完全等同,尽管在使用上的差异没有那么大,但有一些理由可以支持nn.Dropout。

Dropout 只在训练期间应用,所以当预测或评估模型时,你希望dropout被关闭。

dropout 模块nn.Dropout方便地处理这一点,并在模型进入评估模式时立即关闭 dropou,而 functional dropout 则不关心评估/预测模式。

即使你可以将functional dropout设置为 training=False,但它仍然不是像 nn.Dropout这样方便的解决方案。

此外,drop率存储在模块中,因此不必将其保存在额外的变量中。在更大的网络中,你可能希望创建不同的 drop率层-这里nn.Dropout可能会增加可读性,多次使用这些层时会更方便。

最后,分配给模型的所有模块都在模型中注册。 因此,你的模型类别可以跟踪它们,这就是为什么可以通过调用eval()来关闭dropout模块。当使用 functional dropou时,你的模型无法识别它,因此它并不适用。

Via:https://stackoverflow.com/a/53452827/14964791

收藏
2021-02-23 11:21 更新 karry •  4540