Перейти к содержимому
ПереводыИсследователи и авторы

Understanding Deep Learning: путеводитель по книге

Путеводитель по учебнику Саймона Принса «Understanding Deep Learning» (MIT Press, 2023): карта всех 21 главы с уроками курса, конспекты ключевых глав — кусочно-линейные сети, инициализация, остаточные сети, трансформеры, диффузия, RL, «почему глубокое обучение работает» — и 68 ноутбуков к ним.

«Understanding Deep Learning» (UDL) — учебник Саймона Принса, вышедший в MIT Press в 2023 году; полный PDF бесплатно лежит на сайте книги. В предисловии автор объясняет название: это книга об идеях, на которых держится глубокое обучение, а не о коде. И отчасти шутка: по-настоящему глубокое обучение пока не понимает никто. Себя Принс видит «духовным наследником» классического «Deep Learning» Гудфеллоу и др. (2016), который не покрывает новые темы.

Сильные стороны книги:

  • схемы — около 300 пронумерованных рисунков, в основном авторских; Принс старался объяснять известные идеи по-новому, а не пересказывать статьи;
  • единая нотация (её стоит посмотреть в приложении A до чтения);
  • после каждой главы — заметки с историей и литературой, задачи (ответы на часть — в «Answer Booklet» для студентов) и ноутбуки Python, на которые есть ссылки на полях.

Для кого: первые главы (2–13) требуют начальной линейной алгебры, анализа и вероятностей — уровня нашей ступени 1. Главы о порождающих моделях и RL (14–19) требуют больше вероятностей и анализа. Наш ученик может читать UDL параллельно ступеням 3–4 как «вторую точку зрения» на темы уроков, а главы 15–19 — к ступеням 6 и 9.

  1. Ступень 3. Главы 3–4 (поверхностные и глубокие сети) — вместе с уроком 3.1.1; главы 5–7 (потери, оптимизация, backprop, инициализация) — вместе с 3.1.2, модулем 3.2 и уроком 3.4.1; главы 8–9 (обобщение, регуляризация) — как повторение ступени 2; главы 10–11 (CNN, остаточные сети) — к урокам 3.5 и 3.4.2.
  2. Ступень 4. Глава 12 (трансформеры) — к модулям 4.4 и 4.5.
  3. Ступень 6. Глава 19 (RL) — к модулю 6.0, вместе со Spinning Up и Саттоном–Барто.
  4. Ступень 9. Главы 14–18 (порождающие модели) — к модулю 9.1, глава 21 (этика) — к уроку 9.3.5.
  5. В любой момент после ступени 3 — глава 20 «Почему глубокое обучение работает?»: лучшая обзорная глава книги.

Решайте задачи в конце глав хотя бы выборочно и обязательно запускайте ноутбуки: они короткие, работают на CPU и написаны в стиле «допишите пропущенный кусок кода».

ГлаваО чёмНоутбукиУрок курсаВажность для нас
1. Введениеобучение с учителем, без учителя, с подкреплением; этика; как читать книгу1.1 — повторение математики2.1.1★
2. Обучение с учителеммодель, потери, обучение на примере линейной регрессии2.12.2.1★
3. Поверхностные сетиодин скрытый слой, ReLU, кусочно-линейные области, теорема об универсальной аппроксимации3.1–3.43.1.1★★★
4. Глубокие сетикомпозиция сетей как «складывание» пространства, матричная запись, глубина против ширины4.1–4.33.1.1★★★
5. Функции потерьмаксимум правдоподобия как рецепт построения потерь; регрессия, бинарная и многоклассовая классификация; кросс-энтропия5.1–5.31.3.2★★★
6. Обучение моделейградиентный спуск, SGD, momentum, Adam, гиперпараметры6.1–6.51.4.1, 1.4.2★★
7. Градиенты и инициализацияbackprop на игрушечной модели и в общем виде, инициализация He, пример кода на PyTorch7.1–7.33.1.2, 3.2.2, 3.4.1★★★
8. Измерение качестваисточники ошибки: шум, смещение, дисперсия; двойной спуск; выбор гиперпараметров8.1–8.42.1.2★★
9. Регуляризацияявная (L2) и неявная регуляризация, ранняя остановка, ансамбли, dropout, аугментация, байесовский подход9.1–9.52.1.2, 3.4.2★★
10. Свёрточные сетиинвариантность и эквивариантность, 1D и 2D свёртки, понижение и повышение разрешения, приложения10.1–10.53.5.1, 3.5.2★★
11. Остаточные сетиостаточные связи и блоки, взрыв дисперсии, batch norm, ResNet, U-Net11.1–11.33.4.1, 3.4.2★★★
12. Трансформерыскалярное самовнимание, многоголовость, слой трансформера, BERT, GPT-3, перевод, длинные последовательности, ViT12.1–12.44.4.2, 4.5.1, 4.5.4★★★
13. Графовые сетипредставление графов, графовые свёртки, классификация графов и вершин, графовое внимание13.1–13.4нет в курсе☆
14. Обучение без учителятаксономия порождающих моделей, что такое хорошая порождающая модель, метрики—9.1.3★
15. GANдискриминатор как сигнал, устойчивость (Вассерштейн), условная генерация, StyleGAN15.1–15.29.1.3★
16. Нормализующие потокиобратимые слои, якобианы, многомасштабные потоки16.1–16.39.1.4★
17. VAEмодели со скрытой переменной, ELBO, трюк репараметризации17.1–17.39.1.3★★
18. Диффузионные моделипрямой и обратный процессы, обучение через ELBO, предсказание шума, ускорение и условная генерация18.1–18.49.1.2★★★
19. Обучение с подкреплениемMDP, отдача, табличные методы, Q-learning, градиент политики, actor-critic, офлайн-RL19.1–19.56.0.1–6.0.3★★
20. Почему глубокое обучение работает?почему сети легко обучаются и хорошо обобщают, ландшафт потерь, нужны ли столько параметров и глубина20.1–20.42.1.2, 5.1.1★★★
21. Этикавыравнивание ценностей, злоупотребления, ответственность исследователя21.1–21.29.3.5★★
Приложения A–Cнотация, математика, вероятности—ступень 1★

Звёзды — наша оценка важности для курса: ★★★ — читать обязательно, ☆ — можно пропустить.

Ниже — пересказ своими словами. Нумерация глав и разделов — как в книге, чтобы легко было найти место в PDF.

Главы 3–4. Нейросеть как кусочно-линейная функция

Заголовок раздела «Главы 3–4. Нейросеть как кусочно-линейная функция»

Главная «фирменная» идея книги. Поверхностная сеть с ReLU (ReLUReLU (выпрямитель)EN rectified linear unit (ReLU)ReLU(z) = max(0, z). Дешёвая, не насыщается при z > 0; минус — «мёртвые» нейроны, у которых z < 0 на всех примерах.) делает три вещи: считает несколько линейных функций входа, пропускает каждую через ReLU и складывает результаты с весами. Каждый скрытый нейрон добавляет к графику один «излом» — точку, где ReLU переходит из нуля в прямую. Итог — непрерывная кусочно-линейная функция: вход разбит на линейные области, на каждой выход — линейная функция. С достаточным числом нейронов такая сеть приблизит любую непрерывную функцию (теорема об универсальной аппроксимациитеорема об универсальной аппроксимацииEN universal approximation theoremСеть с одним скрытым слоем и неполиномиальной активацией приближает любую непрерывную функцию на ограниченной области. Ничего не говорит о числе нейронов, обучении и обобщении.).

Глава 4 объясняет, зачем глубина. Если подать выход одной поверхностной сети на вход другой, первая сеть как бы складывает пространство входов (несколько точек входа дают одно значение), а вторая применяет свою кусочно-линейную функцию — и её эффект повторяется на каждом сгибе. Поэтому у глубокой сети гораздо больше линейных областей на один параметр. Вывод главы (пять пунктов): обе сети универсальны; у глубоких больше областей на параметр; некоторые функции глубокая сеть приближает гораздо экономнее; большие структурированные входы (картинки) удобнее обрабатывать по стадиям; на практике лучшие результаты дают глубокие сети. Ноутбук 3.3 считает число областей, 4.1 показывает «складывание».

Первая половина — обратное распространение: сначала на игрушечной модели вручную (ноутбук 7.1), затем в матричной форме для глубокой сети (7.2). Наш курс проходит то же в модуле 3.2.

Вторая половина — инициализация. Если веса слоя взяты с дисперсией σ2\sigma^2, а смещения — нули, то от слоя к слою дисперсия предактиваций умножается примерно на 12Dσ2\tfrac12 D \sigma^2: множитель DD даёт сумма по DD входам, а 12\tfrac12 — ReLU, который обнуляет половину значений. Чтобы дисперсия не таяла и не взрывалась, нужно σ2=2/Dh\sigma^2 = 2/D_h — инициализация He (инициализация Kaimingинициализация Kaiming (He)EN Kaiming / He initializationVar(w) = 2 / n_in (He и соавт., MSRA, 2015). Двойка компенсирует то, что ReLU обнуляет половину входов. В PyTorch — nn.init.kaiming_normal_.). Тот же вывод для обратного прохода даёт 2/Dh′2/D_{h'} (размер следующего слоя); если размеры разные, берут компромисс — среднее. Без этого значения на глубоких слоях выходят за пределы чисел с плавающей точкой — это затухающие и взрывающиеся градиенты (затухание градиентовзатухание градиентовEN vanishing gradientsГрадиент первых слоёв — произведение множителей всех слоёв выше; если они меньше 1, он экспоненциально уменьшается с глубиной (0.9⁵⁰ ≈ 0.005), и нижние слои перестают учиться.). Глава заканчивается полным примером обучения на PyTorch (nn.Sequential, kaiming_normal_, SGD, StepLR) — его стоит набрать руками после урока 3.3.2.

Если просто наращивать глубину, ошибка на обучении и на тесте у классификаторов изображений растёт. Принс объясняет это так: градиент по параметрам ранних слоёв меняется быстро и непредсказуемо по сравнению с размером шага («раздробленные градиенты», ноутбук 11.1). Остаточная связь (остаточная связьостаточная связьEN residual connection) прибавляет результат блока к его входу: каждый слой влияет на выход и напрямую, и через последующие слои, поэтому градиенту не обязательно проходить через все слои, а поверхность потерь становится глаже. Взамен появляется другая беда: дисперсия активаций при прямом проходе растёт экспоненциально по числу блоков. Её лечат batch norm (пакетная нормализацияпакетная нормализация (BatchNorm)EN batch normalizationНормирует каждый признак по примерам батча, хранит скользящие статистики для инференса (Ioffe, Szegedy, 2015). Стандарт CNN; в LLM не используется.), которая нормирует по батчу и затем сдвигает и масштабирует обучаемыми параметрами; к тому же шум статистик батча работает как регуляризация. Дальше — ResNet, DenseNet, U-Net и «песочные часы» для оценки позы. В трансформерах (глава 12) та же схема, только нормализация — LayerNorm.

Принс выводит самовнимание из двух требований к модели текста: (1) общие параметры, чтобы работать с текстами разной длины; (2) связи между словами, зависящие от самих слов. Его запись отличается от нашей: входы — векторы- столбцы xnx_n, а выход для позиции nn — взвешенная сумма значений san=∑ma[xm,xn] vm\mathrm{sa}_n = \sum_m a[x_m, x_n]\, v_m, где веса неотрицательны и в сумме дают 1. Удобный образ из книги — самовнимание как маршрутизация: каждое выходное место по-своему смешивает одни и те же «значения». Отсюда видно, почему число весов внимания растёт как N2N^2 по длине, но не зависит от размера вектора DD, а вычисление значений — линейно по NN с общими весами.

Дальше в главе: веса через скалярные произведения запросов и ключей и softmax, масштабирование на Dq\sqrt{D_q}, позиционное кодирование, многоголовое внимание, слой трансформера (внимание + MLP, остаточные связи, LayerNorm); три вида моделей на примерах — кодировщик BERT, декодер GPT-3, кодировщик-декодер для перевода; длинные последовательности (разреженные матрицы внимания) и трансформеры для изображений (ViT). Ноутбуки 12.1–12.2 реализуют самовнимание и многоголовое внимание на NumPy, 12.3 — токенизацию, 12.4 — стратегии декодирования. Эта глава хорошо дополняет уроки 4.4.2 и 4.5.1: переведите формулы Принса в нашу «строчную» запись softmax(QK⊤/dk)V\mathrm{softmax}(QK^\top/\sqrt{d_k})V — отличное упражнение.

Диффузионная модель (диффузионная модельдиффузионная модельEN diffusion model) переводит пример данных через цепочку скрытых переменных, многократно подмешивая шум; после достаточного числа шагов от картинки остаётся белый шум. Поскольку каждый шаг маленький, обратный шаг «убрать немного шума» можно приблизить нормальным распределением, а его параметры — предсказать нейросетью. Потеря выводится из нижней границы правдоподобия (ELBO, как у VAE в главе 17) и в итоге сводится к простой квадратичной ошибке предсказания шума. Для изображений каждый шаг — это U-Net, поэтому генерация медленная; её ускоряют детерминированной формулировкой, где хватает меньшего числа шагов. Глава заканчивается условной генерацией — по классу, картинке и тексту, из чего и вырастают модели «текст → изображение». Ноутбуки 18.1–18.4 делают одномерную диффузию от начала до конца — идеальная практика к уроку 9.1.2.

Автор честно предупреждает, что RL заслуживает отдельной книги, и даёт вводный обзор: MDP, отдача и политика; табличные методы — динамическое программирование (модель среды известна), Монте-Карло (обновление после эпизодов) и TD-методы (обновление по ходу эпизода); глубокий Q-learning (уровень человека в играх Atari 2600); градиент политики, стохастические политики (важны при частичной наблюдаемости) и борьба с дисперсией; actor-critic; офлайн-RL и Decision Transformer. Глава хороша как короткая карта перед модулем 6.0; глубже — Spinning Up и конспект обзора Венг о градиенте политики. Ноутбуки 19.1–19.5 — MDP, динамическое программирование, Монте-Карло, TD-методы и контрольные переменные (тот самый baseline для уменьшения дисперсии).

Глава 20. Почему глубокое обучение работает?

Заголовок раздела «Глава 20. Почему глубокое обучение работает?»

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

  • Обучение. Два главных фактора, делающих оптимизацию посильной, — избыточная параметризация и выбор функции активации. Сети легко подгоняют даже случайные метки (ноутбук 20.1). По ходу обучения параметры движутся в подпространстве малой размерности к одному из семейства связанных глобальных минимумов; плохих локальных минимумов на практике не видно.
  • Обобщение. Тоже улучшается с ростом числа параметров (двойной спуск из главы 8); важны плоскость минимума и индуктивное смещение архитектуры.
  • Нужно ли столько параметров? Гипотеза «лотерейного билета» (ноутбук 20.3): внутри большой сети есть маленькая подсеть, которая обучается не хуже.
  • Нужна ли глубина? Похоже, хорошему обобщению нужны и много параметров, и много слоёв, но почему — неизвестно.

Итог главы: предсказательной теории, которая говорила бы заранее, когда обучение и обобщение удадутся, пока нет; глубокое обучение движется эмпирическими демонстрациями, а понимание отстаёт.

Проверьте вывод главы 7 сами — 50 слоёв ReLU шириной 100 и три варианта дисперсии весов:

import numpy as np
rng = np.random.default_rng(0)
D, layers = 100, 50 # ширина слоя и число слоёв
x = rng.normal(size=(D, 1000)) # 1000 случайных входов-столбцов (как у Принса: векторы-столбцы)
for name, var in [("σ² = 1/D", 1 / D), ("σ² = 2/D (He)", 2 / D), ("σ² = 4/D", 4 / D)]:
h = x
for k in range(layers):
omega = rng.normal(0, np.sqrt(var), size=(D, D)) # веса слоя, смещения нулевые
f = omega @ h # предактивации f = Ω h
h = np.maximum(f, 0) # ReLU
print(f"{name:14}: дисперсия предактиваций после {layers} слоёв = {f.var():.3g}")

Ожидаемый вывод:

σ² = 1/D : дисперсия предактиваций после 50 слоёв = 1.39e-15
σ² = 2/D (He) : дисперсия предактиваций после 50 слоёв = 0.618
σ² = 4/D : дисперсия предактиваций после 50 слоёв = 3.1e+14

При σ2=1/D\sigma^2 = 1/D каждый слой умножает дисперсию примерно на 12\tfrac12, и за 50 слоёв она падает до 10−1510^{-15}; при 4/D4/D — умножает на 2 и взрывается до 101410^{14}. Инициализация He держит её порядка единицы (отклонение от 1 — случайный разброс конечной ширины).

Минимальный набор ноутбуков, если времени мало: 3.3 (линейные области), 4.1 (композиция сетей), 5.3 (многоклассовая кросс-энтропия), 6.4–6.5 (momentum и Adam), 7.2–7.3 (backprop и инициализация), 8.3 (двойной спуск), 11.2 (остаточные сети), 12.1–12.2 (самовнимание), 18.2 (одномерная диффузия), 19.4 (TD-методы).

  • Errata — список опечаток; PDF на сайте регулярно обновляется.
  • Ответы на задачи для студентов.
  • Слайды и материалы для преподавателей — в папках Slides и CM20315 репозитория.
  • Блоги автора на RBC Borealis о нейронном касательном ядре, гауссовых процессах и ОДУ в машинном обучении — ссылки на сайте книги. Это продвинутое чтение после главы 20.

Что читать дальше. Сам Принс рекомендует: для кода — «Dive into Deep Learning» (у неё есть китайская версия d2l-zh, «Погружение в глубокое обучение»); для шире о машинном обучении — «Probabilistic Machine Learning» Мёрфи; для RL — Саттона и Барто; для математики — «Mathematics for Machine Learning».

ENRU
shallow / deep neural networkповерхностная (один скрытый слой) / глубокая сеть
piecewise linear region, jointкусочно-линейная область, излом
universal approximation theoremтеорема об универсальной аппроксимации
folding the input spaceскладывание пространства входов
maximum likelihood recipeрецепт потерь через максимум правдоподобия
He initializationинициализация He (Kaiming)
shattered gradientsраздробленные градиенты
residual connection, batch normalizationостаточная связь, нормализация по батчу
self-attention as routingсамовнимание как маршрутизация
forward (diffusion) / reverse (denoising) processпрямой (зашумление) / обратный (очистка от шума) процесс
evidence lower bound (ELBO)нижняя граница правдоподобия (ELBO)
overparameterizationизбыточная параметризация
double descent, lottery ticketдвойной спуск, «лотерейный билет»
inductive biasиндуктивное смещение