Жалоба идёт назад по конвейеру

После этого урока ты посчитаешь градиент любого веса сети с одним hidden layer — на числах и в общем виде, как на слайде профессора, — и объяснишь, почему на все веса хватает двух проходов.

В сети миллион весов. Gradient descent из прошлого урока на каждом шаге хочет знать про каждый вес одно число: насколько изменится ошибка, если этот вес чуть сдвинуть. Миллион частных производных.

Самый прямой способ узнать такое число — пошевелить вес и прогнать сеть заново. Один вес — один прогон. Миллион весов — миллион прогонов ради одного-единственного шага обучения.

Backpropagation получает тот же миллион чисел за два прогона: один вперёд и один назад. И не приближённо, а точно. Как одна поездка назад успевает сообщить каждому весу его личную долю вины?

Миллион производных и два способа «в лоб»

В уроке 13 всё обучение уместилось в одну строку:

\[ w^{k+1} = w^{k} - \eta \left.\pd{E(w)}{w}\right|_{w^{k}} \]

Там ошибка была параболой от одного-двух весов, и производную можно было выписать сразу. В настоящей Feed Forward Neural Network так не получится. Вес первого слоя влияет на ошибку не напрямую, а через всё, что стоит после него: свой нейрон, его activation function, выходной нейрон. И таких весов тысячи.

Получить производные «в лоб» можно двумя способами. Оба плохие.

Сдвинь один вес на крошечное \(\varepsilon\), прогони сеть заново и посмотри, насколько изменилась ошибка: \(\Delta E / \varepsilon\). Способ называется finite differences (конечные разности).

Для \(W\) весов нужен \(W + 1\) прогон, а каждый прогон сам стоит порядка \(W\) умножений. Итого порядка \(W^2\). И ответ приближённый.

Взять правило производной сложной функции и честно выписать \(\partial E / \partial w\) для каждого веса отдельно.

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

Backpropagation (обратное распространение ошибки) — алгоритм, который считает производные ошибки \(E\) по всем весам сети за один проход вперёд и один проход назад. Он применяет правило производной сложной функции по порядку, от выхода ко входу, и переиспользует уже посчитанные промежуточные результаты.

«Backpropagation — это алгоритм обучения». Нет. Он только считает градиент и не меняет ни одного веса. Веса меняет gradient descent, которому этот градиент отдают. Backpropagation отвечает на вопрос «как получить наклон», gradient descent — «что с ним делать». Название слайда 24 лекции 2, "Gradient descent - Backpropagation", склеивает их в одно; на экзамене лучше разделять.

Конвейер с журналом

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

Жалоба едет назад по той же ленте. Каждый рабочий делает с ней две вещи. Поправляет свою настройку: на «жалоба × то, что лежало у меня на входе». И пересчитывает жалобу для предыдущего: насколько его деталь повлияла на мой результат. Один проезд вперёд, один назад — и настроены все.

x станция 1 станция 2 g заказ t журнал журнал товар едет вперёд жалоба едет назад
Рис. 1. Фиолетовые стрелки — изделие едет вперёд, станции пишут в журнал. Бирюзовый пунктир — жалоба едет назад и заходит в журнал каждой станции: там лежит то, без чего её не пересчитать.

Рабочие — это нейроны со своими весами. Журнал — сохранённые промежуточные числа. Жалоба — число, которое передаётся от выхода ко входу. Осталось понять правило, по которому жалобу пересчитывают при передаче.

Backpropagation считает градиент. Учит сеть gradient descent, которому этот градиент отдают.

Chain rule: умножай всё, что по дороге

Правило пересчёта — производная сложной функции, chain rule («правило цепочки»). Бытовая версия — три шестерёнки подряд. Если вторая крутится вдвое быстрее первой, а третья втрое быстрее второй, то третья крутится в шесть раз быстрее первой. Скорости вдоль цепочки перемножаются.

Профессор записывает это так (слайд 30 лекции 2). Пусть \(z = f(g(x))\), то есть \(z = f(y)\), где \(y = g(x)\). Тогда

\[ \frac{dz}{dx} = \frac{dz}{dy}\,\frac{dy}{dx} = f'(y)\,g'(x) \]
\(dy/dx\)
как быстро внутренняя функция \(g\) отзывается на \(x\)
\(dz/dy\)
как быстро внешняя функция \(f\) отзывается на свой вход \(y\)

Пример из конспекта (стр. 100–101): \(y = (2x + 3)^2\). Внутри стоит \(g = 2x + 3\), снаружи — квадрат. Каждое звено знает только свою производную: у внутреннего это 2, у внешнего \(2g\).

x g = 2x + 3 y = g² y ∂g/∂x = 2 ∂y/∂g = 2g ∂y/∂x = 2g · 2 = 4(2x + 3) звено за звеном
Рис. 2. Под каждым звеном — только его собственная производная. Производная всей цепочки — их произведение: \(4(2x + 3) = 8x + 12\).

Каждый такой множитель называют local derivative (локальная производная). Звено отвечает только на вопрос «как мой выход отзывается на мой вход» и ничего не знает об остальной цепочке.

Для сети понадобится ещё одно школьное правило. В сумме \(w_1x_1 + w_2x_2 + \dots + w_5x_5\) от веса \(w_5\) зависит только последнее слагаемое. Поэтому производная всей суммы по \(w_5\) равна \(x_5\), а остальные слагаемые исчезают как константы.

Производная вдоль цепочки — произведение local derivatives всех её звеньев.

Сеть 1–1–1: вперёд с журналом, назад с жалобой

Самая маленькая сеть, на которой видно всё, — пример из конспекта (Example 9, стр. 102–106). Один вход, один нейрон в hidden layer с sigmoid, один выходной нейрон с линейной activation function. Обучающий пример (sample) тоже один: \(x = 1\), правильный ответ (target) \(t = 0.5\). Шаг обучения (learning rate) \(\eta = 0.1\).

Конспект и слайды называют одни и те же вещи по-разному. В уроке — обозначения профессора, а таблица поможет читать и то, и другое.

Одно и то же в конспекте и на слайдах.
КонспектСлайды и урокЧто это
\(b^{(1)}_1\), \(b^{(2)}_1\)\(w^{(1)}_{10}\), \(w^{(2)}_{10}\)bias: вес от входа, который всегда равен 1
\(w^{(l)}_{ij}\)\(w^{(l)}_{ji}\)вес слоя \(l\); первый индекс в обоих случаях — нейрон, в который вес входит
\(y\)\(g(x|w)\)выход сети
\(a^{(1)}_1\) в двух смыслах\(a^{(1)}\) и \(h\)взвешенная сумма нейрона до активации (net input) и его выход после неё
\(E = \tfrac12 (t - y)^2\)\(E = \sum_n (t_n - g)^2\)error function; разница — множитель 2 в каждом градиенте

Forward pass: считаем и записываем

Forward pass (прямой проход) — обычное вычисление ответа сети слева направо. Его цель — узнать, насколько хороши текущие веса. Отличие от простого вычисления одно: каждое промежуточное число сохраняется. Сохранённое называют cache; это и есть журнал рабочих. В него попадут вход \(x\), net input hidden-нейрона \(a^{(1)}\), его выход \(h\), выход сети \(g\) и ошибка \(E\).

Backward pass: жалоба и два правила

Backward pass (обратный проход) начинается там, где forward pass закончился: у ошибки. Его цель — узнать, в какую сторону и насколько сильно менять каждый вес. Назад передаётся одно число на нейрон.

Error signal нейрона, \(\delta\) (в конспекте — error term), — производная ошибки по его net input: \(\delta = \partial E / \partial a\). Это «жалоба», дошедшая до нейрона: во сколько раз изменение ошибки больше маленького сдвига его взвешенной суммы. Знак говорит о направлении: при \(\delta \lt 0\) ошибка падает, когда сумма растёт.

У выходного нейрона жалоба получается прямо из ошибки. В примере \(E = \tfrac12 (t - g)^2\), а выход линейный, \(g = a^{(2)}\), поэтому

\[ \delta^{(2)} = \pd{E}{g} \cdot g'\big(a^{(2)}\big) = -(t - g) \cdot 1 \]

Дальше работают два правила.

\[ \pd{E}{w^{(l)}_{ji}} = \delta^{(l)}_j \cdot h^{(l-1)}_i \] \[ \delta^{(1)} = \delta^{(2)} \cdot w^{(2)}_{11} \cdot \sigma'\big(a^{(1)}\big) \]
\(\delta^{(l)}_j\)
error signal нейрона \(j\) слоя \(l\) — того, в который вес входит
\(h^{(l-1)}_i\)
то, что пришло по этому весу на forward pass: выход нейрона \(i\) предыдущего слоя. Для первого слоя это вход \(x_i\), для bias — единица
\(\sigma'(a^{(1)})\)
производная sigmoid; она равна \(h(1 - h)\) и считается из уже записанного \(h\)

Первое правило — chain rule в два звена. Вес влияет на ошибку только через net input своего нейрона, \(a_j = \sum_i w_{ji} h_i\). Производная этой суммы по \(w_{ji}\) равна \(h_i\): то самое школьное правило про сумму. Всё остальное уже собрано в \(\delta_j\).

Второе правило — передача жалобы на одно звено назад. От \(a^{(1)}\) до \(a^{(2)}\) два шага: через sigmoid (local derivative \(\sigma'\)) и через вес \(w^{(2)}_{11}\). На них жалоба и умножается.

«Назад едет сама ошибка \(t - g\)». Так легко прочитать и конспект (стр. 101): "The error (the difference between the predicted output and the actual target) is propagated backward through the network". Назад едет не разность, а производная ошибки \(\delta\). У линейного выхода она пропорциональна \(t - g\), но уже у hidden-нейрона это другое число: по дороге оно умножилось на вес и на \(\sigma'\).

Градиент веса = error signal нейрона, в который вес входит, × то, что по этому весу пришло.

Один шаг обучения сети 1–1–1

Сеть из примера конспекта. Под рисунком — журнал: числа появляются в нём по мере счёта. Жёлтая плашка — посчитано на этом шаге, плашка в рамке — прочитано из журнала. Бирюзовым закрашены нейроны, до которых жалоба \(\delta\) уже дошла.

  1. Дойди до шага 6 (жалоба у выхода). Прежде чем нажать «Дальше», реши: на какое число из журнала надо умножить \(\delta^{(2)}\), чтобы получить градиент веса \(w^{(2)}_{11}\), — на \(a^{(1)} = 0.7\) или на \(h = 0.668\)?
    Что должно получиться

    На \(h\). По весу \(w^{(2)}_{11}\) к выходному нейрону пришёл выход hidden-нейрона, 0.668, а не его net input. На шаге 7 в рамке ровно две плашки: \(\delta^{(2)}\) и \(h\). Ради этого виджет и сделан: градиент веса — это жалоба нейрона, в который вес входит, умноженная на то, что по весу пришло. Заново ничего не считается. Внизу на том же шаге появляется проверка шевелением: \(\Delta E / \Delta w = -0.0440\), то же число.

  2. Перед шагом 8: жалоба, которая дойдёт до hidden-нейрона, будет по модулю больше или меньше исходной? Во сколько раз?
    Что должно получиться

    Меньше в девять раз: была \(-0.0659\), стала \(-0.0073\). По дороге она умножилась на вес \(w^{(2)}_{11} = 0.5\) и на \(\sigma'(a^{(1)}) = 0.222\), вместе на 0.111. Заметь: \(\sigma'\) получена как \(h(1 - h)\) из журнала, sigmoid заново не вызывали.

  3. Переключи error function на вариант профессора, \((t - g)^2\). Что изменится на forward pass, а что на backward?
    Что должно получиться

    На forward pass — только само значение \(E\): 0.00434 вместо 0.00217. На backward pass удваивается всё: обе жалобы и все четыре градиента. Двойка появляется в \(\delta^{(2)}\) и едет назад вместе с ней. Шаг тоже вдвое длиннее: ошибка падает на 50 %, а не на 27 %.

  4. Верни \(\tfrac12 (t - g)^2\) и увеличивай \(\eta\). При каком \(\eta\) сеть попадёт почти точно в target? При каком ошибка после шага станет больше, чем до него?
    Что должно получиться

    Почти точно — при \(\eta = 0.7\): выход 0.502. Начиная с \(\eta = 1.4\) ошибка после шага больше исходной: сеть перелетает цель дальше, чем стояла до неё. Backpropagation тут ни при чём, наклон он сообщил честно. Длину шага выбирает gradient descent — это история про learning rate из урока 13.

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

Example 9 в обозначениях профессора: \(x = 1\), \(t = 0.5\), \(\eta = 0.1\), \(E = \tfrac12 (t - g)^2\).
ШагЧто считаемЧисла
1дано\(w^{(1)}_{11} = 0.4\), \(w^{(1)}_{10} = 0.3\), \(w^{(2)}_{11} = 0.5\), \(w^{(2)}_{10} = 0.1\)
2\(a^{(1)} = w^{(1)}_{11}x + w^{(1)}_{10}\)\(0.4 \cdot 1 + 0.3 = 0.7\)
3\(h = \sigma(a^{(1)})\)\(1 / (1 + e^{-0.7}) = 0.668\)
4\(g = w^{(2)}_{11}h + w^{(2)}_{10}\)\(0.5 \cdot 0.668 + 0.1 = 0.434\)
5\(E = \tfrac12 (t - g)^2\)\(\tfrac12 \cdot 0.066^2 = 0.0022\)
6\(\delta^{(2)} = -(t - g) \cdot 1\)\(-(0.5 - 0.434) = -0.066\)
7\(\partial E/\partial w^{(2)}_{11} = \delta^{(2)} h\)\(-0.066 \cdot 0.668 = -0.044\)
\(\partial E/\partial w^{(2)}_{10} = \delta^{(2)} \cdot 1\)\(-0.066\)
8\(\delta^{(1)} = \delta^{(2)} w^{(2)}_{11}\, h(1 - h)\)\(-0.066 \cdot 0.5 \cdot 0.222 = -0.0073\)
9\(\partial E/\partial w^{(1)}_{11} = \delta^{(1)} x\)\(-0.0073 \cdot 1 = -0.0073\)
\(\partial E/\partial w^{(1)}_{10} = \delta^{(1)} \cdot 1\)\(-0.0073\)
10\(w \leftarrow w - \eta\,\partial E/\partial w\)\(w^{(2)}_{11} = 0.5044\), \(w^{(2)}_{10} = 0.1066\), \(w^{(1)}_{11} = 0.40073\), \(w^{(1)}_{10} = 0.30073\)
11новый forward pass\(g = 0.444\), \(E = 0.0016\)

Что дал один шаг

x h g 0.4 0.5 bias 0.3 bias 0.1 g = 0.434 t = 0.5 до цели 0.066 E = 0.00217

До: веса из условия

x h g 0.4007 0.5044 bias 0.3007 bias 0.1066 g = 0.444 t = 0.5 до цели 0.056 E = 0.00158

После: один шаг с \(\eta = 0.1\)

Рис. 3. Фиолетовая точка — выход сети, пунктир — target, бирюзовый отрезок — сколько осталось. Веса изменились в третьем-четвёртом знаке, а ошибка упала на 27 %.

Конспект обрывает пример на обновлении весов и этот результат не показывает. Если повторять те же три действия — forward, backward, update, — выход подбирается к цели: 0.452 после двух шагов, 0.487 после десяти, 0.49998 после пятидесяти.

Заметь, как по-разному сдвинулись слои. Вес у выхода получил градиент \(-0.044\), вес у входа — всего \(-0.0073\), в шесть раз меньше. По дороге назад жалоба умножилась на \(w^{(2)}_{11}\,\sigma'(a^{(1)}) = 0.5 \cdot 0.222\). Производная sigmoid никогда не превышает 0.25 (урок 10), поэтому каждый слой с sigmoid ослабляет жалобу по дороге назад — если только большой вес этого не перекроет. В глубокой сети из этого вырастает отдельная проблема — о ней урок 24.

Формула профессора: \(\partial E / \partial w^{(1)}_{ji}\)

Теперь та же механика в общем виде — так, как она записана на слайдах и как её естественно спросить на экзамене. На слайде 25 лекции 2 профессор рисует сеть с \(I\) входами, одним hidden layer из \(J\) нейронов и одним выходом и даёт задание: "Compute the \(w^{(1)}_{ji}\) weight update formula by gradient descent". С подсказкой: "Use j=3 and i=5".

\[ g_1(x_n|w) = g_1\Big(\sum_{j=0}^{J} w^{(2)}_{1j}\, h_j\big(a_{j,n}\big)\Big) \] \[ a_{j,n} = \sum_{i=0}^{I} w^{(1)}_{ji}\, x_{i,n} \] \[ E(w) = \sum_{n=1}^{N} \big(t_n - g_1(x_n, w)\big)^2 \]
\(x_{i,n}\)
\(i\)-й вход sample \(n\); \(x_{0,n} = 1\) — вход для bias
\(a_{j,n}\)
net input hidden-нейрона \(j\). Буква введена для краткости: на слайдах эта сумма написана целиком или заменена точкой, \(h_j(.)\)
\(h_j\)
activation function hidden-нейрона \(j\) и его выход; \(h_0 = 1\) — вход для bias выходного нейрона
\(g_1\)
activation function выходного нейрона и выход сети
\(t_n\)
target sample \(n\)
\(E(w)\)
error function, здесь Sum of Squared Errors

Вес \(w^{(1)}_{35}\) — связь от пятого входа к третьему hidden-нейрону. От него до ошибки пять звеньев, и у каждого своя local derivative.

forward pass: считаем и записываем w₃₅ Σ h₃ Σ g₁ E x₅ h₃′ w₁₃ g₁′ −2(t − g₁) hidden-нейрон 3 выходной нейрон backward pass: перемножаем справа налево
Рис. 4. Над каждой стрелкой — её local derivative. Производная ошибки по \(w^{(1)}_{35}\) — произведение всех пяти. Здесь \(w_{35}\) — вес первого слоя, \(w_{13}\) — второго.

Путь от веса до ошибки

Сеть со слайда 25 при \(I = 5\), \(J = 3\). Sample один: под входами его числа \(x_i\), target \(t = 1\). Вес выбирается ползунками или нажатием на вход и на hidden-нейрон. Кружок «1» в столбце входов — это \(x_0\), вход для bias.

  1. Оставь \(j = 3\), \(i = 5\) и собери произведение кнопкой «Дальше». Перед последним шагом предскажи знак: gradient descent увеличит вес \(w^{(1)}_{35}\) или уменьшит?
    Что должно получиться

    Градиент отрицательный: \(-0.3144 \cdot 1 \cdot 0.8 \cdot 0.2403 \cdot 2\) \(= -0.1208\). Вес сдвигается против градиента, то есть растёт. То же без формул: выход 0.843 меньше target 1, вес \(w^{(2)}_{13}\) положительный и вход \(x_5\) положительный, значит, рост \(w^{(1)}_{35}\) поднимет выход.

  2. Не трогая \(j\), поставь \(i = 2\). Сколько из пяти множителей изменится? А при \(i = 4\)?
    Что должно получиться

    Один, последний: \(x_5 = 2\) сменился на \(x_2 = -1\), и градиент стал \(+0.0604\). Первые четыре множителя — жалоба нейрона \(h_3\), одна на все шесть его входных весов. При \(i = 4\) вход равен нулю, и градиент тоже ноль: вес, по которому ничего не пришло, ни в чём не виноват.

  3. Верни \(i = 5\) и переключи \(j\) с 3 на 2. Какие множители остались прежними?
    Что должно получиться

    Три. Первые два, \(-2(t - g_1)\) и \(g_1'\), — это жалоба выходного нейрона, одна на всю сеть. Последний, \(x_5 = 2\), не изменился, потому что вход тот же. Сменились вес \(w^{(2)}_{1j}\) (был 0.8, стал \(-0.4\)) и производная \(h_j'\) (была 0.2403, стала 0.2445); градиент стал \(+0.0615\). Вот главная мысль виджета: множители у самой ошибки общие для разных весов, поэтому их достаточно посчитать один раз.

  4. Смени activation function выхода на sigmoid. Какой множитель перестал быть единицей?
    Что должно получиться

    Второй: теперь \(g_1' = g_1(1 - g_1) = 0.210\). Изменился и первый множитель, потому что выход стал другим: 0.699 вместо 0.843. Градиент для \(j = 3\), \(i = 5\) по модулю упал: был \(-0.121\), стал \(-0.049\). Множитель \(g_1'\) легче всего потерять — как раз потому, что для линейного выхода он равен единице.

Тот же вывод на бумаге

На бумаге тот же путь записывают формулами. Ниже — вывод со слайда 26 для \(j = 3\), \(i = 5\), по одному действию за шаг. Для краткости \(g_1\) означает \(g_1(x_n, w)\).

  1. Ошибка — сумма по samples. Производная суммы равна сумме производных, поэтому разбираемся с одним слагаемым:

    \[ \pd{E}{w^{(1)}_{35}} = \sum_{n=1}^{N} \pd{\,(t_n - g_1)^2}{w^{(1)}_{35}} \]
  2. Внешнее звено — квадрат. По chain rule: производная квадрата, умноженная на производную того, что внутри. Внутри стоит \(t_n - g_1\), и от веса зависит только \(g_1\), со знаком минус:

    \[ \pd{\,(t_n - g_1)^2}{w^{(1)}_{35}} = -2\,(t_n - g_1)\,\pd{g_1}{w^{(1)}_{35}} \]
  3. Следующее звено — выходной нейрон: \(g_1\) есть activation function от суммы. Снова chain rule: производная активации на производную суммы.

    \[ \pd{g_1}{w^{(1)}_{35}} = g_1'(\cdot)\,\pd{}{w^{(1)}_{35}} \sum_{j=0}^{J} w^{(2)}_{1j} h_j \]

    Здесь \(g_1'(\cdot)\) — производная activation function выхода, взятая в её собственном net input, то есть в сумме \(\sum_j w^{(2)}_{1j} h_j\). Профессор пишет её как \(g_1'(x_n, w)\).

  4. В сумме по \(j\) от веса \(w^{(1)}_{35}\) зависит одно слагаемое: это входной вес нейрона 3, остальные нейроны его не видят. Остаётся \(w^{(2)}_{13} h_3\), а \(w^{(2)}_{13}\) — константа:

    \[ \pd{}{w^{(1)}_{35}} \sum_{j=0}^{J} w^{(2)}_{1j} h_j = w^{(2)}_{13}\,\pd{h_3}{w^{(1)}_{35}} \]
  5. Звено hidden-нейрона: \(h_3\) — activation function от суммы \(a_{3,n}\). Chain rule в третий раз:

    \[ \pd{h_3}{w^{(1)}_{35}} = h_3'(a_{3,n})\,\pd{a_{3,n}}{w^{(1)}_{35}} \]
  6. В сумме \(a_{3,n} = \sum_i w^{(1)}_{3i} x_{i,n}\) от \(w^{(1)}_{35}\) зависит только слагаемое с \(i = 5\). Его производная — то, что пришло по весу:

    \[ \pd{a_{3,n}}{w^{(1)}_{35}} = x_{5,n} \]
  7. Собираем звенья обратно, от ошибки к весу:

    \[ \begin{aligned} \pd{E}{w^{(1)}_{35}} = -2 \sum_{n=1}^{N} & (t_n - g_1)\, g_1'(\cdot) \\ & \cdot\, w^{(2)}_{13}\, h_3'(a_{3,n})\, x_{5,n} \end{aligned} \]
  8. В выводе не использовано ничего особенного про числа 3 и 5. Заменяем их на \(j\) и \(i\) и подставляем градиент в правило gradient descent:

    \[ w^{(1)}_{ji} \leftarrow w^{(1)}_{ji} - \eta\,\pd{E}{w^{(1)}_{ji}} \]

Получается формула, которую профессор повторяет на слайдах 27, 29 и 33. Её стоит уметь и вывести, и прочитать по множителям.

\[ \begin{aligned} \pd{E}{w^{(1)}_{ji}} = {} & -2 \sum_{n=1}^{N} \big(t_n - g_1(x_n, w)\big) \\ & \cdot\, g_1'(x_n, w)\; w^{(2)}_{1j} \\ & \cdot\, h_j'\Big(\sum_{i=0}^{I} w^{(1)}_{ji}\, x_{i,n}\Big)\; x_{i,n} \end{aligned} \]
Пять множителей, как их подписывает слайд 30 лекции 2.
№МножительЧья это local derivativeГде живёт
1\(-2(t_n - g_1)\)\(\partial E / \partial g\)у ошибки
2\(g_1'(x_n, w)\)\(\partial g / \partial (w^{(2)}_{1j} h_j)\)выходной нейрон
3\(w^{(2)}_{1j}\)\(\partial (w^{(2)}_{1j} h_j) / \partial h_j\)связь hidden → выход
4\(h_j'(a_{j,n})\)\(\partial h_j / \partial (w^{(1)}_{ji} x_i)\)hidden-нейрон \(j\)
5\(x_{i,n}\)\(\partial (w^{(1)}_{ji} x_i) / \partial w^{(1)}_{ji}\)вход \(i\)

Производные трёх activation functions курса считаются из уже записанного выхода (слайд 18 лекции 2): linear — \(g' = 1\), sigmoid — \(g' = g(1 - g)\), tanh — \(g' = 1 - g^2\). На экзамене это экономит время: \(e^{-a}\) второй раз считать не нужно.

Вес выходного слоя: путь короче

У веса \(w^{(2)}_{1j}\) дорога до ошибки короче на два звена. Первые два множителя те же, а дальше сразу стоит то, что пришло по весу, — выход \(h_j\):

\[ \pd{E}{w^{(2)}_{1j}} = -2 \sum_{n=1}^{N} (t_n - g_1)\, g_1'(\cdot)\, h_j(\cdot) \]

Это снова первое правило из примера 1–1–1: жалоба нейрона, в который вес входит, на вход веса. В обозначениях с \(\delta\) обе формулы урока выглядят так:

\[ \delta^{\text{out}}_n = -2\,(t_n - g_1)\; g_1'(\cdot) \] \[ \delta_{j,n} = \delta^{\text{out}}_n\; w^{(2)}_{1j}\; h_j'(a_{j,n}) \] \[ \pd{E}{w^{(2)}_{1j}} = \sum_{n=1}^{N} \delta^{\text{out}}_n\, h_j(a_{j,n}) \] \[ \pd{E}{w^{(1)}_{ji}} = \sum_{n=1}^{N} \delta_{j,n}\, x_{i,n} \]
\(\delta^{\text{out}}_n\)
error signal выходного нейрона на sample \(n\): множители 1 и 2
\(\delta_{j,n}\)
error signal hidden-нейрона \(j\): та же жалоба, прошедшая через вес и через активацию (множители 3 и 4)

Два прохода вместо миллиона

Вернёмся к задачке из начала. Выводить такую формулу руками для каждого веса нельзя, и на слайде 29 лекции 2 профессор спрашивает у неё: "Can I make it automatic?" Ответ — на слайде 30, одной фразой: "Weights update can be done in parallel, locally, and requires just 2 passes". Теперь каждое слово можно расшифровать.

Разгадка в том, что произведения для разных весов почти целиком совпадают. В виджете это было видно: первые два множителя общие для всей сети, следующие два — для всех весов одного нейрона. Backpropagation считает общую часть один раз и передаёт её назад готовым числом \(\delta\).

w₁₅ w₂₅ w₃₅ h₁ h₂ h₃ g₁ g₁ g₁ E E E

Формула для каждого веса отдельно

w₁₅ w₂₅ w₃₅ h₁ h₂ h₃ g₁ E один раз

Backpropagation

Рис. 5. Жёлтым отмечен участок от выхода до ошибки — множители 1 и 2. Слева его проходят заново для каждого веса. Справа он посчитан однажды, и от него расходятся ветки.

Посчитаем на сети со слайда при \(I = 5\), \(J = 3\). Весов в ней 22: \((5 + 1) \cdot 3\) в первом слое и \(3 + 1\) во втором. Шевелением это 23 прогона. У backpropagation один прогон вперёд, четыре жалобы на обратном пути (одна у выхода и три у hidden-нейронов) и 22 умножения. Для миллиона весов счёт тот же: два прохода вместо миллиона и одного.

Шевеление при этом не бесполезно. Им проверяют готовую реализацию: если backpropagation и finite differences дают одно число, формулы верны. В обоих виджетах урока такая проверка есть: это строка «пошевелить вес на ±0.001» под ползунками.

Два следствия, которые стоит уметь объяснить

Activation function обязана быть дифференцируемой. На каждом шаге назад жалоба умножается на \(h'(a)\). У ступеньки перцептрона производная равна нулю везде, кроме точки скачка (там её нет вовсе): жалоба обнуляется и до первого слоя не доходит. Поэтому на слайде 17 лекции 2 стоит требование "Activation functions must be differentiable to train it". Правило из урока 7, Hebbian learning, тут не выручит: ему нужен target для каждого нейрона, а у hidden-нейронов своего target нет (урок 8).

Сумма по \(n\) — не часть backpropagation. Backpropagation даёт градиент для одного sample. Что делать с градиентами разных samples, решает вариант gradient descent из урока 13: batch складывает все \(N\), stochastic берёт один, mini-batch — несколько.

А если выходов несколько или слоёв больше?

Тогда от hidden-нейрона до ошибки ведёт не одна дорога, а несколько: через каждый нейрон следующего слоя. Chain rule для нескольких дорог складывает их вклады:

\[ \delta_j = h_j'(a_j) \sum_{k} w_{kj}\, \delta_k \]

Сумма идёт по всем нейронам \(k\), в которые входит выход нейрона \(j\). При одном выходе в ней одно слагаемое, и получается формула этого урока. Правило для веса не меняется: жалоба × вход.

Метод придумали не для нейросетей. Впервые его опубликовал в 1970 году финский студент Seppo Linnainmaa в магистерской работе — как способ быстро дифференцировать цепочки вычислений. Paul Werbos в 1974 году обсуждал его применение к нейросетям. Знаменитым метод сделала статья Rumelhart, Hinton и Williams в Nature (1986): четыре страницы, на которых показано, что hidden-нейроны с его помощью сами выучивают полезные признаки.

Двух проходов хватает, потому что множители у ошибки общие для всех весов: их считают один раз и передают назад.

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

Consider a feed-forward neural network with one hidden layer of \(J\) neurons and a single output:

\[ \begin{aligned} g_1(x_n|w) = g_1\Big( & \sum_{j=0}^{J} w^{(2)}_{1j} \\ & \cdot\, h_j\Big(\sum_{i=0}^{I} w^{(1)}_{ji}\, x_{i,n}\Big)\Big) \end{aligned} \]

It is trained by minimising \(E(w) = \sum_{n=1}^{N} (t_n - g_1(x_n, w))^2\). Derive \(\partial E / \partial w^{(1)}_{ji}\) and write the gradient descent update rule for this weight.

Show model answer

Let \(a_{j,n} = \sum_i w^{(1)}_{ji} x_{i,n}\). Apply the chain rule from the error back to the weight.

\[ \pd{E}{w^{(1)}_{ji}} = -2 \sum_{n=1}^{N} (t_n - g_1)\,\pd{g_1}{w^{(1)}_{ji}} \] \[ \pd{g_1}{w^{(1)}_{ji}} = g_1'(x_n, w)\; w^{(2)}_{1j}\;\pd{h_j}{w^{(1)}_{ji}} \]

(only the \(j\)-th term of \(\sum_j w^{(2)}_{1j} h_j\) depends on \(w^{(1)}_{ji}\))

\[ \pd{h_j}{w^{(1)}_{ji}} = h_j'(a_{j,n})\; x_{i,n} \]

(only the \(i\)-th term of \(a_{j,n}\) depends on \(w^{(1)}_{ji}\)). Hence

\[ \begin{aligned} \pd{E}{w^{(1)}_{ji}} = -2 \sum_{n=1}^{N} & (t_n - g_1)\; g_1'(x_n, w) \\ & \cdot\, w^{(2)}_{1j}\; h_j'(a_{j,n})\; x_{i,n} \end{aligned} \]

Update rule, with learning rate \(\eta\), starting from random initial weights:

\[ w^{(1)}_{ji} \leftarrow w^{(1)}_{ji} - \eta\,\pd{E}{w^{(1)}_{ji}} \]

В полном ответе есть три вещи. Первая — множитель \(-2\) и знак. Вторая — сказано словами, что из суммы по \(j\) выживает одно слагаемое и из суммы по \(i\) тоже одно. Третья — последний множитель \(x_{i,n}\) и сумма по \(n\). Легче всего потерять \(g_1'\): он равен единице только для линейного выхода.

A network has two inputs, two hidden neurons with sigmoid activation and one output neuron with linear activation. The weights are (the bias is the weight with second index 0):

  • hidden neuron 1: \(w^{(1)}_{10} = 0\), \(w^{(1)}_{11} = 1\), \(w^{(1)}_{12} = -0.5\)
  • hidden neuron 2: \(w^{(1)}_{20} = -1\), \(w^{(1)}_{21} = 1\), \(w^{(1)}_{22} = 0.5\)
  • output neuron: \(w^{(2)}_{10} = 0.1\), \(w^{(2)}_{11} = 0.4\), \(w^{(2)}_{12} = 0.6\)

For the single training sample \(x = (1, 2)\), \(t = 1\) and the error \(E(w) = (t - g_1(x, w))^2\), compute \(\partial E / \partial w^{(1)}_{22}\).

Show model answer

Forward pass: \(a_1 = 0 + 1 - 1 = 0\), \(h_1 = 0.5\); \(a_2 = -1 + 1 + 1 = 1\), \(h_2 = \sigma(1) = 0.7311\).

\[ \begin{aligned} g_1 &= 0.1 + 0.4 \cdot 0.5 + 0.6 \cdot 0.7311 \\ &= 0.7386 \end{aligned} \]

Backward pass, factor by factor: \(-2(t - g_1) = -0.5227\); \(g_1' = 1\) (linear output); \(w^{(2)}_{12} = 0.6\); \(h_2' = h_2(1 - h_2) = 0.1966\); \(x_2 = 2\).

\[ \begin{aligned} \pd{E}{w^{(1)}_{22}} &= -0.5227 \cdot 1 \cdot 0.6 \cdot 0.1966 \cdot 2 \\ &= -0.1233 \end{aligned} \]

Нейрон 1 в ответ не входит совсем: вес \(w^{(1)}_{22}\) идёт в нейрон 2, и из суммы по \(j\) остаётся только он. Считать \(h_1\) всё равно нужно — без него не получить \(g_1\). Держи четыре знака после запятой до самого конца и не перепутай \(x_2 = 2\) с \(x_1 = 1\).

A network has one input, one hidden neuron with sigmoid activation and one output neuron with linear activation: \(w^{(1)}_{11} = 0.4\), \(w^{(1)}_{10} = 0.3\), \(w^{(2)}_{11} = 0.5\), \(w^{(2)}_{10} = 0.1\). The training sample is \(x = 1\), \(t = 0.5\), the error is \(E(w) = (t - g(x|w))^2\) and the learning rate is \(\eta = 0.1\). Compute the value of \(w^{(2)}_{11}\) after one step of gradient descent.

Show model answer

Forward pass: \(a = 0.4 + 0.3 = 0.7\), \(h = \sigma(0.7) = 0.6682\), \(g = 0.5 \cdot 0.6682 + 0.1 = 0.4341\).

\[ \begin{aligned} \pd{E}{w^{(2)}_{11}} &= -2\,(t - g)\, g'\, h \\ &= -2 \cdot 0.0659 \cdot 1 \cdot 0.6682 \\ &= -0.0881 \end{aligned} \] \[ w^{(2)}_{11} \leftarrow 0.5 - 0.1 \cdot (-0.0881) = 0.5088 \]

Это сеть из конспекта, но с ошибкой профессора. В конспекте получается 0.5044, потому что там \(E = \tfrac12 (t - y)^2\) и градиент вдвое меньше. Для веса выходного слоя множителей три: \(-2(t - g)\), \(g'\) и вход веса \(h\).

For a network with one hidden layer and a single output neuron with sigmoid activation, trained with \(E(w) = \sum_n (t_n - g_1(x_n, w))^2\), which expression is \(\partial E / \partial w^{(2)}_{1j}\), the derivative with respect to a weight of the output neuron?

  • \(-2\sum_n (t_n - g_1)\; g_1'(\cdot)\; h_j(\cdot)\) Жалоба выходного нейрона, умноженная на то, что пришло по весу: выход \(h_j\).
  • \(-2\sum_n (t_n - g_1)\; g_1'(\cdot)\; w^{(2)}_{1j}\) \(w^{(2)}_{1j}\) — производная по \(h_j\), а не по весу. Она нужна, когда идёшь дальше назад, к первому слою.
  • \(-2\sum_n (t_n - g_1)\; h_j(\cdot)\) Пропущена производная выходной активации. Так было бы только при линейном выходе, а здесь sigmoid.
  • \(-2\sum_n (t_n - g_1)\; g_1'(\cdot)\; h_j'(\cdot)\; x_{i,n}\) \(h_j'\) и \(x_{i,n}\) появляются только у весов первого слоя; у \(w^{(2)}_{1j}\) индекса \(i\) нет вовсе.
Show model answer

The path from \(w^{(2)}_{1j}\) to the error has three links: \(\partial E / \partial g_1 = -2(t_n - g_1)\), the output activation \(g_1'(\cdot) = g_1(1 - g_1)\), and \(\partial (w^{(2)}_{1j} h_j) / \partial w^{(2)}_{1j} = h_j\).

Правило одно для всех слоёв: error signal нейрона, в который вес входит, × вход веса. Для выходного слоя вход веса — \(h_j\), для первого — \(x_{i,n}\).

Backpropagation computes the gradient of the error with one forward and one backward pass. (a) Why is this cheaper than perturbing each weight in turn? (b) Explain the statement "weights update can be done in parallel, locally, and requires just 2 passes". (c) Why must the activation functions be differentiable?

Show model answer

(a) Perturbing the weights (finite differences) needs one extra forward pass per weight, i.e. \(W + 1\) passes for \(W\) weights, and gives only an approximation. Backpropagation applies the chain rule from the output backwards and reuses the shared factors: the error signal of a neuron, \(\partial E / \partial a\), is computed once and used by all its incoming weights and by the previous layer. The cost is one forward plus one backward pass, and the gradient is exact.

(b) Local: the derivative with respect to a weight is the error signal of the neuron the weight enters times the signal that came through the weight; both are available at the weight itself. Parallel: given the error signals of a layer, the gradients of all its weights are independent and can be computed at once. Two passes: the forward pass computes and stores the outputs of all neurons; the backward pass propagates the error signals from the output to the input using the stored values.

(c) Every backward step multiplies the error signal by the derivative of an activation function, \(g'(a)\) or \(h'(a)\). A step function has zero derivative almost everywhere, so no error signal would reach the earlier weights.

Опорные слова ответа: chain rule, reuse of shared factors, stored values. Фраза "because it is faster" без объяснения, что именно переиспользуется, на вопрос не отвечает.

Select all true statements about backpropagation.

  • It computes the gradient of the error; the weights themselves are changed by gradient descent. Backpropagation отвечает на вопрос «как получить наклон», а не «что с ним делать».
  • The forward pass has to store the outputs of the neurons, because the backward pass uses them. И входы весов, и производные активаций берутся из сохранённых значений.
  • It needs one backward pass for every weight of the network. Один backward pass на все веса сразу — в этом весь смысл.
  • In a network with one hidden layer, \(\partial E / \partial w^{(1)}_{ji}\) for one sample is proportional to the input \(x_{i,n}\). Это последний множитель формулы. При нулевом входе градиент веса равен нулю.
  • The gradient it returns is an approximation whose accuracy depends on a small step \(\varepsilon\). Это описание finite differences. Chain rule даёт точную производную.
Show model answer

True: the first, the second and the fourth. Backpropagation is an exact, efficient way to compute the gradient with one forward and one backward pass; it relies on values stored during the forward pass; the derivative with respect to a first-layer weight contains the factor \(x_{i,n}\).

В вопросах «select all» разбирай каждое утверждение отдельно, как самостоятельный вопрос «верно или нет». Типичная ловушка — смешать backpropagation с gradient descent или с численной проверкой градиента.

Проверь себя

В примере 1–1–1 жалоба у выхода равна \(\delta^{(2)}\). На какое число её умножают, чтобы получить \(\partial E / \partial w^{(2)}_{11}\)?

  • На \(a^{(1)} = 0.7\) Это net input hidden-нейрона. По весу \(w^{(2)}_{11}\) едет не он, а то, что получилось после sigmoid.
  • На \(h = 0.668\) Вес \(w^{(2)}_{11}\) умножается на \(h\), поэтому производная суммы по нему равна \(h\).
  • На \(x = 1\) Вход \(x\) приходит по весу первого слоя; он понадобится для \(\partial E / \partial w^{(1)}_{11}\).
  • На \(w^{(2)}_{11} = 0.5\) На сам вес жалобу умножают, когда передают её дальше назад, к hidden-нейрону.

Что именно едет назад на backward pass?

  • Значения \(h\) и \(g\) в обратном порядке Значения forward pass никуда не едут: они лежат в журнале и ждут, когда их прочитают.
  • Разность \(t - g\), одна и та же для всех слоёв С неё всё начинается, но на каждом звене она умножается на local derivative и меняется.
  • Производная ошибки по net input нейрона; на каждом звене она умножается на вес и на производную activation function Это и есть error signal \(\delta\). В примере: \(-0.0659 \cdot 0.5 \cdot 0.222 = -0.0073\).
  • Новые значения весов Веса меняет gradient descent, уже после того, как backward pass закончен.

Формула профессора для \(\partial E / \partial w^{(1)}_{ji}\) состоит из пяти множителей. Какие из них одинаковы для всех весов первого слоя (при одном и том же sample)?

  • \(-2(t_n - g_1)\) Зависит только от выхода сети и target.
  • \(g_1'(x_n, w)\) Производная активации единственного выходного нейрона.
  • \(w^{(2)}_{1j}\) Зависит от \(j\): общий только для весов, входящих в нейрон \(h_j\).
  • \(h_j'(\cdot)\) Тоже зависит от \(j\): у каждого hidden-нейрона своя точка на sigmoid.
  • \(x_{i,n}\) Зависит от \(i\): у весов от разных входов он разный.

Первые два множителя — жалоба выходного нейрона. Её считают один раз, и поэтому хватает одного прохода назад.

У sample вход \(x_4\) равен нулю. Что этот sample добавит в градиенты весов \(w^{(1)}_{j4}\)?

  • Ноль для любого \(j\) Последний множитель равен \(x_{4,n} = 0\). По этим весам ничего не пришло, значит, на ошибку они не повлияли.
  • \(-2(t_n - g_1)\) Это только первый множитель; произведение с нулём даст ноль.
  • Зависит от \(h_j'\) Каким бы ни был \(h_j'\), он умножается на ноль.
  • Нельзя сказать без backward pass Можно: достаточно посмотреть на последний множитель формулы.

Ошибку \(\tfrac12 (t - g)^2\) заменили на \((t - g)^2\), а \(\eta\) не тронули. Что произойдёт с первым шагом обучения?

  • Ничего: точка минимума та же Точка минимума та же, но шаг определяется градиентом, а он изменился.
  • Все градиенты и сам шаг удвоятся, направление останется прежним Двойка появляется в жалобе выхода и вместе с ней попадает во все слои. Эффект такой же, как от удвоения \(\eta\).
  • Удвоится только градиент выходного слоя Жалоба hidden-нейрона получается из жалобы выхода, поэтому удваивается и она.
  • Изменится направление шага Все градиенты умножились на одно положительное число: направление то же.

В hidden layer sigmoid заменили на ступеньку перцептрона. Что даст backpropagation для весов первого слоя?

  • Тот же градиент, что и с sigmoid Множитель \(h_j'\) у ступеньки совсем другой.
  • Ноль почти при любых весах Производная ступеньки равна нулю везде, кроме точки скачка. Жалоба умножается на ноль и до первого слоя не доходит.
  • Бесконечно большой градиент Производная не определена только в самой точке скачка; во всех остальных точках она равна нулю.
  • Градиент с противоположным знаком Знак тут ни при чём: множитель обнуляется.

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

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