Активации, инициализация и нормализация батчем

Урок 7 из 16 курса «Нейросети с нуля: по открытому коду Андрея Карпати»: неофициальный курс AI University по открытому коду (MIT). Урок входит в платный доступ; первые уроки курса бесплатно.

О чём урок

Этот урок переключает фокус с архитектуры на то, что происходит «под капотом» при обучении глубоких сетей: как ведут себя числа на старте обучения, почему глубокие сети с наивной инициализацией учатся плохо или вообще не учатся, и как нормализация батчем решает эту проблему. После урока вы сможете диагностировать нездоровую инициализацию по значению стартовой потери и по гистограммам активаций, правильно масштабировать веса линейных слоёв, реализовать BatchNorm1d с нуля и понимать, какую диагностику стоит снимать во время обучения, чтобы убедиться, что сеть действительно учится.

Неофициальный курс AI University по открытому коду (MIT). В уроке приводится код из karpathy/makemore © Andrej Karpathy, лицензия MIT; комментарии переведены на русский, объяснения написаны нашей командой. Курс не связан с автором кода и не одобрен им.

Материал полезен сам по себе, но вдвойне полезен как подготовка к следующим урокам: в WaveNet-подобной модели (урок 8) и в nanoGPT (уроки 9-13) эти же идеи появляются в виде LayerNorm, residual-соединений и аккуратной инициализации проекций.

Перед тем как написать хоть одну строку обучающего цикла, полезно задать себе простой вопрос: а какой должна быть потеря на первом шаге, ещё до всякого обучения? Если модель ничего не знает о данных, разумно ожидать, что она предсказывает все классы равновероятно. Для задачи с vocab_size классами равномерное распределение даёт функцию потерь:

L = -ln(1/vocab_size) = ln(vocab_size)

Для символьного словаря из 27 символов (26 букв и специальный токен, как в CharDataset из makemore) это ln(27) ≈ 3.296. Если при первом forward pass вы видите значение, скажем, 12 или 20, это не повод радоваться «большой» стартовой сложности задачи. Это сигнал, что логиты на выходе сети слишком велики по модулю, softmax уже сильно «уверен» в неправильных классах, и функция потерь штрафует эту уверенную неправоту гораздо сильнее, чем честную неопределённость.

Проверим это на игрушечном примере.

При таком разбросе первая потеря получается заметно выше ожидаемой (логиты имеют…

План урока

  1. Сколько должна «стоить» потеря в начале обучения
  2. Насыщение tanh и умирающие градиенты
  3. Инициализация Кайминга: как компенсировать рост дисперсии
  4. BatchNorm: нормализация статистики активаций прямо во время обучения
  5. Побочные эффекты BatchNorm и почему в трансформерах используют LayerNorm
  6. Диагностика обучения: отношение обновления к масштабу весов
  7. Ручной градиент cross-entropy как упражнение
  8. Попробуйте сами

Урок входит в полный доступ. Полный текст и видео открываются после оплаты. Первые уроки каждого курса бесплатны.

Полезные гиды