在PyTorch中,torch.nn
和torch.nn.Functional
中有一些功能类似的函数,但是它们之间存在一些不同,其中的nn.Dropout
和Functional.Dropout
的是线上就有一些不同。
例子
import torch
import torch.nn as nn
import torch.nn.functional as F
class Model1(nn.Module):
# Model1使用的是functioal.dropout
def __init__(self, p=0.0):
super().__init__()
self.p = p
def forward(self, inputs):
return F.dropout(inputs, p=self.p, training=True)
class Model2(nn.Module):
# Model2使用的是nn.Dropout
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) # torch.nn.functional.dropout
model2 = 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函数关掉dropout
print('----------------查看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的,这里就不展开了。