Шпаргалка формул нейросетей · Функции активации

Leaky ReLU: «протекающий» ReLU

ReLU с крошечной поправкой: слева от нуля функция не обнуляет сигнал, а умножает его на маленький α. Разбираем по косточкам, почему этого хватает, чтобы нейроны не умирали, откуда берётся инициализация Хе с множителем 1 + α², как сеть из таких нейронов режет пространство на плоские куски и как PReLU учит α сам.

Javharbek Abdulatipov · 30 мин чтения
$$\operatorname{LReLU}(x)=\max(\alpha x,\,x)=\begin{cases}x, & x>0\\ \alpha x, & x\le 0\end{cases}$$

Зачем он нужен

ReLU — самая популярная активация глубокого обучения: $\max(0,x)$ считается мгновенно, а справа от нуля градиент не затухает. Но у него есть слабое место. Слева от нуля ReLU не приглушает сигнал, а обнуляет его — и вместе с ним градиент. Нейрон, у которого вход отрицателен на всех примерах, выдаёт 0, получает нулевой градиент и больше никогда не учится. Это «умирающий ReLU» (dying ReLU).

Leaky ReLU — минимальная поправка: слева от нуля график не горизонтален, а слегка наклонён, $\alpha x$ с маленьким $\alpha$ (обычно от $0{,}01$ до $0{,}3$). Сигнал «протекает» сквозь закрытую дверь — отсюда и название (leaky — «протекающий»).

Где он встречается:

  • дискриминаторы GAN — в DCGAN (Рэдфорд и др., 2015) все слои дискриминатора используют Leaky ReLU с $\alpha=0{,}2$;
  • детекторы YOLO — сеть Darknet в YOLOv2 и YOLOv3 построена на Leaky ReLU с $\alpha=0{,}1$;
  • графовые сети — коэффициенты внимания в GAT считаются через Leaky ReLU с $\alpha=0{,}2$;
  • свёрточные сети с PReLU — вариант с обучаемым $\alpha$ (Хе и др., 2015) помог впервые опустить ошибку top-5 на ImageNet ниже оценки человеческой ошибки;
  • любая сеть, где ReLU «умирает» — замена занимает одну строку и почти ничего не стоит.
Главное за минуту

$\operatorname{LReLU}(x)=x$ при $x>0$ и $\alpha x$ при $x\le0$. Производная — ступенька: $1$ справа и $\alpha$ слева, поэтому градиент никогда не обнуляется целиком. Функция остаётся кусочно-линейной, монотонной и почти такой же дешёвой, как ReLU. При $\alpha=0$ это ReLU, при $\alpha=1$ — тождественная функция, при обучаемом $\alpha$ — PReLU.

Интуиция: дверь, которая не закрывается до конца

ReLU похож на дверь: положительный сигнал проходит целиком, отрицательный упирается в закрытую створку. Leaky ReLU оставляет щель — отрицательный сигнал проходит, но ослабленным в $1/\alpha$ раз. При $\alpha=0{,}1$ вход $-2$ превращается в $-0{,}2$.

Потяните точку по графику. Оранжевый «треугольник наклона» показывает производную: шаг на 1 вдоль оси $x$ меняет значение на $\alpha$ слева от нуля и на 1 справа. Ниже — сама производная: две горизонтальные ступеньки с разрывом в нуле. Подвигайте ползунок $\alpha$: от ReLU ($\alpha=0$) через «протекающий» вариант к прямой $y=x$ ($\alpha=1$).

Рисунок 1. Leaky ReLU и его производная при $\alpha=0{,}1$. В точке $x=-2$ значение равно $-0{,}2$, производная — $0{,}1$. Серый пунктир — ReLU, точечная линия — $y=x$. В нуле производной нет: слева она равна $\alpha$, справа — 1; подведите точку к нулю — в показаниях появится субдифференциал $[\alpha;\,1]$ и значение $\alpha$, которое берёт PyTorch.
Что заметить

Слева график не плоский, но очень пологий: при $\alpha=0{,}01$ вход $-100$ даёт всего $-1$. Вся нелинейность Leaky ReLU сосредоточена в одной точке — изломе в нуле, где наклон меняется с $\alpha$ на 1. Выразительная сила сети из таких нейронов берётся именно из этих изломов.

Формула по косточкам

Одну и ту же функцию полезно уметь записывать тремя способами — каждый пригодится в своём месте.

1. По случаям

$$\operatorname{LReLU}_\alpha(x)=\begin{cases}x, & x>0,\\ \alpha x, & x\le 0.\end{cases}$$
$x$
вход нейрона — обычно пре-активация $z=w^\top h+b$;
$\alpha$
наклон отрицательной части, гиперпараметр; обычно $0<\alpha<1$;
$\alpha x$
«протечка»: отрицательный вход не обнуляется, а сжимается в $1/\alpha$ раз.

В точке $x=0$ обе ветки дают ноль, поэтому неважно, к какой из них отнести ноль: функция непрерывна.

2. Через максимум

$$\operatorname{LReLU}_\alpha(x)=\max(\alpha x,\;x)\qquad(\alpha\le 1)$$

При $x>0$ и $\alpha\le1$ выполняется $x\ge\alpha x$, а при $x<0$ — наоборот, $\alpha x\ge x$. Значит, максимум сам выбирает нужную ветку. Но только при $\alpha\le1$: при $\alpha=2$ справа победит $2x$, и получится другая функция. Запись удобна в коде (np.maximum(alpha * x, x)), но про условие легко забыть.

3. Линейная часть плюс модуль

$$\operatorname{LReLU}_\alpha(x)=\frac{1+\alpha}{2}\,x+\frac{1-\alpha}{2}\,|x|$$

Проверка: при $x>0$ получаем $\frac{1+\alpha}{2}x+\frac{1-\alpha}{2}x=x$, при $x<0$ — $\frac{1+\alpha}{2}x-\frac{1-\alpha}{2}x=\alpha x$. Эта форма верна при любом $\alpha$ и объясняет главное: Leaky ReLU — это линейная функция плюс «немного модуля». Вся нелинейность сидит во втором слагаемом, и её доля $\frac{1-\alpha}{2}$ уменьшается с ростом $\alpha$. При $\alpha=1$ нелинейность исчезает полностью.

Рисунок 2. Слева — Leaky ReLU как верхняя огибающая двух прямых $y=x$ и $y=\alpha x$. Сдвиньте $\alpha$ выше 1: огибающая (чёрный пунктир) отрывается от настоящего Leaky ReLU (синяя линия). Справа — разложение на линейную часть и модуль; при $\alpha=0{,}2$ коэффициенты равны $0{,}6$ и $0{,}4$.
$x$$\alpha=0{,}01$$\alpha=0{,}2$$\operatorname{LReLU}'(x)$
−5−0,05−1$\alpha$
−2−0,02−0,4$\alpha$
−0,5−0,005−0,1$\alpha$
0,50,50,5$1$
222$1$
555$1$

Справа от нуля все варианты совпадают с ReLU; они различаются только тем, сколько отрицательного сигнала «протекает».

Свойства

  • Область определения и значений — вся числовая прямая $\mathbb R$ (при $\alpha>0$). У ReLU значения только $[0;\,+\infty)$.
  • Непрерывность и кусочная линейность: две прямые, склеенные в нуле. Функция дифференцируема везде, кроме $x=0$.
  • Строгая монотонность при $\alpha>0$: больший вход даёт больший выход. Поэтому функция обратима: $\operatorname{LReLU}_\alpha^{-1}(y)=y$ при $y>0$ и $y/\alpha$ при $y\le0$, то есть $\operatorname{LReLU}_{1/\alpha}$. У ReLU обратной нет: все отрицательные входы склеены в ноль.
  • Положительная однородность: $\operatorname{LReLU}(cx)=c\,\operatorname{LReLU}(x)$ при $c\ge0$. Масштаб входа просто переносится на выход — отсюда простые формулы инициализации.
  • Липшицевость с константой $\max(1,|\alpha|)$, то есть 1 при $\alpha\le1$: $|\operatorname{LReLU}(a)-\operatorname{LReLU}(b)|\le|a-b|$.
  • Неограниченность сверху и снизу, но вниз функция растёт в $1/\alpha$ раз медленнее.
  • Частные случаи: $\alpha=0$ — ReLU, $\alpha=1$ — тождественная функция, $\alpha=-1$ — модуль $|x|$ (уже не монотонный).

Среднее и разброс выхода

Пусть вход нейрона $z\sim N(0,1)$. Тогда

$$\mathbb E\bigl[\operatorname{LReLU}(z)\bigr]=\frac{1-\alpha}{\sqrt{2\pi}},\qquad \mathbb E\bigl[\operatorname{LReLU}(z)^2\bigr]=\frac{1+\alpha^2}{2}$$

При $\alpha=0{,}01$ среднее равно $0{,}395$ (у ReLU — $0{,}399$), при $\alpha=0{,}2$ — $0{,}319$. Чем больше $\alpha$, тем ближе выходы к нулевому среднему; это немного облегчает обучение следующего слоя. Второй момент $\frac{1+\alpha^2}{2}$ понадобится в разделе об инициализации.

Откуда эти формулы

Для $z\sim N(0,1)$ известно, что $\mathbb E[z\,\mathbf 1_{z>0}]=\varphi(0)=1/\sqrt{2\pi}$, а по симметрии $\mathbb E[z\,\mathbf 1_{z<0}]=-1/\sqrt{2\pi}$. Поэтому

$$\mathbb E[\operatorname{LReLU}(z)]=\mathbb E[z\mathbf 1_{z>0}]+\alpha\,\mathbb E[z\mathbf 1_{z<0}]=\frac{1}{\sqrt{2\pi}}-\frac{\alpha}{\sqrt{2\pi}}$$

Аналогично $\mathbb E[z^2\mathbf 1_{z>0}]=\mathbb E[z^2\mathbf 1_{z<0}]=\tfrac12$, откуда $\mathbb E[\operatorname{LReLU}(z)^2]=\tfrac12+\tfrac{\alpha^2}{2}$. Вторая формула верна для любого симметричного распределения с единичной дисперсией, первая — только для нормального.

Производная: ступенька вместо обрыва

На каждой ветке функция линейна, поэтому производная — просто наклон ветки:

$$\operatorname{LReLU}'_\alpha(x)=\begin{cases}1, & x>0,\\ \alpha, & x<0.\end{cases}$$
Вывод по определению

При $x>0$ для достаточно малых $h$ точка $x+h$ тоже положительна, и $\frac{\operatorname{LReLU}(x+h)-\operatorname{LReLU}(x)}{h}=\frac{(x+h)-x}{h}=1$. При $x<0$ так же получаем $\frac{\alpha(x+h)-\alpha x}{h}=\alpha$.

В нуле односторонние пределы разные:

$$\lim_{h\to0^+}\frac{\operatorname{LReLU}(h)-0}{h}=1,\qquad \lim_{h\to0^-}\frac{\alpha h-0}{h}=\alpha$$

При $\alpha\ne1$ они не совпадают, поэтому производной в нуле нет — это точка излома.

Что делать с нулём на практике? В точке излома есть субградиент (subgradient): при $0\le\alpha\le1$ любое число $g\in[\alpha;\,1]$ задаёт прямую $y=gx$, которая лежит не выше графика. Библиотеки выбирают одно значение по соглашению — в PyTorch при $x=0$ берётся $\alpha$. Точно в ноль вход попадает редко, так что выбор почти ни на что не влияет.

Почему ступенька лучше обрыва

По цепному правилу градиент по весу $w_j$ нейрона $a=\operatorname{LReLU}(z)$, $z=\sum_j w_jx_j+b$, равен

$$\frac{\partial L}{\partial w_j}=\frac{\partial L}{\partial a}\cdot\operatorname{LReLU}'(z)\cdot x_j$$

У ReLU средний множитель равен 0 при $z<0$, у Leaky ReLU — $\alpha$. Слева градиент в $1/\alpha$ раз слабее, но не равен нулю: нейрон, «застрявший» в отрицательной зоне, продолжает получать сигнал об ошибке.

Производная по α: шаг к PReLU

Если сделать $\alpha$ обучаемым параметром, понадобится производная по нему. Она тоже простая:

$$\frac{\partial\operatorname{LReLU}_\alpha(x)}{\partial\alpha}=\begin{cases}0, & x>0,\\ x, & x\le 0\end{cases}\;=\;\min(0,\,x)$$

Наклон $\alpha$ учится только на примерах, попавших в левую ветку, — так устроен PReLU (раздел 9). Вторая производная по $x$ равна нулю везде, кроме нуля: вся кривизна сосредоточена в изломе, и в смысле обобщённых функций $\operatorname{LReLU}''(x)=(1-\alpha)\,\delta(x)$.

Умирающий ReLU и как Leaky его лечит

Как умирает нейрон. Пусть после неудачного большого шага (слишком большой темп обучения, выброс в данных, неудачная инициализация) сдвиг $b$ нейрона стал сильно отрицательным. Тогда $z=w^\top x+b<0$ на всех примерах, ReLU выдаёт 0, производная $\operatorname{ReLU}'(z)=0$ — и градиенты по $w$, $b$ и по выходному весу $v$ обнуляются одновременно. Градиентный спуск больше не сдвинет этот нейрон: он мёртв (строго навсегда — для нейрона первого слоя при обычном SGD; в глубоких слоях вход нейрона меняется вместе с предыдущими слоями, и изредка нейроны оживают). В конспектах курса CS231n отмечают, что при слишком большом темпе обучения мёртвой может оказаться до 40% сети.

Ниже — самый чистый эксперимент. Один нейрон $f(x)=v\cdot\operatorname{act}(wx+b)$ должен выучить «шарнир» $y=1{,}5\max(0,\,x-1)$ по 41 точке отрезка $[-3;\,3]$. Старт: $w=1$, $b=-4$, $v=1$ — излом в точке $x=4$, за пределами данных, поэтому на всех примерах $z<0$. Обучение — градиентный спуск по MSE с шагом $0{,}1$.

Рисунок 3. Нажмите «Пуск». Нейрон ReLU (чёрный пунктир) заморожен: все его градиенты равны нулю, и ошибка навсегда остаётся $1{,}09$. Нейрон Leaky ReLU с $\alpha=0{,}1$ получает слабый градиент, его прямая наклоняется и сдвигается, и на 24-м шаге излом входит в область данных. Через 1500 шагов ошибка равна $0{,}0549$. При $\alpha=0{,}01$ оживление занимает 135 шагов, зато итоговая ошибка — $0{,}00082$.

Обратите внимание на компромисс. Большой $\alpha$ быстро возвращает нейрон к жизни, но левая ветка остаётся наклонной: при $\alpha=0{,}1$ итоговая модель слева имеет наклон $\alpha v w\approx0{,}116$ вместо нуля, отсюда остаточная ошибка. Маленький $\alpha$ почти не искажает форму функции, но оживляет медленнее.

Leaky — не гарантия

Ненулевой градиент не означает, что нейрон обязательно вернётся: он может так и остаться на левой ветке, работая как линейная функция $\alpha(w^\top x+b)$. Leaky ReLU гарантирует другое — нейрон никогда не замерзает намертво и продолжает учиться. Против самой причины гибели помогают умеренный темп обучения, разогрев (warmup), нормализация и правильная инициализация.

Сеть из Leaky ReLU: кусочно-линейный рельеф

В сети с двумя входами каждый нейрон $\operatorname{LReLU}(w_k^\top x+b_k)$ «сгибает» плоскость вдоль прямой $w_k^\top x+b_k=0$: по одну сторону от неё вклад нейрона в $1/\alpha$ раз положе, чем по другую. Сумма нейронов $f(x)=\sum_k v_k\operatorname{LReLU}(w_k^\top x+b_k)$ — многогранная поверхность: внутри каждой области, где набор включённых нейронов не меняется, она плоская, а на прямых-изломах меняет наклон.

Рисунок 4. Сеть из шести нейронов Leaky ReLU. Слева — поверхность $f(x_1,x_2)$ в 3D (её можно вращать), справа — вид сверху с шестью прямыми изломов. Они делят квадрат $[-3;\,3]^2$ на 19 линейных областей. Тяните оранжевую точку: в центре, в точке $(0{,}2;\,-0{,}3)$, выключены все шесть нейронов, но градиент не нулевой: $|\nabla f|=0{,}100$. Поставьте $\alpha=0$: центральная область станет плоской — это 5% квадрата, где у сети из ReLU градиент по входу равен нулю. При $\alpha=1$ вся сеть превращается в одну плоскость.

Число областей не зависит от $\alpha$ (пока $\alpha\ne1$): его задают только прямые изломов. Зато от $\alpha$ зависит, что происходит там, где все нейроны выключены. У ReLU там плато с нулевым градиентом, и примеры, попавшие на него, ничего не сообщают сети. У Leaky ReLU плато наклонено, и градиент там, как правило, не нулевой.

Сколько областей может быть

$n$ прямых общего положения делят плоскость не более чем на $1+n+\binom n2$ частей: для $n=6$ это 22. В квадрате на рисунке видно 19 из них. У глубоких сетей число линейных областей может расти с глубиной экспоненциально — это одно из объяснений их выразительной силы.

Глубокие сети: инициализация Хе для Leaky ReLU

В глубокой сети сигнал проходит через десятки слоёв $z_{l+1}=W_{l+1}\operatorname{LReLU}(z_l)$. Если на каждом слое дисперсия умножается на число, хоть немного отличное от 1, через 50 слоёв это превратится во взрыв или исчезновение сигнала. Посчитаем этот множитель.

Вывод множителя

Пусть веса $W_{ij}$ независимы, $\mathbb E W_{ij}=0$, $\operatorname{Var}W_{ij}=s^2$, а входы $z_l$ симметричны относительно нуля. Для одного выхода $z_{l+1,i}=\sum_{j=1}^{n}W_{ij}h_j$, где $h_j=\operatorname{LReLU}(z_{l,j})$:

$$\operatorname{Var}z_{l+1}=n\,s^2\,\mathbb E[h^2]=n\,s^2\,\frac{1+\alpha^2}{2}\operatorname{Var}z_l$$

Последнее равенство — второй момент из раздела о свойствах: половина $z_l^2$ приходит с положительной ветки целиком, половина — с отрицательной, умноженная на $\alpha^2$. Чтобы дисперсия сохранялась, множитель должен быть равен 1:

$$s^2=\frac{2}{(1+\alpha^2)\,n_{\text{in}}}\qquad\Longleftrightarrow\qquad g=\sqrt n\,s=\sqrt{\frac{2}{1+\alpha^2}}$$

На обратном проходе градиент умножается на $W^\top$ и на $\operatorname{LReLU}'(z)$, а $\mathbb E[\operatorname{LReLU}'(z)^2]=\frac{1+\alpha^2}{2}$ — тот же множитель. Поэтому одна и та же инициализация сохраняет и прямой сигнал, и градиенты.

$$\operatorname{Var}z_{l+1}=\frac{g^2(1+\alpha^2)}{2}\,\operatorname{Var}z_l,\qquad g_{\text{He}}=\sqrt{\frac{2}{1+\alpha^2}}$$

При $\alpha=0$ получается знаменитое $g=\sqrt2$ инициализации Хе (Kaiming) для ReLU. Для Leaky ReLU коэффициент чуть меньше: $1{,}414$ при $\alpha=0{,}01$, $1{,}387$ при $\alpha=0{,}2$, $1{,}355$ при $\alpha=0{,}3$.

Рисунок 5. RMS пре-активаций на каждом слое случайной сети ширины 256 (вертикальная шкала логарифмическая). По умолчанию $\alpha=0{,}3$, а веса инициализированы «как для ReLU», $g=\sqrt2$: множитель дисперсии равен $1{,}09$ за слой, и к 50-му слою RMS вырастает до $11{,}6$ (теория — $11{,}7$). С правильным $g=\sqrt{2/(1+\alpha^2)}$ множитель равен 1, и на 50-м слое RMS равен $1{,}34$ (теория — $1{,}35$). При $g=1$ множитель $0{,}545$, и сигнал гаснет до $3{,}45\cdot10^{-7}$.
В PyTorch

Ровно это делает nn.init.kaiming_normal_(w, a=alpha, nonlinearity='leaky_relu'): стандартное отклонение $\sqrt{2/((1+a^2)\,n_{\text{in}})}$. По умолчанию там a=0, то есть инициализация для обычного ReLU, — для Leaky ReLU параметр a нужно передать явно.

PReLU, RReLU и вся семья

Как выбрать $\alpha$? Есть три ответа.

  • Фиксированный $\alpha$ — классический Leaky ReLU (Маас, Ханнун, Ын, 2013, $\alpha=0{,}01$). Сегодня часто берут $0{,}1$–$0{,}3$: в сравнении Сюй и др. (2015) «сильно протекающий» вариант с $\alpha=1/5{,}5\approx0{,}18$ работал лучше, чем $0{,}01$.
  • Обучаемый $\alpha$ — PReLU (Parametric ReLU, Хе и др., 2015). $\alpha$ становится параметром — один на слой или по одному на канал — и учится градиентным спуском вместе с весами. Начальное значение в PyTorch — $0{,}25$.
  • Случайный $\alpha$ — RReLU (Randomized ReLU): при обучении $\alpha$ заново берётся для каждого элемента входа из равномерного распределения $U(1/8;\,1/3)$ (границы по умолчанию в PyTorch), при выводе — среднее $\frac{1/8+1/3}{2}=\frac{11}{48}\approx0{,}229$. Шум действует как регуляризация.

У PReLU градиент по $\alpha$ — это $\min(0,\,z)$ из раздела о производной: наклон учится только на отрицательных входах. Посмотрим, как градиентный спуск находит сразу и вес, и наклон.

Рисунок 6. Модель $\operatorname{PReLU}_\alpha(wx)$ с двумя параметрами учится на 31 точке, сгенерированной «учителем» $w^*=1{,}5$, $\alpha^*=0{,}2$ с шумом. Справа — поверхность ошибки $L(w,\alpha)$ (чем светлее, тем меньше). Из старта $(0{,}5;\,1{,}3)$ градиентный спуск с шагом $0{,}05$ за 87 шагов приходит в $w=1{,}521$, $\alpha=0{,}209$ с ошибкой $0{,}0158$ — это минимум для этих зашумлённых данных (у самого учителя ошибка $0{,}0170$). Перетащите старт в другое место.

PReLU добавляет всего по одному параметру на канал, но в работе Хе и др. он вместе с новой инициализацией позволил обучить очень глубокие свёрточные сети и получить ошибку top-5 $4{,}94\%$ на ImageNet — ниже оценки человеческой ошибки $5{,}1\%$. Авторы отмечают, что к $\alpha$ не стоит применять затухание весов (weight decay): оно тянет $\alpha$ к нулю, то есть обратно к ReLU.

Гладкие родственники

Излом в нуле можно сгладить. ELU заменяет левую прямую экспонентой $\alpha(e^x-1)$, которая насыщается на уровне $-\alpha$ (здесь $\alpha$ — свой параметр ELU, обычно 1). SELU добавляет масштаб: $\lambda\approx1{,}0507$ и $\alpha\approx1{,}6733$ подобраны так, чтобы в полносвязной сети с инициализацией LeCun активации сами поддерживали нулевое среднее и единичную дисперсию. GELU и SiLU — гладкие и даже немонотонные функции, которые сегодня стоят в трансформерах.

Рисунок 7. Leaky ReLU с $\alpha=0{,}1$ рядом с родственниками. Наведите курсор: при $x=-2$ Leaky ReLU даёт $-0{,}2$, ELU — $-0{,}865$, SELU — $-1{,}520$, GELU — $-0{,}046$, SiLU — $-0{,}238$. Переключитесь на производные: у Leaky ReLU и SELU это ступенька с разрывом в нуле (у SELU слева $\lambda\alpha\approx1{,}758$, справа $\lambda\approx1{,}051$), у ELU, GELU и SiLU — непрерывная кривая.
ФункцияПри $x\le0$Производная слеваОсобенность
ReLU$0$$0$нулевой градиент, «мёртвые» нейроны
Leaky ReLU$\alpha x$$\alpha$фиксированный наклон, обычно $0{,}01$–$0{,}3$
PReLU$\alpha x$, $\alpha$ обучается$\alpha$+1 параметр на слой или канал
RReLU$\alpha x$, $\alpha\sim U(\tfrac18;\,\tfrac13)$$\alpha$шум как регуляризация
ELU$\alpha(e^{x}-1)$$\alpha e^{x}$производная непрерывна при $\alpha=1$, насыщение на $-\alpha$
SELU$\lambda\alpha(e^{x}-1)$$\lambda\alpha e^{x}$самонормализация, $\lambda\approx1{,}0507$

В коде

В NumPy Leaky ReLU — одна строка. Надёжнее писать np.where, чем np.maximum(alpha * x, x): вторая запись тихо ломается при $\alpha>1$.

pythonimport numpy as np

def leaky_relu(x, alpha=0.01):
    # where, а не maximum(alpha * x, x): эта запись верна при любом alpha
    return np.where(x > 0, x, alpha * x)

def leaky_relu_grad(x, alpha=0.01):
    return np.where(x > 0, 1.0, alpha)      # в нуле берём alpha, как PyTorch

def he_std(n_in, alpha=0.01):
    # инициализация Хе для Leaky ReLU: Var w = 2 / ((1 + alpha²) · n_in)
    return np.sqrt(2.0 / ((1.0 + alpha**2) * n_in))

x = np.array([-3.0, -0.5, 0.0, 2.0])
print(leaky_relu(x))        # [-0.03  -0.005  0.     2.   ]
print(leaky_relu_grad(x))   # [0.01 0.01 0.01 1.  ]
print(he_std(256, 0.2))     # 0.08667190566019205
pythonimport torch
import torch.nn as nn

act = nn.LeakyReLU(negative_slope=0.01)   # 0.01 — значение по умолчанию
x = torch.tensor([-3.0, 0.0, 2.0], requires_grad=True)
act(x).sum().backward()
print(x.grad)                    # tensor([0.0100, 0.0100, 1.0000]) — в нуле α

prelu = nn.PReLU(num_parameters=1, init=0.25)   # α — обучаемый параметр
print(prelu(torch.tensor([-2.0, 3.0])).detach())  # tensor([-0.5000,  3.0000])

lin = nn.Linear(256, 256)
# std = √(2 / ((1 + a²) · 256)); по умолчанию a=0, то есть «как для ReLU»
nn.init.kaiming_normal_(lin.weight, a=0.2, nonlinearity="leaky_relu")
print(nn.init.calculate_gain("leaky_relu", 0.2))  # 1.3867504905630728
Значения по умолчанию в библиотеках разные

PyTorch nn.LeakyReLU: negative_slope=0.01. TensorFlow tf.nn.leaky_relu: alpha=0.2. Keras layers.LeakyReLU: $0{,}3$. Одна и та же «Leaky ReLU» в трёх фреймворках — три разные функции. При переносе модели указывайте $\alpha$ явно.

С численной точки зрения Leaky ReLU безопасен: ни экспонент, ни деления, ни переполнений. Единственная тонкость — inplace=True в PyTorch: он экономит память, но перезаписывает вход, который может понадобиться другим операциям графа.

Частые ошибки

  1. Запись max(alpha * x, x) при $\alpha>1$. Формула верна только при $\alpha\le1$; при больших $\alpha$ получается другая функция. Безопасная запись — where(x > 0, x, alpha * x).
  2. Слишком большой $\alpha$. При $\alpha\to1$ доля нелинейности $\frac{1-\alpha}{2}$ стремится к нулю, функция становится почти линейной, и глубокая сеть теряет выразительность. Разумный диапазон — от $0{,}01$ до $0{,}3$.
  3. Инициализация «как для ReLU» без поправки на $\alpha$. Множитель дисперсии $1+\alpha^2$ за слой: при $\alpha=0{,}3$ RMS сигнала с 1-го по 50-й слой вырастает примерно в $1{,}09^{24{,}5}\approx8{,}3$ раза (рисунок 5). Передавайте $\alpha$ в kaiming_normal_(..., a=alpha).
  4. Надежда, что Leaky ReLU сам вылечит нестабильное обучение. Он убирает нулевой градиент, но не причину: слишком большой темп обучения по-прежнему опасен.
  5. Затухание весов на $\alpha$ у PReLU. Оно тянет $\alpha$ к нулю, и PReLU превращается в ReLU. Исключайте $\alpha$ из группы параметров с weight decay.
  6. Разные значения по умолчанию в PyTorch ($0{,}01$), TensorFlow ($0{,}2$) и Keras ($0{,}3$): при переносе модели между фреймворками результат молча меняется.
  • ReLU: частный случай $\alpha=0$; там же — подробнее об «умирающем ReLU».
  • SiLU / Swish и GELU: гладкие активации, у которых слева тоже проходит небольшой отрицательный сигнал, но затем он гаснет.
  • Сигмоида и tanh: насыщающиеся активации; у Leaky ReLU насыщения нет вовсе, а значит, нет и затухания градиента из-за насыщения.
  • MSE: функция потерь в экспериментах на рисунках 3 и 6.
  • SGD и Adam: слишком большой шаг оптимизатора — главная причина гибели ReLU-нейронов.

Итоги

1) $\operatorname{LReLU}_\alpha(x)=x$ при $x>0$ и $\alpha x$ при $x\le0$; это $\max(\alpha x,x)$ при $\alpha\le1$ и $\frac{1+\alpha}{2}x+\frac{1-\alpha}{2}|x|$ при любом $\alpha$. 2) Производная — ступенька из $\alpha$ и $1$: градиент не обнуляется, нейрон не замерзает. 3) Компромисс: больший $\alpha$ быстрее оживляет нейроны, но приближает функцию к линейной. 4) Сеть из Leaky ReLU — кусочно-линейная функция без плоских «мёртвых» плато. 5) Инициализация: $\operatorname{Var}w=\frac{2}{(1+\alpha^2)\,n_{\text{in}}}$. 6) PReLU учит $\alpha$ по градиенту $\min(0,z)$.

Проверь себя

1. Чему равно $\operatorname{LReLU}(-5)$ при $\alpha=0{,}2$?
2. Чему равна производная Leaky ReLU при $x<0$?
3. При каких $\alpha$ верно $\operatorname{LReLU}_\alpha(x)=\max(\alpha x,x)$?
4. Сеть с Leaky ReLU ($\alpha=0{,}3$) инициализирована «как для ReLU», $g=\sqrt2$. Каков множитель дисперсии за слой?
5. Нейрон ReLU получает $z<0$ на всех примерах. Что верно?