Как работает Dropout в нейронных сетях?

«Как работает Dropout в нейронных сетях?» — вопрос из категории Нейронные сети и Deep Learning, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Dropout — это мощная техника регуляризации, применяемая во время обучения нейронных сетей для предотвращения переобучения (overfitting). Ее ключевая идея — предотвратить коадаптацию (слишком сильную взаимную зависимость) нейронов.

Принцип работы:

  1. На этапе обучения: Для каждого обучающего примера в каждом слое, к которому применен Dropout, каждый нейрон (или узел) независимо и случайно "отключается" с заданной вероятностью p (например, 0.5). Это означает, что его выход приравнивается к нулю, и он не участвует в прямом и обратном проходе для данной итерации.
  2. На этапе инференса (тестирования/продакшена): Все нейроны остаются активными, но выход каждого нейрона слоя с Dropout умножается на коэффициент (1 - p). Это делается для того, чтобы ожидаемое значение выхода (математическое ожидание) слоя во время инференса совпадало с ожидаемым значением во время обучения.

Почему это работает? Dropout заставляет сеть учиться более устойчивым и распределенным признакам, так как нейрон не может полагаться на присутствие каких-то конкретных других нейронов. Это эмулирует обучение и усреднение предсказаний большого ансамбля ("комитета") различных архитектур подмоделей, что приводит к лучшей обобщающей способности.

Пример реализации в PyTorch:

import torch.nn as nn

model = nn.Sequential(
    nn.Linear(in_features=784, out_features=256),
    nn.ReLU(),
    nn.Dropout(p=0.3),  # 30% нейронов этого слоя будут отключены в каждой итерации обучения
    nn.Linear(256, 128),
    nn.ReLU(),
    nn.Dropout(p=0.2),  # 20% нейронов
    nn.Linear(128, 10)
)

# Важно: переключать режим!
model.train()  # Dropout активен
# ... обучение ...
model.eval()   # Dropout отключен, выходы масштабируются автоматически
# ... инференс ...

Ключевые моменты:

  • p — гиперпараметр. Типичные значения от 0.2 до 0.5.
  • Обычно не применяется к выходному слою.
  • В современных фреймворках масштабирование при инференсе (scale by (1-p)) выполняется автоматически при вызове model.eval().