Возникает ли дрейф модели при обучении с дроп-аутом и инференсе без него
Что проверяют
Понимаете ли вы механику дроп-аута настолько, чтобы увидеть реальное расхождение между обучением и инференсом. Слово «дрейф» тут обманчиво: речь не о смене распределения данных в проде, а о том, одинаково ли ведёт себя сеть в режимах train и eval. Следом часто спрашивают про связку дроп-аута с BatchNorm и про MC Dropout.
Как отвечать
Сначала разведите понятия. Дрейф данных и концепта возникает из-за изменений в мире, дроп-аут его не вызывает и от него не лечит. Дальше по механике:
- среднее: на обучении нейрон выключается с вероятностью
p, и без поправки на инференсе сумма входов следующего слоя оказалась бы больше. Фреймворки применяют inverted dropout: выжившие активации на обучении умножаются на1/(1-p), матожидание совпадает, и на инференсе ничего масштабировать не нужно. Так работаютnn.Dropoutв PyTorch иkeras.layers.Dropout; - дисперсия: среднее выровнено, а дисперсия нет. Если после дроп-аута стоит BatchNorm, его статистики, накопленные на обучении, не совпадают с тем, что приходит на инференсе. Это известный эффект variance shift, поэтому дроп-аут ставят после последнего BN или берут умеренное
p; - режим модели: в PyTorch дроп-аут выключается только вызовом
model.eval(). Без него предсказания случайны от запуска к запуску, и со стороны это похоже на «дрейф»; - MC Dropout: дроп-аут намеренно оставляют на инференсе, делают несколько прогонов и по разбросу оценивают неопределённость.
Итог: систематического сдвига по среднему нет благодаря масштабированию, остаточное расхождение сидит в дисперсии и в ошибках переключения режимов.
Где спотыкаются
Смешивают дрейф данных с различием режимов и уходят в рассказ про мониторинг и переобучение, так и не ответив на вопрос.
Не знают про масштабирование и утверждают, что на инференсе веса надо домножать на 1-p. Так делал исходный вариант метода, в PyTorch и Keras поправка уже заложена в обучение.
Забывают model.eval() в коде валидации: дроп-аут остаётся включённым, метрики скачут, а причину ищут в данных. torch.no_grad() отвечает только за градиенты и режим слоёв не переключает.