Технические различия уже были показаны в другом ответе.Однако основное отличие состоит в том, что nn.Dropout
- это сам модуль горелки, который имеет некоторое удобство:
Краткий пример для иллюстрации некоторых отличий:
import torch
import torch.nn as nn
class Model1(nn.Module):
# Model 1 using functional dropout
def __init__(self, p=0.0):
super().__init__()
self.p = p
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)
)
Итак, что я должен использовать?
И то, и другое полностью эквивалентно с точки зрения применения отсева, и хотя различия в использовании не так велики, есть некоторые причины, чтобы поддержатьnn.Dropout
over nn.functional.dropout
:
Выпадение предназначено для применения только во время обучения, поэтому при прогнозировании или оценке модели вы хотите, чтобы отсев был отключен.
Модуль отсеваnn.Dropout
удобно обрабатывает это и отключает выпадение, как только ваша модель переходит в режим оценки, в то время как функциональный выпад не заботится о режиме оценки / прогнозирования.
Даже если вы можете установить функциональное отключение на training=False
, чтобы отключить его, это все же не такое удобное решение, как с nn.Dropout
.
.Частота выпадения хранится в модуле, поэтому вам не нужно сохранять ее в дополнительной переменной.В более крупных сетях вы можете захотеть создать разные выпадающие слои с разной скоростью выпадения - здесь nn.Dropout
может повысить удобочитаемость и также может принести некоторое удобство при многократном использовании слоев.
Наконец, все модули, которые назначеныВаша модель зарегистрирована в вашей модели.Таким образом, ваш модельный класс отслеживает их, поэтому вы можете просто отключить выпадающий модуль, вызвав eval()
.При использовании функционального исключения ваша модель не знает об этом, поэтому она не будет отображаться ни в одной сводке.