Оценка по кривой

После этого урока ты на калькуляторе посчитаешь выход Batch Normalization для любого mini-batch, объяснишь, зачем слою \(\gamma\) и \(\beta\), и скажешь, что в нём меняется при переходе от обучения к inference.

Один и тот же экзамен сдают три потока. Первому достался лёгкий вариант, третьему — тяжёлый, и сравнивать сырые баллы нечестно. Преподаватель «оценивает по кривой»: внутри каждого потока вычитает средний балл и делит на разброс. Теперь ноль означает «как средний в своём потоке», какой бы вариант ни попался.

На пересдачу приходит один человек. Поток из одного студента. Средний балл такого потока равен его собственному баллу, разность равна нулю — что бы он ни написал. Как оценить по кривой его?

11 февраля 2015 года Sergey Ioffe и Christian Szegedy выложили статью, в которой эта процедура встроена внутрь нейросети: каждый нейрон на каждом шаге обучения пересчитывает свои значения относительно текущего mini-batch. По словам авторов, модель классификации изображений дошла до той же точности, сделав в 14 раз меньше шагов обучения. Своя «пересдача в одиночку» у этого слоя тоже есть, и решена она так, как поступил бы разумный преподаватель.

Стандартизация, которая устаревает на каждом шаге

Перед PCA в Applied Statistics признаки стандартизируют: из каждого вычитают среднее и делят на стандартное отклонение. После этого у всех признаков среднее 0 и разброс 1, и ни один не перекрикивает остальные только из-за единиц измерения. С входами нейросети поступают так же.

Слайды о Batch Normalization начинаются с этой мысли: "Networks converge faster if inputs have been whitened (zero mean, unit variances) and are uncorrelated to account for covariate shift" (лекция 3, слайд 33). Zero mean, unit variances — та самая стандартизация. Uncorrelated добавляет к ней второе требование: признаки не должны коррелировать друг с другом. В строгом смысле whitening — это оба требования вместе. А covariate shift — сдвиг распределения входов; точное определение будет чуть ниже.

Под этой фразой на слайде три облака точек. Original data: облако стоит в стороне от начала координат. Zero-centered data: из каждой координаты вычли её среднее, облако переехало в центр. Normalized data: каждую ось поделили на её стандартное отклонение, и красные стрелки размаха стали одинаковой длины. Третье облако всё ещё вытянуто вдоль диагонали: корреляцию рисунок не убирает, на нём стандартизация, а не полный whitening.

Входы стандартизируют один раз, до обучения: данные не меняются, значит, и статистика не устареет. Но у второго слоя свои «данные» — выходы первого. У третьего — выходы второго. А эти выходы меняются после каждого обновления весов. Слой подстроился под одно распределение своих входов, а шаг спустя оно уже другое. У явления есть имя: internal covariate shift. На слайде оно появляется одной строкой: "We can have internal covariate shift; normalization could be useful also at the level of hidden layers" (лекция 3, слайд 34).

Internal covariate shift — изменение распределения входов скрытого слоя в ходе обучения, вызванное тем, что обновляются веса предыдущих слоёв.

Слово internal здесь несёт весь смысл. Без него получается другое, более старое понятие. Слайды их тоже разводят (лекция 3, слайды 33–34): covariate shift стоит во фразе про входы сети, internal covariate shift — во фразе про скрытые слои.

Распределение входов модели на обучении и на тесте разное: \(P_{train}(X) \ne P_{test}(X)\), а задача та же. Пример конспекта: детектор кошек учили на ярких студийных фото, а проверяют на тёмных уличных.

Датасет один и тот же. Меняется то, что течёт между слоями: распределение входов слоя на шаге 100 не такое, как на шаге 1, потому что слои перед ним успели измениться.

Насколько далеко может уехать распределение? Конспект даёт такие числа: на итерации 1 вход слоя имеет среднее 0 и дисперсию 1, на итерации 100 — среднее 3 и дисперсию 10. Посмотрим, что это значит для одного нейрона с tanh. Его pre-activation обозначим \(x\): так она названа в алгоритме на слайде, до которого дойдём в следующем разделе (в лекции 2 это \(a\)). Будем считать пример насыщенным, когда \(\abs{x} \gt 2\): там \(\tanh'(x) \lt 0.071\), и градиент через нейрон почти не проходит. Это механизм из урока 24.

−2 2 x tanh(x) насыщение 4.6 %

Итерация 1: среднее 0, дисперсия 1

−2 2 x tanh(x) насыщение 68 %

Итерация 100: среднее 3, дисперсия 10

Рис. 1. Вход одного и того же нейрона с tanh в начале обучения и сто шагов спустя (числа из конспекта, стр. 188). Синий колокол — распределение \(x\) по примерам, серые полосы — зоны насыщения \(\abs{x} \gt 2\). Доля примеров в них выросла с 4.6 % до 68 %.

На итерации 100 две трети примеров дают нейрону почти нулевой градиент. При этом сам нейрон никто не трогал: его собственные веса могли вообще не измениться. Уехали слои перед ним.

Конспект перечисляет три последствия. Нейроны попадают в насыщение, и градиент затухает. Поток градиента становится нестабильным: масштаб сигналов гуляет от шага к шагу. И приходится брать маленький learning rate и очень аккуратную инициализацию, чтобы распределения не уезжали слишком быстро.

Каждый слой учится на данных, которые производят слои перед ним, а они всё время меняются: слой целится в движущуюся мишень.

Четыре шага Batch Normalization

Идея Ioffe и Szegedy простая: раз стандартизация входов помогает, а внутри сети она устаревает, будем делать её заново на каждом шаге — прямо внутри сети. На слайде метод описан тремя пунктами под строкой "Batch normalization is a technique to cope with this:" (лекция 3, слайд 34).

Пересчитывать статистику по всему датасету после каждого обновления весов слишком дорого, поэтому берут ту, что под рукой: по текущему mini-batch. Это и есть оценка по кривой. Поток — это mini-batch, сырой балл — pre-activation нейрона.

Важно, что именно усредняется. Представь таблицу: строки — примеры из mini-batch, столбцы — нейроны слоя. BN работает по столбцам: у каждого нейрона своё среднее и своя дисперсия, посчитанные по \(m\) примерам. На слайде на это указывает слово unit: "Each unit's pre-activation is normalized" (лекция 3, слайд 35). Корреляции между нейронами BN не трогает: как и на рисунке со слайда 33, это стандартизация, а не полный whitening.

нейроны слоя 1 2 3 4 5 пример 1 пример 2 пример 3 пример 4 0.4 −1.2 2.0 0.7 −0.5 0.3 1.1 −2.0 1 3 5 7 2.2 0.1 −0.4 0.9 −1.6 0.8 0.2 1.5 по строке — Layer Norm μ = 4, σ² = 5 по столбцу
Рис. 2. BN считает среднее и дисперсию отдельно для каждого нейрона — по столбцу таблицы, то есть по примерам mini-batch. Усреднение по строке (по нейронам одного примера) — другой метод, Layer Normalization.

Теперь формулы. Берём один нейрон и смотрим на его pre-activation на каждом примере из mini-batch: \(x_1, \dots, x_m\). Обозначения взяты из рамки с алгоритмом на слайде (лекция 3, слайды 35–37). Под рамкой подпись: "Algorithm 1: Batch Normalizing Transform, applied to activation x over a mini-batch". Буква \(x\) здесь — не вход сети, а значение, к которому применяют BN. Слово activation в подписи означает ту самую pre-activation, число до нелинейности.

С другими источниками рамка соотносится так. В конспекте то же число записано как \(z_i^{(l)}\), с номером слоя \(l\); здесь, как в рамке, номер слоя опущен. В лекции 2 pre-activation обозначалась \(a\) (слайд 18), номер примера \(n\), размер mini-batch \(M\) (слайд 28). В рамке номер примера \(i\), а размер \(m\), как и в конспекте.

\[ \mu_B \leftarrow \frac{1}{m}\sum_{i=1}^{m} x_i \] \[ \sigma_B^2 \leftarrow \frac{1}{m}\sum_{i=1}^{m} (x_i - \mu_B)^2 \] \[ \hat x_i \leftarrow \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} \] \[ y_i \leftarrow \gamma\,\hat x_i + \beta \equiv \mathrm{BN}_{\gamma,\beta}(x_i) \]
\(x_i\)
pre-activation нейрона на примере \(i\)
\(m\)
размер mini-batch
\(\mu_B,\ \sigma_B^2\)
mini-batch mean и mini-batch variance (в конспекте batch mean и batch variance): среднее и дисперсия по mini-batch. Индекс \(B\) — имя самого набора; на слайде он рукописный, \(\mathcal{B} = \{x_{1 \ldots m}\}\)
\(\epsilon\)
маленькая константа, чтобы не делить на ноль
\(\hat x_i\)
нормализованное значение (normalize): среднее 0, дисперсия 1
\(\gamma,\ \beta\)
scale и shift: два обучаемых числа на нейрон, в рамке "Parameters to be learned"
\(y_i\)
выход слоя BN. Запись \(\equiv \mathrm{BN}_{\gamma,\beta}(x_i)\) даёт всему преобразованию имя; дальше оно пишется короче, \(\mathrm{BN}(x)\). Это не целевое значение: цель в курсе обозначена \(t_n\)
\(\leftarrow\)
запись алгоритма: посчитать правую часть и сохранить под именем слева. В расчётах ниже вместо стрелки стоит обычный знак равенства

Первые три шага — та же стандартизация, что перед PCA. Отличий два: статистика берётся по mini-batch, а не по всей выборке, и дисперсия делится на \(m\), а не на \(m - 1\). Четвёртый шаг новый, о нём следующий раздел. Сначала числа: mini-batch из четырёх примеров \(x = (1, 3, 5, 7)\), параметры \(\gamma = 2\), \(\beta = 1\), а \(\epsilon\) так мал, что его не видно.

  1. Mini-batch mean. Складываем четыре значения и делим на \(m = 4\):

    \[ \mu_B = \frac{1 + 3 + 5 + 7}{4} = 4 \]
  2. Mini-batch variance. Отклонения от среднего: \(-3,\ -1,\ 1,\ 3\). Берём средний квадрат:

    \[ \sigma_B^2 = \frac{9 + 1 + 1 + 9}{4} = 5 \]

    Стандартное отклонение \(\sigma_B = \sqrt{5} \approx 2.236\).

  3. Normalize. Из каждого значения вычитаем 4 и делим на 2.236. Для последнего примера:

    \[ \hat x_4 = \frac{7 - 4}{2.236} = 1.342 \]

    Остальные три: \(-1.342\), \(-0.447\), \(0.447\). Сумма равна нулю, сумма квадратов равна 4, значит, дисперсия \(4 / 4 = 1\).

  4. Scale and shift. Умножаем на \(\gamma = 2\) и прибавляем \(\beta = 1\):

    \[ y_4 = 2 \cdot 1.342 + 1 = 3.683 \]
  5. Что получилось. Среднее \(y\) по mini-batch равно 1, то есть \(\beta\). Стандартное отклонение равно 2, то есть \(\gamma\). Исходные 4 и 2.236 из ответа исчезли: какими бы они ни были, у результата были бы те же среднее и разброс.

Весь пример в одной таблице: \(\gamma = 2\), \(\beta = 1\).
пример\(x_i\)\(x_i - \mu_B\)\(\hat x_i\)\(y_i\)
11−3−1.342−1.683
23−1−0.4470.106
3510.4471.894
4731.3423.683
среднее4001
разброс2.2362.23612

Если в условии задачи \(\epsilon\) не задан, считай его нулём. Дисперсию дели на \(m\). На калькуляторе это режим \(\sigma_n\), а не \(s\) и не \(\sigma_{n-1}\): с ними для того же примера выйдет \(\hat x_4 = 1.162\) вместо \(1.342\).

Зачем после нормализации снова растягивать

После шага 3 у каждого нейрона среднее 0 и разброс 1. У всех одинаково, и это слишком жёстко. У нейрона с tanh большая часть примеров попадает на средний, почти линейный участок кривой. У нейрона с ReLU примерно половина примеров даёт ноль. А если для задачи нужно другое? Чистая нормализация ограничивает то, что слой способен выразить (representational power).

Поэтому есть шаг 4: \(y_i = \gamma\,\hat x_i + \beta\). Параметр \(\gamma\) растягивает или сжимает, \(\beta\) сдвигает. Оба — обычные параметры сети (learnable parameters). У каждого нейрона своя пара, начальные значения \(\gamma = 1\) и \(\beta = 0\), дальше их учит gradient descent вместе с весами. В истории про экзамен это официальная шкала: после кривой баллы переводят в шкалу со средним \(\beta\) и разбросом \(\gamma\), и шкалу эту выбирает сама сеть.

На слайде эта строка алгоритма обведена пунктиром, и стрелка от неё ведёт к пояснению: "Apply a linear transformation, to squash the range, so that the network can decide (learn) how much normalization needs" (лекция 3, слайд 36; в конце фразы пропущено слово, читай how much normalization it needs). Linear transformation здесь — умножение на \(\gamma\) и сдвиг на \(\beta\); строго говоря, такое преобразование называют аффинным. Squash the range — сжать размах значений, хотя растянуть его \(\gamma\) может так же легко. Главное в этой фразе — the network can decide (learn): сколько нормализации оставить, сеть решает сама. При \(\gamma = 1\), \(\beta = 0\) она остаётся полной.

Конспект показывает другой край (Example 4, стр. 190). Пусть до нормализации у нейрона было \(\mu = 2\), \(\sigma = 3\). Если сеть выучит \(\gamma = 3\), \(\beta = 2\), то

\[ y_i = 3 \cdot \frac{x_i - 2}{3} + 2 = x_i . \]

Нормализация отменена полностью, вход вернулся таким, каким пришёл.

«Раз \(\gamma\) и \(\beta\) могут вернуть всё как было, BN ничего не делает». Делает. Раньше среднее и разброс входа нейрона получались как побочный результат всех весов всех предыдущих слоёв и гуляли вместе с ними. Теперь это два собственных числа нейрона. Предыдущие слои могут меняться как угодно: среднее выхода BN по mini-batch останется \(\beta\), разброс останется \(\gamma\), пока сам нейрон не решит их поменять. И оговорка к Example 4: равенство \(y_i = x_i\) точно выполняется только для mini-batch с такими же \(\mu_B\) и \(\sigma_B\). У следующего статистика чуть другая, а \(\gamma\) и \(\beta\) те же.

Слайд говорит о том же осторожнее конспекта: "Forces activations to take values on a unit Gaussian at the beginning of the training" (лекция 3, слайд 34). Слова at the beginning of the training точны: среднее 0 и дисперсия 1 на входе активации держатся, пока \(\gamma = 1\) и \(\beta = 0\), а дальше сеть двигает их сама. Слова unit Gaussian понимай как «среднее 0, дисперсия 1». Вычесть число и поделить на число — значит сдвинуть гистограмму и изменить её ширину, форма остаётся прежней: если значения \(x\) не были распределены нормально, не будут и \(\hat x\). На экзамене можно повторить формулировку слайда и добавить в скобках zero mean, unit variance.

Проверь себя на рисунке из конспекта. На рис. 22 (стр. 192) средняя панель подписана «After BN During Training». Гистограммы трёх mini-batch на ней совпали, но стоят они около −1, а не около нуля, и заметно шире распределения с дисперсией 1. Как это согласуется с «mean 0, variance 1»?

Проверить себя

На панели показан выход слоя \(y\), а не \(\hat x\). При \(\gamma \approx 2\) и \(\beta \approx -1\) картинка должна выглядеть именно так. Конспект об этих значениях молчит, поэтому рисунок и подпись кажутся несогласованными.

Где стоит слой

BN ставят между линейной частью слоя и функцией активации. На слайде: "after fully connected layers (or convolutional layers), and before nonlinearities", а на схеме рядом три блока, Fully Connected → Batch Norm → ReLU (лекция 3, слайд 34). Конспект называет тот же порядок Linear → Batch Norm → Activation.

\[ x^{(l)} = W^{(l)} h^{(l-1)} + b^{(l)} \] \[ y^{(l)} = \mathrm{BN}\bigl(x^{(l)}\bigr) \] \[ h^{(l)} = g\bigl(y^{(l)}\bigr) \]

Здесь \(x^{(l)}\) — pre-activation слоя \(l\), то самое \(x\) из алгоритма; в конспекте это \(z^{(l)}\). Выход слоя конспект пишет как \(a^{(l)}\) — не путай с \(a\) из лекции 2, где так названа pre-activation. На слайдах выход скрытого слоя — \(h^{(l)}\) (лекция 2, слайд 17), и здесь он такой же.

Linear Batch Norm g x y h Wh + b x̂, потом γx̂ + β активация bias тут лишний
Рис. 3. Место BN в слое: после линейной части, перед функцией активации. На вход активации попадает уже \(y\), а не \(x\). На слайде (лекция 3, слайд 34) те же три блока стоят сверху вниз и подписаны Fully Connected, Batch Norm, ReLU.

У этой схемы два следствия, которых нет ни в конспекте, ни на слайдах. Смещение \(b\) перед BN бесполезно. И общий масштаб весов нейрона тоже ни на что не влияет — из этого вырастет одно из главных преимуществ слоя. Оба получаются в четыре строки.

  1. Прибавим ко всем значениям нейрона одну и ту же константу \(b\). Среднее сдвинется на столько же:

    \[ x'_i = x_i + b \quad\Rightarrow\quad \mu'_B = \mu_B + b \]
  2. Отклонения от среднего не изменились, значит, не изменились ни дисперсия, ни \(\hat x_i\):

    \[ x'_i - \mu'_B = x_i - \mu_B \]

    Итог: \(\mathrm{BN}(x + b) = \mathrm{BN}(x)\). Смещение стёрто, его работу делает \(\beta\). Поэтому слой перед BN создают без смещения (в Keras use_bias=False).

  3. Теперь умножим все значения на \(c \gt 0\): например, все веса нейрона выросли в \(c\) раз. Среднее и стандартное отклонение умножатся на то же число:

    \[ \mu'_B = c\,\mu_B, \qquad \sigma'_B = c\,\sigma_B \]
  4. В дроби \(c\) сокращается (при пренебрежимо малом \(\epsilon\)):

    \[ \hat x'_i = \frac{c\,x_i - c\,\mu_B}{c\,\sigma_B} = \hat x_i \]

    Итог: \(\mathrm{BN}(c\,x) = \mathrm{BN}(x)\). Масштаб весов тоже стёрт.

Стенд: один нейрон, один mini-batch, четыре шага

Синие столбики — гистограмма того, что получил бы tanh, если остановиться на выбранном шаге; синие бусины на кривой сверху — те же 200 примеров после tanh. Серым закрашены зоны насыщения. Ползунки «среднее входа» и «дисперсия входа» изображают internal covariate shift: так предыдущие слои двигают распределение. На старте стоит «итерация 100» из конспекта.

  1. Стенд на шаге 1: сырые \(x\) и их среднее. Прикинь по гистограмме, какая доля примеров сидит в серых зонах, и сверься с полем «в насыщении tanh». Потом дойди кнопкой «Дальше» до шага 3. Что стало с этим полем?
    Что должно получиться

    Сначала 67.5 % (теория для среднего 3 и дисперсии 10 даёт 68 %), после нормализации 4.5 %. Бусины на кривой tanh переехали с плоской полки на крутой участок: градиенту снова есть через что идти.

  2. Перейди на шаг 4 при \(\gamma = 1\), \(\beta = 0\). Что будет с синей гистограммой, если двигать среднее и дисперсию входа? Сначала ответь, потом двигай.
    Что должно получиться

    Ничего. Пунктирный контур исходных \(x\) ездит и расплывается, а синяя гистограмма стоит как вкопанная. Это главное, что показывает стенд: вход гуляет, а то, что видит активация, остаётся на месте. Сдвинуть синюю гистограмму можно только ползунками \(\gamma\) и \(\beta\).

  3. Example 4 из конспекта: поставь среднее 2, дисперсию 9 (то есть \(\sigma = 3\)), затем \(\gamma = 3\) и \(\beta = 2\). Что получится на шаге 4? А если после этого снова подвигать среднее входа?
    Что должно получиться

    Синяя гистограмма точно легла на пунктирный контур: \(y = x\), формула слоя в поле под графиком стала \(y = 1.00 \cdot x + 0.00\). Но стоит сдвинуть вход, и контур уезжает, а синяя гистограмма остаётся со средним 2 и разбросом 3. Среднее и разброс теперь принадлежат нейрону, а не предыдущим слоям.

  4. Забегая вперёд. Нажми «Сбросить стенд», останься на шаге 4 и включи «режим inference». Снова подвигай среднее входа. Что изменилось по сравнению с опытом 2?
    Что должно получиться

    Теперь синяя гистограмма едет вместе со входом. В момент переключения статистика заморозилась (\(\mu = 3\), \(\sigma^2 = 10\)), и слой стал одной неизменной прямой \(y = 0.32 \cdot x - 0.95\): поле «слой BN как формула» перестало меняться. В режиме training эта формула пересобиралась под каждый mini-batch. Зачем нужна замороженная версия — в следующем разделе.

Пересдача в одиночку: training и inference

Вернёмся к студенту с пересдачи. В сети его ситуация называется inference (на слайдах — test time): модель обучена, и ей приносят один пример. Посчитай честно шаги 1–3 для mini-batch из единственного значения \(x_1 = 7\). Что выдаст слой?

Проверить себя

\(\mu_B = 7\), \(\sigma_B^2 = 0\), \(\hat x_1 = 0\), выход равен \(\beta\). Для любого входа. Слой выдаёт константу и ничего не сообщает о примере.

Дело не только в размере. Даже если на тест пришло сто примеров сразу, считать статистику по ним плохо: ответ для каждого зависел бы от того, кто оказался рядом. Один и тот же снимок давал бы разные предсказания в разной компании. На обучении такая зависимость терпима и даже полезна, это будет видно ниже. На inference она недопустима: предсказание должно быть функцией одного входа.

Разумный преподаватель достал бы архив: средний балл и разброс по всем прошлым потокам. BN делает то же. Пока идёт обучение, слой для каждого нейрона ведёт running averages (они же moving averages) — скользящие средние статистик всех mini-batch, которые через него прошли.

На слайде весь порядок работы слоя уместился в четыре строки под заголовком "In practice" (лекция 3, слайд 35):

Как именно вести running averages, слайд не говорит. Формулы ниже — из конспекта.

\[ \mu_{\mathrm{run}} \leftarrow (1 - \alpha)\,\mu_{\mathrm{run}} + \alpha\,\mu_B \] \[ \sigma^2_{\mathrm{run}} \leftarrow (1 - \alpha)\,\sigma^2_{\mathrm{run}} + \alpha\,\sigma_B^2 \]
\(\mu_{\mathrm{run}},\ \sigma^2_{\mathrm{run}}\)
накопленные оценки среднего и дисперсии; в конспекте индекс написан целиком: running
\(\alpha\)
маленькая константа, в конспекте 0.1: насколько сильно свежий mini-batch сдвигает оценку. Буква та же, что у momentum coefficient в уроке 27, но это другая величина

Это экспоненциальное сглаживание: свежие mini-batch весят больше, старые постепенно забываются. Пример на числах: \(\mu_{\mathrm{run}}\) стартует с нуля, а каждый mini-batch даёт \(\mu_B = 4\). После первого шага оценка равна 0.4, после второго 0.76, после третьего 1.08, после десятого 2.61, после двадцать второго 3.61. Общая формула: \(\mu_{\mathrm{run}} = 4\,(1 - 0.9^k)\). Архиву нужно несколько десятков шагов, чтобы наполниться.

На inference эти два числа замораживают и подставляют вместо статистики mini-batch:

\[ y = \gamma\,\frac{x - \mu_{\mathrm{run}}}{\sqrt{\sigma^2_{\mathrm{run}} + \epsilon}} + \beta \]

Всё, кроме \(x\), здесь константы. Никакой зависимости от соседей, никакой случайности.

mini-batch μ, σ² этого batch x̂ = (x − μ) / σ x зависит от соседей

Training: статистика этого mini-batch

один пример running averages μ, σ² из архива x̂ = (x − μ) / σ x всегда одни и те же

Inference: замороженный архив

Рис. 4. Формула нормализации одна, меняется источник \(\mu\) и \(\sigma^2\). В режиме training их дают соседи по mini-batch, и на каждом шаге они новые. В режиме inference их берут из running averages, накопленных за обучение: соседи не нужны.

Если раскрыть скобки, на inference весь слой BN оказывается обычной прямой:

\[ y = a\,x + c \] \[ a = \frac{\gamma}{\sqrt{\sigma^2_{\mathrm{run}} + \epsilon}}, \qquad c = \beta - a\,\mu_{\mathrm{run}} \]

Буквы \(a\) и \(c\) здесь — просто два числа, наклон и сдвиг прямой; с \(a\) из лекции 2 они не связаны. Умножить на число и прибавить число умеет и сам линейный слой. Поэтому после обучения \(a\) и \(c\) можно заранее вмонтировать в веса и смещение предыдущего слоя, и на inference BN не будет стоить ничего.

«Режим переключится сам». Не всегда. В PyTorch его переключают вручную: model.eval() перед предсказанием, model.train() перед обучением. В Keras fit() и predict() выбирают режим сами, но при прямом вызове model(x) его задаёт аргумент training. Типичный симптом забытого переключения: модель с BN хорошо обучилась, а ответ для одного и того же примера меняется в зависимости от того, с чем его подали.

Вот и ответ на задачку из начала урока. Поток из одного студента по кривой оценить нельзя: получится ноль. Его оценивают по архиву прошлых потоков. Слой BN ведёт такой архив всё обучение и на inference пользуется только им.

Один пример и его случайные соседи

На каждой итерации приходит новый mini-batch из \(m\) случайных примеров (у всей выборки среднее 3 и дисперсия 10), и одно место в нём всегда занимает наш пример \(x = 5\). Бирюзовая точка — \(\hat x\), который он получает в режиме training, по статистике этого mini-batch. Малиновая линия — \(\hat x\), который он получил бы в режиме inference, по накопленным к этому моменту running averages (\(\alpha = 0.1\)).

  1. Оставь \(m = 32\) и нажми «Обучать». Наш пример не меняется: \(x = 5\). Лягут ли бирюзовые точки на одну горизонталь?
    Что должно получиться

    Нет. Они рассыпаны вокруг 0.63 с разбросом около 0.2: соседи каждый раз новые, а с ними меняются \(\mu_B\) и \(\sigma_B\). Это и есть шум, который работает как регуляризация. Малиновая линия стартует с 5 (в начале \(\mu_{\mathrm{run}} = 0\), \(\sigma^2_{\mathrm{run}} = 1\)) и за три-четыре десятка итераций спускается к пунктиру: архиву нужно время.

  2. Нажми «Сбросить», поставь \(m = 2\) и запусти снова. Какие значения \(\hat x\) теперь могут достаться примеру? Сначала угадай.
    Что должно получиться

    Только \(+1\) и \(-1\). Среднее двух чисел лежит ровно посередине, и оба отстоят от него на \(\sigma_B\). От примера осталось одно: больше он своего соседа или меньше. Линия inference тоже гуляет и стоит выше пунктира: архив копит слишком шумные оценки, а дисперсия по двум точкам в среднем занижена вдвое — то самое деление на \(m\) вместо \(m - 1\).

  3. Теперь \(m = 8\), потом \(m = 32\), потом \(m = 128\). Следи за полем «разброс точек training». Как он зависит от \(m\)?
    Что должно получиться

    Примерно 0.43, 0.22 и 0.10: mini-batch вчетверо больше — шум вдвое меньше. Это стандартная ошибка среднего \(\sigma / \sqrt{m}\) из Applied Statistics. Главное, что показывает виджет: в режиме training ответ BN для одного и того же примера зависит от случайных соседей, и тем сильнее, чем меньше mini-batch; в режиме inference ответ один.

Что BN даёт и чего стоит

На слайде четыре преимущества под заголовком "Has shown to" (лекция 3, слайд 37; в углу самого слайда напечатано 38). За каждым стоит механизм, который в этом уроке уже был.

В конспекте пунктов пять. Пятый, Improves convergence speed, — общий итог первых четырёх: отсюда «в 14 раз меньше шагов» из статьи. На слайдах ему отвечают слова faster learning во втором пункте и converge faster в первой фразе темы (лекция 3, слайд 33).

Почему градиент уменьшается, когда веса растут?

Пусть \(x = \vb{w}\T\vb{h}\), и все веса нейрона умножили на \(c \gt 0\). Выход BN не изменился, значит, не изменилась и ошибка: \(E(c\,\vb{w}) = E(\vb{w})\) при любом \(\vb{w}\). Продифференцируем обе части по \(\vb{w}\):

\[ c\,\nabla E(c\,\vb{w}) = \nabla E(\vb{w}) \] \[ \nabla E(c\,\vb{w}) = \frac{1}{c}\,\nabla E(\vb{w}) \]

Веса в \(c\) раз длиннее — градиент в \(c\) раз короче. Без BN большой шаг раздувает веса, а те раздувают следующий градиент. С BN обратная связь отрицательная.

BN — обычная дифференцируемая операция, и backpropagation проходит через неё по цепному правилу. Особенность одна: \(\mu_B\) и \(\sigma_B\) сами зависят от всех примеров mini-batch, поэтому градиент идёт и через них. На слайде это строка "Backpropagation takes into account normalization" (лекция 3, слайд 35).

На следующем слайде от строки normalize идёт стрелка к подписи "Simple Linear operation! So it can be back-propagated" (лекция 3, слайд 36). Буквально её понимать не стоит. Вычесть число и поделить на число — линейная операция, пока эти числа постоянны, как на inference. На обучении \(\mu_B\) и \(\sigma_B\) сами считаются по тем же \(x_i\), а в \(\sigma_B\) сидят квадраты и корень. Проверка: удвой все \(x_i\) — и \(\hat x_i\) не изменятся вовсе (при пренебрежимо малом \(\epsilon\)), чего с линейной операцией не бывает. Для backpropagation линейность и не нужна, хватает дифференцируемости; точное слово стоит на слайде 34: in a differentiable way.

Для двух новых параметров формулы короткие, они прямо следуют из \(y_i = \gamma \hat x_i + \beta\):

\[ \pd{E}{\beta} = \sum_{i=1}^{m} \pd{E}{y_i} \] \[ \pd{E}{\gamma} = \sum_{i=1}^{m} \pd{E}{y_i}\,\hat x_i \]
А как выглядит градиент по самому входу \(x_i\)?

Обозначим \(g_i = \pd{E}{y_i}\). Значение \(x_i\) влияет на ошибку тремя путями: через свой \(\hat x_i\), через \(\mu_B\) и через \(\sigma_B\). Два последних входят в выход каждого примера. Если сложить все три пути (при пренебрежимо малом \(\epsilon\)), получится

\[ \pd{E}{x_i} = \frac{\gamma}{\sigma_B}\Bigl( g_i - \bar g - \hat x_i\,\overline{g \hat x} \Bigr) \]

Черта означает среднее по mini-batch: \(\bar g\) — среднее всех \(g_k\), а \(\overline{g \hat x}\) — среднее произведений \(g_k \hat x_k\). Из пришедшего градиента BN вычитает его среднее и его составляющую вдоль \(\hat x\). Это те самые два направления, которые нормализация всё равно стёрла бы: общий сдвиг и общий масштаб. Главная мысль короче формулы: на обратном проходе \(\mu_B\) и \(\sigma_B\) не считаются константами.

Сколько параметров добавляет слой

На каждый нейрон (в свёрточной сети — на каждый канал) BN хранит четыре числа.

Параметры слоя BN на один нейрон.
ЧислоРольКто его меняетТип
\(\gamma\)scalegradient descenttrainable
\(\beta\)shiftgradient descenttrainable
\(\mu_{\mathrm{run}}\)running meanформула (79)non-trainable
\(\sigma^2_{\mathrm{run}}\)running varianceформула (80)non-trainable

BN после полносвязного слоя из 64 нейронов — это \(4 \cdot 64 = 256\) чисел, из них 128 обучаемых и 128 необучаемых. Вопросы на счёт параметров ловят на двух неверных ответах: «у BN параметров нет» и «все параметры BN обучаемые».

Где BN подводит

Всё держится на том, что статистика mini-batch — хорошая оценка статистики всей выборки. Среднее по \(m\) примерам шумит со стандартной ошибкой \(\sigma / \sqrt{m}\). При \(m = 32\) это \(0.18\,\sigma\), терпимо. При \(m = 4\) уже \(0.5\,\sigma\): центр промахивается на половину разброса самих значений. При \(m = 2\) нормализованные значения всегда равны \(\pm 1\). При \(m = 1\) слой выдаёт константу \(\beta\). Маленькие mini-batch и BN плохо совместимы.

Статья про BN вышла через пять дней после статьи с He initialization: 6 и 11 февраля 2015 года. Авторы BN объясняли успех тем, что слой уменьшает internal covariate shift. В 2018 году группа из MIT (Santurkar, Tsipras, Ilyas, Madry) показала, что стабильность распределений мало связана с успехом BN; по их версии, слой делает поверхность ошибки более гладкой, и идти по ней градиентом легче. Метод работает, а спор о причине не закрыт. На слайдах этого спора нет: там BN объясняется через internal covariate shift (лекция 3, слайд 34), как в исходной статье и в конспекте. На экзамене излагай именно это объяснение. Одна фраза о том, что его оспаривают, — необязательное дополнение сверх слайдов.

В формате экзамена

Write the Batch Normalization transform applied to the pre-activations \(x_1, \dots, x_m\) of one unit over a mini-batch (a) at training time and (b) at test time. Explain why the learnable parameters \(\gamma\) and \(\beta\) are introduced.

Show model answer

(a) Training: mean and stddev are computed for each mini-batch, separately for each unit; the unit's pre-activation is normalized (mean subtraction, stddev division), then scaled and shifted.

\[ \mu_B = \frac{1}{m}\sum_{i=1}^{m} x_i \] \[ \sigma_B^2 = \frac{1}{m}\sum_{i=1}^{m}(x_i - \mu_B)^2 \] \[ \hat x_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} \] \[ y_i = \gamma\,\hat x_i + \beta \equiv \mathrm{BN}_{\gamma,\beta}(x_i) \]

Backpropagation takes the normalization into account. Meanwhile running averages are updated: \(\mu_{\mathrm{run}} \leftarrow (1-\alpha)\mu_{\mathrm{run}} + \alpha\mu_B\), and the same for \(\sigma^2_{\mathrm{run}}\).

(b) Test: the global mean / stddev are used instead of the mini-batch ones; these global statistics are the running averages estimated during training. They are frozen, so the output is a deterministic function of the single input and does not depend on the other samples.

\[ y = \gamma\,\frac{x - \mu_{\mathrm{run}}}{\sqrt{\sigma^2_{\mathrm{run}} + \epsilon}} + \beta \]

\(\gamma\) and \(\beta\): normalisation alone would force every unit to zero mean and unit variance and would limit the representational power of the layer. The scale and shift step is a linear transformation that lets the network decide (learn) how much normalization it needs: it can give each unit any mean and scale, and even undo the normalisation with \(\gamma = \sigma\), \(\beta = \mu\). These become two directly learnable quantities, decoupled from the weights of the preceding layers.

В полном ответе четыре вещи: все четыре шага с \(\epsilon\) под корнем; слова «for each unit, over the mini-batch»; другой источник статистики на тесте; и объяснение, зачем нужны \(\gamma\), \(\beta\). Слова слайдов, которые стоит повторить: "global mean / stddev", "running averages", "the network can decide (learn) how much normalization" (лекция 3, слайды 35–36). Фраза «to restore the original distribution» сама по себе ничего не объясняет: скажи про representational power.

During training a unit receives the mini-batch of pre-activations \(x = (2,\ 4,\ 4,\ 6)\). Its Batch Normalization parameters are \(\gamma = 3\), \(\beta = -1\); neglect \(\epsilon\). Compute the output of the BN layer for the sample with \(x = 6\).

Show model answer
\[ \mu_B = \frac{2 + 4 + 4 + 6}{4} = 4 \] \[ \sigma_B^2 = \frac{4 + 0 + 0 + 4}{4} = 2, \quad \sigma_B = 1.414 \] \[ \hat x = \frac{6 - 4}{1.414} = 1.414 \] \[ y = 3 \cdot 1.414 - 1 = 3.243 \]

Две типичные потери: деление на \(m - 1\) (тогда \(\sigma_B^2 = 2.67\) и ответ 2.674) и забытый корень (деление на дисперсию 2 вместо 1.414 даёт ровно 2).

A fully connected layer with 64 units is followed by a Batch Normalization layer. How many trainable parameters does the Batch Normalization layer add to the model?

Show model answer

One \(\gamma\) and one \(\beta\) per unit: \(2 \cdot 64 = 128\) trainable parameters. The layer also stores a running mean and a running variance per unit, \(2 \cdot 64 = 128\) non-trainable parameters, 256 in total.

Смотри на слово в вопросе: trainable — 128, total — 256. Число входов слоя на ответ не влияет.

Which statements about Batch Normalization at inference (test) time are correct? Select all that apply.

  • The mean and variance used are the running averages accumulated during training. Да: формулы (79)–(80) копят их всё обучение, на тесте они заморожены.
  • The mean and variance are computed on the test mini-batch. Тогда ответ для примера зависел бы от соседей, а для одного примера слой выдал бы константу \(\beta\).
  • The output for a sample does not depend on the other samples processed together with it. Именно ради этого статистику замораживают.
  • \(\gamma\) and \(\beta\) are re-estimated on the test data. Это обученные параметры. На тестовых данных в модели не меняется ничего.
  • The layer is a fixed affine function of its input and can be merged into the preceding linear layer. \(y = a x + c\) с константами \(a\) и \(c\).
Show model answer

Correct: the first, the third and the fifth. At test time the global statistics estimated with running averages are used: \(y = \gamma (x - \mu_{\mathrm{run}}) / \sqrt{\sigma^2_{\mathrm{run}} + \epsilon} + \beta\), where everything except \(x\) is a constant fixed after training.

Вопрос проверяет одну идею с трёх сторон: на тесте BN детерминирован. Если понятна причина, все пять вариантов решаются без запоминания.

The running mean of a Batch Normalization layer is initialised to 0 and updated as \(\mu_{\mathrm{run}} \leftarrow (1 - \alpha)\mu_{\mathrm{run}} + \alpha \mu_B\) with \(\alpha = 0.1\). The first three mini-batches have mini-batch means 2, 6 and 4. Compute the running mean after the third update.

Show model answer
\[ 0.9 \cdot 0 + 0.1 \cdot 2 = 0.2 \] \[ 0.9 \cdot 0.2 + 0.1 \cdot 6 = 0.78 \] \[ 0.9 \cdot 0.78 + 0.1 \cdot 4 = 1.102 \]

Ответ далёк от настоящего среднего 4: скользящее среднее стартует с нуля и разгоняется медленно. Если в задаче \(\alpha\) стоит при старом значении, а не при новом, — это запись Keras; прочитай формулу в условии.

A fully connected layer computes the pre-activations \(x = W h + b\) and is followed by Batch Normalization. (a) Why is the bias \(b\) redundant? (b) Why does Batch Normalization work poorly with very small mini-batches, and what is its output for a mini-batch of a single sample at training time?

Show model answer

(a) BN subtracts the mini-batch mean. Adding the same constant \(b\) to every \(x_i\) shifts \(\mu_B\) by \(b\) and leaves \(x_i - \mu_B\) and \(\sigma_B^2\) unchanged, so \(\mathrm{BN}(x + b) = \mathrm{BN}(x)\). The shift is provided by \(\beta\) instead.

(b) \(\mu_B\) and \(\sigma_B^2\) are estimates from \(m\) samples; their noise grows as \(m\) decreases (standard error \(\sigma/\sqrt{m}\)), so the output for a sample depends strongly on its random companions, and the running averages become noisy as well. With \(m = 1\): \(\mu_B = x\), \(\sigma_B^2 = 0\), \(\hat x = 0\), so the output is \(\beta\) for every input.

В (a) нужна одна строка алгебры, а не слова «BN нормализует». В (b) нужны слова noisy estimates и конкретный ответ «\(\beta\)» для одного примера.

What is internal covariate shift, and how does Batch Normalization cope with it? State where the Batch Normalization layer is placed in the network.

Show model answer

Networks converge faster if their inputs have been whitened (zero mean, unit variances) and are uncorrelated. The same issue appears inside the network: during training the distribution of the inputs of each hidden layer keeps changing, because the weights of the preceding layers are updated. This is internal covariate shift, so normalization is useful also at the level of hidden layers.

Batch Normalization normalizes each unit's pre-activation with the mean and stddev of the current mini-batch. This forces the activations to take values on a unit Gaussian (zero mean, unit variance) at the beginning of the training; a learnable scale \(\gamma\) and shift \(\beta\) then let the network decide how much normalization it needs. The BatchNorm layer is added after fully connected (or convolutional) layers and before the nonlinearities: Fully Connected → Batch Norm → ReLU. It can be interpreted as doing preprocessing at every layer of the network, but integrated into the network itself in a differentiable way.

Ответ собран из формулировок слайдов 33–34 лекции 3: их стоит узнавать и уметь повторить. Covariate shift без слова internal — другое явление: распределение входов сети на обучении и на тесте разное.

List four effects that Batch Normalization has been shown to have on the training of a network, and give a one-sentence reason for each.

Show model answer

1. It improves the gradient flow through the network: the pre-activations stay in the non-saturating range of the nonlinearity, so the gradients do not vanish.

2. It allows using higher learning rates (faster learning): the layer output does not depend on the scale of the incoming weights, \(\mathrm{BN}(c\,x) = \mathrm{BN}(x)\) for any \(c \gt 0\), and larger weights get smaller gradients.

3. It reduces the strong dependence on weight initialization: the scale of the signal entering the nonlinearity is set by \(\gamma\) and \(\beta\), not by the initial weights.

4. It acts as a form of regularization, slightly reducing the need for dropout: at training time the output for a sample depends on the other samples of its mini-batch, which adds noise.

Четыре пункта — это список "Has shown to" (лекция 3, слайд 37). Причин на слайде нет, они из этого урока; без них ответ превращается в перечисление. Пятому пункту конспекта, Improves convergence speed, на слайде отвечает скобка faster learning.

Проверь себя

В слое 5 нейронов, в mini-batch 8 примеров. Сколько значений \(\mu_B\) посчитает BN на одном шаге обучения?

  • 5 По одному на нейрон, каждое — среднее по 8 примерам. Это столбцы рис. 2.
  • 8 Одно среднее на пример, по нейронам, — это строки таблицы, то есть Layer Normalization.
  • 1 Так можно понять слова конспекта «for that layer», но у каждого нейрона своя статистика.
  • 40 40 — это число самих значений \(x\). Среднее сворачивает 8 из них в одно.

Слой BN с \(\gamma = 2\), \(\beta = -1\) работает в режиме training. Чему равны среднее и стандартное отклонение его выхода по mini-batch?

  • 0 и 1 Это свойства \(\hat x\) после шага 3. После шага 4 они уже другие.
  • −1 и 2 \(y = \gamma \hat x + \beta\): среднее 0 переходит в \(\beta\), разброс 1 — в \(\gamma\).
  • Зависит от входа слоя В этом и смысл BN: от входа среднее и разброс выхода не зависят.
  • 2 и −1 Перепутаны роли: сдвигает \(\beta\), растягивает \(\gamma\). Разброс не бывает отрицательным.

Почему на inference BN не берёт статистику текущего batch? Отметь все верные причины.

  • Предсказание для примера зависело бы от того, какие примеры пришли вместе с ним Один и тот же вход получал бы разные ответы в разной компании.
  • Для одного примера \(\sigma_B^2 = 0\) и \(\hat x = 0\): слой выдал бы \(\beta\) при любом входе Это «поток из одного студента» из начала урока.
  • На inference параметры \(\gamma\) и \(\beta\) не определены Определены: это обученные параметры, они работают в обоих режимах.
  • Running averages оценивают статистику всей обучающей выборки надёжнее, чем один небольшой batch Они усредняют много mini-batch, шум отдельного сглаживается.
  • На тестовых данных нет целевых значений, поэтому среднее посчитать нельзя Среднее \(x\) считается без всяких целей \(t_n\). Причина не в них.

Картинка для памяти: пересдающего оценивают по архиву, а не по нему самому.

Что такое internal covariate shift?

  • Распределение входных данных на тесте отличается от распределения на обучении Это covariate shift без слова internal. Именно их путает конспект на стр. 188.
  • Распределение входов скрытого слоя меняется в ходе обучения, потому что меняются веса предыдущих слоёв Датасет тот же; меняется то, что течёт между слоями.
  • Градиент уменьшается, проходя через слои назад Это vanishing gradient. Он может быть следствием сдвига, но это другое явление.
  • Веса сети уходят от своих начальных значений Это причина, а не само явление: термин говорит о распределении входов слоя.

В mini-batch два примера: \(x = (3,\ 9)\). Чему равны \(\hat x\) при пренебрежимо малом \(\epsilon\)?

  • \((-1,\ 1)\) Среднее 6, отклонения \(\mp 3\), дисперсия \((9 + 9)/2 = 9\), \(\sigma_B = 3\). Для двух примеров всегда выходит \(\pm 1\).
  • \((-3,\ 3)\) Среднее вычли, а на \(\sigma_B = 3\) не поделили.
  • \((-0.71,\ 0.71)\) Так выйдет при делении на \(m - 1\): дисперсия 18. В BN делят на \(m\).
  • \((0.33,\ 1)\) Это деление на максимум. BN вычитает среднее и делит на стандартное отклонение.

Ко всем смещениям \(b\) слоя, стоящего перед BN, прибавили 10. Что произойдёт с выходом BN в режиме training?

  • Сдвинется на 10 Так было бы без BN. Здесь \(\mu_B\) тоже вырастет на 10, и разность \(x_i - \mu_B\) останется прежней.
  • Не изменится \(\mathrm{BN}(x + b) = \mathrm{BN}(x)\): вычитание среднего стирает любую общую константу.
  • Сдвинется на \(10\gamma / \sigma_B\) Масштабировать нечего: сдвиг исчезает ещё на шаге 3, до умножения на \(\gamma\).
  • Вырастет разброс выхода Прибавление константы дисперсию не меняет, а разброс выхода равен \(\gamma\).

Унести с собой

Что посмотреть и почитать