在PyTorch中,torch.nn和torch.nn.Functional中有一些功能类似的函数,但是它们之间存在一些不同,其中的nn.Dropout和Functional.Dropout的是线上就有一些不同。
例子
import torchimport torch.nn as nnimport torch.nn.functional as Fclass Model1(nn.Module):# Model1使用的是functioal.dropoutdef __init__(self, p=0.0):super().__init__()self.p = pdef forward(self, inputs):return F.dropout(inputs, p=self.p, training=True)class Model2(nn.Module):# Model2使用的是nn.Dropoutdef __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) # torch.nn.functional.dropoutmodel2 = Model2(p=0.5) # torch.nn.Dropout# 输入inputs = torch.rand(10)print('torch.nn.functional.dropout的输出{0}\n'.format(model1(inputs)))print('torch.nn.Dropout的输出{0}\n'.format(model2(inputs)))model1.eval()model2.eval()# 通过eval函数关掉dropoutprint('----------------查看eval函数的映像-------------\n')print('torch.nn.functional.dropout的输出{0}\n'.format(model1(inputs)))print('torch.nn.Dropout的输出{0}\n'.format(model2(inputs)))# 打印出模型print(model1)print(model2)
torch.nn.functional.dropout的输出tensor([0.0000, 0.2708, 0.0000, 0.7128, 0.0000, 1.7333, 0.0000, 0.3477, 0.0000, 0.0000])
torch.nn.Dropout的输出tensor([0.0000, 0.2708, 0.0000, 0.7128, 0.0000, 1.7333, 0.0000, 0.0000, 0.3211,
0.7905])————————查看eval函数的映像——————-
torch.nn.functional.dropout的输出tensor([0.0000, 0.0000, 1.6266, 0.0000, 0.0000, 0.0000, 0.0000, 0.3477, 0.3211,
0.7905])torch.nn.Dropout的输出tensor([0.8236, 0.1354, 0.8133, 0.3564, 0.9222, 0.8666, 0.9603, 0.1739, 0.1606,
0.3952])Model1()
Model2(
(drop_layer): Dropout(p=0.5, inplace=False)
)
结论
在训练过程中,这两个函数是没有什么区别的。但是,在测试的时候,我们通常需要将参数设置为dropout(p=0.0),我们常见的model.eval()能够停止掉nn.Dropout的使用。对于torch.nn.functional.dropout就需要手动设置了,所以,一般测试过程中,通常使用nn.Dropout而不是用nn.functional.dropout。
model.eval()还有另外一个作用,是关于Batch Normalization的,这里就不展开了。
