Почему дроп-аут отключают на инференсе
Что проверяют
Понимаете ли вы, что дроп-аут это шум, который добавляют намеренно и только на обучении, и знаете ли, как фреймворк компенсирует масштаб активаций. Заодно смотрят, писали ли вы цикл инференса руками: забытый режим оценки это классическая боевая ошибка.
Как отвечать
Объясните смысл. На обучении дроп-аут с вероятностью p обнуляет часть активаций, чтобы сеть не опиралась на отдельные нейроны и училась избыточному представлению. Это регуляризация, а не часть модели.
На инференсе задача другая: получить воспроизводимое предсказание. Если оставить дроп-аут включённым, один и тот же вход будет давать разные ответы, а качество просядет, потому что часть сигнала выбрасывается без всякой пользы.
Отдельно про масштаб. Современные библиотеки используют inverted dropout: делят оставшиеся активации на 1 - p прямо на обучении, поэтому ожидаемая сумма на входе следующего слоя совпадает с режимом без дроп-аута. На инференсе слой просто пропускает вход как есть, домножать ничего не надо.
Дальше про API: model.eval() в PyTorch переключает режим у модулей, training=False в Keras делает то же самое. Упомяните исключение: Monte Carlo Dropout намеренно оставляет дроп-аут включённым и усредняет несколько прогонов, чтобы оценить неопределённость предсказания.
Где спотыкаются
Говорят, что на инференсе выходы домножают на 1 - p. Это старая схема, до inverted dropout. Сейчас коэффициент применяется на обучении, и повторное умножение на инференсе испортило бы масштаб активаций.
Второе: путают model.eval() и torch.no_grad(). Первый переключает поведение слоёв, второй только отключает построение графа для градиентов. Нужны оба: без eval() дроп-аут продолжит работать в режиме обучения, а память всё равно уйдёт на градиенты.
Третье: забывают, что режим меняет не только дроп-аут. Батч-нормализация на инференсе берёт накопленные скользящие средние вместо статистик текущего батча, и без eval() предсказание начинает зависеть от того, с кем строка попала в один батч.