Функция F.dropout2d
Функция F.dropout2d применяет специальный вид dropout для данных свёрточных слоёв. В отличие от обычного dropout, который обнуляет отдельные элементы, dropout2d обнуляет целые карты признаков (каналы). Это помогает сети не полагаться на конкретные каналы и улучшает обобщение.
Первым параметром передаётся четырёхмерный тензор формы (batch, channels, height, width). Вторым параметром задаётся вероятность p обнуления каждого канала. Во время обучения каналы масштабируются на коэффициент 1/(1-p) для сохранения математического ожидания.
Синтаксис
torch.nn.functional.dropout2d(input, p=0.5, training=True, inplace=False)
Пример
Давайте создадим простой четырёхмерный тензор и применим к нему dropout2d с вероятностью обнуления 0.5:
import torch
import torch.nn.functional as F
torch.manual_seed(0)
t = torch.ones(1, 3, 2, 2)
res = F.dropout2d(t, p=0.5, training=True)
print(res)
Результат выполнения кода:
tensor([
[
[[2., 2.],
[2., 2.]],
[[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.]]
]
])
Как видно из результата, первый канал остался неизменным и был масштабирован на коэффициент 2, а второй и третий каналы были полностью обнулены.
Пример
Рассмотрим работу функции в режиме оценки training=False, когда dropout не применяется:
import torch
import torch.nn.functional as F
torch.manual_seed(0)
t = torch.ones(1, 3, 2, 2)
res = F.dropout2d(t, p=0.5, training=False)
print(res)
Результат выполнения кода:
tensor([
[
[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]]
]
])
Пример
Теперь посмотрим, как dropout2d работает с реальными данными, полученными после свёрточного слоя. Для этого создадим небольшой классификатор и применим dropout2d к его промежуточным представлениям:
import torch
import torch.nn as nn
import torch.nn.functional as F
torch.manual_seed(0)
class ConvNet(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 3, kernel_size=3, padding=1)
def forward(self, x):
x = self.conv1(x)
x = F.dropout2d(x, p=0.3, training=self.training)
return x
model = ConvNet()
model.train()
t = torch.randn(2, 1, 4, 4)
res = model(t)
print(res.shape)
print(res[0, 0, :, :])
Результат выполнения кода:
torch.Size([2, 3, 4, 4])
tensor([
[ 0.0000, 0.0000, -0.0000, -0.0000],
[-0.0000, 0.0000, -0.0000, -0.0000],
[ 0.0000, -0.0000, -0.0000, -0.0000],
[-0.0000, -0.0000, 0.0000, 0.0000]
])
В этом примере мы применили dropout2d к выходу свёрточного слоя. Как видно из вывода первого канала, некоторые элементы были обнулены, но главное, что обнуление происходит целыми каналами, что делает регуляризацию более эффективной для свёрточных сетей.
Смотрите также
-
функцию
dropout,
которая применяет стандартный dropout к элементам тензора -
функцию
alpha_dropout,
которая применяет dropout с сохранением среднего и дисперсии -
функцию
batch_norm,
которая нормализует данные в батче и также применяется в свёрточных сетях -
функцию
conv2d,
которая выполняет двумерную свёртку и часто используется вместе сdropout2d