Математика глубокого обучения

Инициализация и residual

Откуда берутся Xavier и He, почему residual меняет умножение на сложение

Шаг 83 из 117 · ~30 мин

Одна рекурсия, из которой всё следует

Инициализацию обычно запоминают как таблицу формул. На самом деле есть одно утверждение, а формулы — это его решения относительно Var(w)\operatorname{Var}(w).

Var(y)=ninVar(w)Var(x)\operatorname{Var}(y) = \htmlData{k=fan}{n_{\text{in}}} \cdot \htmlData{k=varw}{\operatorname{Var}(w)} \cdot \htmlData{k=varx}{\operatorname{Var}(x)}

Это прямое следствие блока 3, урок 060: yj=iwjixiy_j = \sum_i w_{ji} x_i, слагаемые независимы и центрированы, дисперсии складываются, а дисперсия произведения независимых центрированных величин равна произведению дисперсий. Ключевая величина здесь — , число входов слоя: дисперсия растёт с ним линейно. Проверено численно при Var(w)=Var(x)=1\operatorname{Var}(w) = \operatorname{Var}(x) = 1:

ninn_{\text{in}}измеренная Var(y)\operatorname{Var}(y)предсказанная
161615.8415.841616
256256260.8260.8256256
102410241027102710241024

Введём коэффициент усиления слоя

g=ninVar(w)g = n_{\text{in}} \operatorname{Var}(w)

тогда Var(xL)=gL\operatorname{Var}(x_{L}) = g^{L} при единичной дисперсии на входе. Всё остальное в этом уроке — про то, что бывает при g1g \ne 1.

Xavier и He — это решения уравнения g=1g = 1

Требование одно: g=1g = 1. Отсюда сразу Var(w)=1/nin\operatorname{Var}(w) = 1/n_{\text{in}}, то есть σw=1/nin\sigma_w = 1/\sqrt{n_{\text{in}}}это и есть Xavier, и формулу не нужно запоминать, её можно вывести за строчку.

Дальше поправка на нелинейность. ReLU обнуляет половину симметричного распределения, поэтому

E[relu(x)2]=12E[x2]\mathbb{E}[\text{relu}(x)^2] = \tfrac12\mathbb{E}[x^2]

— второй момент делится на два. Проверено: при xN(0,1)x \sim \mathcal{N}(0,1) измеренное E[relu(x)2]=0.4997\mathbb{E}[\text{relu}(x)^2] = 0.4997 против теоретических 0.50.5. Значит с ReLU усиление равно g=12ninVar(w)g = \frac12 n_{\text{in}} \operatorname{Var}(w), и уравнение g=1g = 1 даёт

Var(w)=2nin,σw=2nin\operatorname{Var}(w) = \frac{2}{n_{\text{in}}}, \qquad \sigma_w = \sqrt{\frac{2}{n_{\text{in}}}}

это He. Вся разница между двумя схемами — та самая двойка от ReLU, и больше ничего.

Отдельно стоит заметить: ReLU делит на два второй момент, но не дисперсию. Среднее relu(x)\text{relu}(x) равно 1/2π=0.39891/\sqrt{2\pi} = 0.3989 (измерено 0.39870.3987), поэтому Var(relu(x))=1212π=0.3408\operatorname{Var}(\text{relu}(x)) = \frac12 - \frac{1}{2\pi} = 0.3408, а не 0.50.5. Формулы инициализации выведены для второго момента — то есть предполагают центрированность, которой после ReLU уже нет. Это одна из причин, по которой в сети с нормализацией точность формулы перестаёт быть критичной.

Что бывает при g1g \ne 1

Поставьте nin=256n_{\text{in}} = 256, включите ReLU и пройдитесь по схемам. Смотрите на два числа: усиление и итоговый масштаб.

слой ст. откл. активаций

глубина L 24
ширина n 256
σ веса
0.01
усиление g
0.013
итоговое ст. откл.
1.93e-23
Популярный «безопасный» выбор. При n = 256 он даёт g = 0.0128: каждый слой делит масштаб примерно на девять. Через двадцать четыре слоя от сигнала остаётся 2·10⁻²³ — и это не «медленное обучение», а отсутствие сигнала.

Сигнал исчез: к последнему слою от него не осталось ничего, и градиент назад не пройдёт.

Три наблюдения, которые стоит проверить в виджете руками:

  1. Ошибка в усилении накапливается геометрически. Отклонение gg на десять процентов выглядит безобидным, но 1.1100=1.41041.1^{100} = 1.4 \cdot 10^{4}, а 0.9100=2.71050.9^{100} = 2.7 \cdot 10^{-5}. Глубина превращает малую погрешность в катастрофу.
  2. Xavier с ReLU — не «чуть хуже», а сломано на глубине. g=0.5g = 0.5 означает деление масштаба на 2\sqrt{2} каждый слой: через сорок восемь слоёв остаётся 3.610153.6\cdot10^{-15}.
  3. Тот же множитель действует и назад. Обратный проход умножает на noutVar(w)n_{\text{out}} \operatorname{Var}(w), поэтому при g1g \ne 1 вместе с активациями исчезает или расходится и градиент. Отсюда и требование «g=1g = 1 в обе стороны», из-за которого в Xavier иногда берут 2nin+nout\frac{2}{n_{\text{in}} + n_{\text{out}}} — компромисс между двумя условиями, которые одновременно выполнимы только при nin=noutn_{\text{in}} = n_{\text{out}}.

Residual меняет умножение на сложение

Вот в чём главное. Без residual глубина входит в показатель:

Var(xL)=gL\operatorname{Var}(x_L) = g^L

С residual-связью и pre-norm ветвь читает нормированную копию потока, поэтому её вклад равен gg независимо от того, что в потоке уже накопилось:

Var(xL)=1+Lg\operatorname{Var}(x_L) = 1 + L g

Глубина переехала из показателя в множитель. Это и есть причина, по которой residual-сети обучаются на глубинах, где обычный стек не обучается вовсе, — не «градиент течёт лучше» в переносном смысле, а буквально другая асимптотика.

LLgLg^L при g=1.1g = 1.11+Lg1 + Lg при g=1g = 1
10102.62.61111
50501171175151
1001001.41041.4 \cdot 10^{4}101101

Обратите внимание, что при g=1.1g = 1.1 и L=10L = 10 обычный стек ведёт себя лучше. Разница появляется на глубине, и растёт она не постепенно, а экспоненциально.

Остаточный рост никуда не делся: стандартное отклонение потока растёт как 1+L\sqrt{1 + L}5.05.0 при L=24L = 24, 9.859.85 при L=96L = 96. Это уже не проблема выживания сигнала, а проблема масштаба: последний слой видит вход в десять раз крупнее, чем первый.

Множитель 1/2L1/\sqrt{2L}

Отсюда — приём, который выглядит произвольным, а на самом деле решает уравнение. Пусть в сети 2L2L residual-ветвей (внимание и MLP в каждом из LL блоков), и веса выходной проекции каждой ветви поделены на 2L\sqrt{2L}. Тогда вклад одной ветви равен g/(2L)g/(2L), и

Var(xвыход)=1+2L12L=2\operatorname{Var}(x_{\text{выход}}) = 1 + 2L \cdot \frac{1}{2L} = 2

при любой глубине. Проверьте: L=6L = 6, 2424, 9696 — везде ровно двойка. Именно так сделано в GPT-2 и почти во всём, что после него, и теперь понятно, почему в знаменателе стоит число ветвей, а не число слоёв и не что-то ещё.

В виджете это последняя схема. В обычном стеке она даёт затухание — множитель осмыслен только там, где вклады складываются.

Что стоит запомнить

  • Инициализация — не таблица формул, а уравнение g=1g = 1; Xavier и He суть два его решения, отличающиеся двойкой от ReLU.
  • В сети с нормализацией точность инициализации менее критична: нормировка возвращает масштаб к единице после каждого слоя. Но первый прямой проход происходит до первого обновления, и стартовать с 102510^{25} всё равно нельзя.
  • Residual важен не тем, что «добавляет путь», а тем, что переводит глубину из показателя степени в множитель. Всё остальное — следствия.

Источники

Проверки

0 из 2
  1. Усиление, глубина и residual

    Отметьте все верные утверждения об инициализации и residual-связях.

  2. Сигнал через глубокий стек

    Реализуйте propagate(fan_in, weight_sd, depth, relu) — верните [gain, plain_sd, residual_sd, safe_sd]. Дисперсия входа единичная.

    • gain — усиление одного слоя, g=ninσw2g = n_{\text{in}} \sigma_w^2, умноженное на 12\frac12, если relu истинно (ReLU делит второй момент на два);
    • plain_sd — стандартное отклонение активаций после depth слоёв обычного стека. Дисперсия умножается на gg каждый слой, то есть равна gLg^{L};
    • residual_sd — то же для residual-стека с pre-norm: каждая ветвь читает нормированную копию потока, поэтому её вклад равен gg независимо от накопленного, и дисперсия равна 1+Lg1 + Lg;
    • safe_sd — то σw\sigma_w, при котором gg было бы ровно единицей. Это уравнение решается в одну строчку, и его решения — Xavier и He.

    Проверить себя можно так: при weight_sd равном safe_sd первое и второе числа обязаны равняться единице при любой глубине.

    функция propagate

    Загрузка редактора…

    Ctrl/⌘ + Enter