Зачем он нужен
Без нелинейности нейросеть бесполезна: композиция линейных слоёв — снова линейная функция, сколько слоёв ни ставь. Нужна функция, которая «ломает» линейность, но при этом дёшево считается и не душит градиент. ReLU (rectified linear unit, «выпрямленная линейная функция») делает минимально возможное: положительное пропускает как есть, отрицательное заменяет нулём.
Где он встречается:
- свёрточные сети — AlexNet, VGG, ResNet: ReLU — основная нелинейность после свёрток;
- полносвязные сети и табличные модели — выбор по умолчанию для скрытых слоёв;
- исходный Transformer (2017) — блок FFN: $\max(0,\,xW_1+b_1)W_2+b_2$; современные LLM перешли на его гладкие родственники GELU и SiLU (часто в составе вентильного блока SwiGLU);
- мобильные сети — ReLU6 $=\min(\max(0,x),\,6)$ в MobileNet удобна для вычислений с малой разрядностью;
- внутри других формул — $\max(0,\cdot)$ это и hinge-потеря SVM, и triplet loss, и положительная часть числа $x^+$.
$\operatorname{ReLU}(x)=\max(0,x)$: ноль слева, прямая $y=x$ справа. Производная — ступенька: 0 при $x<0$ и 1 при $x>0$; в нуле производной нет, библиотеки берут 0. Справа градиент проходит без ослабления — поэтому глубокие сети с ReLU учатся быстро. Плата — «мёртвые» нейроны, у которых вход всегда отрицателен.
Интуиция: выпрямитель
Название пришло из электроники: диод-выпрямитель пропускает ток в одну сторону и не пропускает в другую. Нейрон с ReLU — это датчик: пока признак ниже порога, он молчит; как только порог пройден, отвечает пропорционально тому, насколько сильно.
Потяните точку. Справа от нуля касательная совпадает с самой функцией (наклон 1), слева лежит на оси (наклон 0). В нуле единственной касательной нет: любая прямая с наклоном от 0 до 1 касается графика снизу — это опорные прямые.
У ReLU нет насыщения справа: при $x=100$ производная та же 1, что и при $x=0{,}1$. У сигмоиды и tanh при $|x|=5$ производная уже меньше $0{,}01$. Зато слева ReLU «насыщен» полностью: производная ровно 0.
Формула по косточкам
Одну и ту же функцию полезно узнавать в разных записях — каждая подсвечивает своё свойство:
- $\max(0,x)$
- сравнение с нулём — одна операция, без экспонент и делений;
- $\frac{x+|x|}{2}$
- при $x>0$ слагаемые равны и дают $x$, при $x<0$ они взаимно уничтожаются;
- $x\cdot\mathbb 1[x>0]$
- вентиль: вход умножается на 0 или 1 в зависимости от знака. Для каждого примера сеть с ReLU — это линейная сеть, в которой часть нейронов выключена.
| $x$ | $\operatorname{ReLU}(x)$ | $\operatorname{ReLU}'(x)$ |
|---|---|---|
| −3 | 0 | 0 |
| −1 | 0 | 0 |
| −0,5 | 0 | 0 |
| 0 | 0 | [0; 1] |
| 0,5 | 0,5 | 1 |
| 1 | 1 | 1 |
| 2,5 | 2,5 | 1 |
Из изломов — любая ломаная
Нейрон $v\cdot\operatorname{ReLU}(x-c)$ — это «шарнир» (hinge): ноль до точки $c$, затем прямая с наклоном $v$. Складывая шарниры с разными $c$, получаем ломаную: в каждой точке $c_k$ наклон меняется ровно на $v_k$. Например, $\operatorname{ReLU}(x+1)-2\operatorname{ReLU}(x)+\operatorname{ReLU}(x-1)$ — «шапочка» высотой 1.
Это и есть главный секрет ReLU-сетей: любая непрерывная кусочно-линейная функция на прямой с $m$ изломами — это $a+bx$ плюс $m$ шарниров, то есть сеть с одним скрытым слоем из $m$ нейронов (плюс выходной сдвиг $a$ и слагаемое $bx$, которое тоже можно выразить двумя нейронами: $x=\operatorname{ReLU}(x)-\operatorname{ReLU}(-x)$). А ломаными можно сколь угодно точно приблизить любую непрерывную функцию на отрезке.
Свойства
- Область значений — $[0;\,+\infty)$: сверху не ограничена, в отличие от сигмоиды и tanh.
- Кусочная линейность: два линейных куска, один излом в нуле.
- Непрерывность и липшицевость с константой 1: $|\operatorname{ReLU}(a)-\operatorname{ReLU}(b)|\le|a-b|$.
- Выпуклость: график лежит не выше любой хорды — максимум двух линейных функций всегда выпукл.
- Положительная однородность: $\operatorname{ReLU}(\alpha x)=\alpha\operatorname{ReLU}(x)$ при $\alpha\ge0$. Масштаб можно переносить между слоями: умножив веса слоя на $\alpha>0$, а следующего — на $1/\alpha$, получим ту же сеть.
- Идемпотентность: $\operatorname{ReLU}(\operatorname{ReLU}(x))=\operatorname{ReLU}(x)$.
- Разложение числа: $x=\operatorname{ReLU}(x)-\operatorname{ReLU}(-x)$ и $|x|=\operatorname{ReLU}(x)+\operatorname{ReLU}(-x)$.
- Разреженность (sparsity): если входы нейронов симметричны относительно нуля, примерно половина выходов — точные нули.
Доказательства: выпуклость и однородность
Выпуклость. Для $t\in[0;1]$ и любых $a,b$: $\max(0,\,ta+(1-t)b)\le\max\bigl(0,\,t\max(0,a)+(1-t)\max(0,b)\bigr)=t\max(0,a)+(1-t)\max(0,b)$, потому что $a\le\max(0,a)$, $b\le\max(0,b)$, а правая часть неотрицательна.
Однородность. При $\alpha>0$ знак $\alpha x$ совпадает со знаком $x$, поэтому $\max(0,\alpha x)=\alpha\max(0,x)$; при $\alpha=0$ обе части равны 0. При $\alpha<0$ равенство нарушается: $\operatorname{ReLU}(-x)\ne-\operatorname{ReLU}(x)$ — функция не нечётна.
Производная, субградиент и гладкие родственники
Почему в нуле производной нет
Производная — предел разностного отношения. Справа и слева от нуля он разный:
Односторонние производные не совпадают, значит, обычной производной нет. Для выпуклых функций есть замена — субградиент: число $g$, для которого $f(y)\ge f(x)+g(y-x)$ при всех $y$, то есть прямая с наклоном $g$ лежит под графиком. В нуле так ведут себя все $g\in[0;1]$: это множество называют субдифференциалом $\partial\operatorname{ReLU}(0)$.
Почему это почти не мешает обучению: для непрерывных данных вход нейрона ровно равен нулю с вероятностью 0. В арифметике с плавающей точкой точные нули всё же случаются, но так редко, что выбор значения из $[0;1]$ почти ни на что не влияет (в 16-битной арифметике нули встречаются заметно чаще, и выбор $\operatorname{ReLU}'(0)$ иногда сказывается на обучении). Библиотеки по соглашению берут 0.
Вторая производная равна нулю везде, кроме нуля (в смысле обобщённых функций $\operatorname{ReLU}''=\delta(x)$). Поэтому внутри каждой линейной области сеть из ReLU — аффинная функция входа, а её градиент по входу кусочно-постоянен.
Softplus: сглаженный ReLU
Если излом мешает (например, нужна гладкая функция для оптимизации второго порядка или физической модели), его можно скруглить:
Разность $\operatorname{softplus}_\beta(x)-\operatorname{ReLU}(x)=\frac1\beta\ln\bigl(1+e^{-\beta|x|}\bigr)$ максимальна в нуле и равна $\frac{\ln2}{\beta}$; при $\beta\to\infty$ softplus стремится к ReLU, а производная-сигмоида — к ступеньке. В нуле она всегда равна $\sigma(0)=0{,}5$ — середине субдифференциала $[0;1]$.
ReLU-сеть в пространстве: линейные области
Нейрон первого слоя с двумя входами выключен по одну сторону прямой $w^\top x+b=0$ и линеен по другую. Каждая такая прямая — линия сгиба. $H$ нейронов разрезают плоскость на области, и в каждой области набор включённых нейронов (паттерн активаций) постоянен, а значит, сеть — обычная аффинная функция. Поверхность выхода — многогранник, склеенный из плоских граней.
$H$ прямых общего положения делят плоскость максимум на $1+H+\binom H2$ частей — число областей одного слоя растёт полиномиально. Глубина работает иначе: каждый следующий слой «складывает» уже разрезанное пространство, и число областей может расти экспоненциально с числом слоёв (Монтуфар и др., 2014). Это одно из объяснений, почему глубокие сети выразительнее широких при том же числе нейронов.
Сеть с одним скрытым слоем ReLU и достаточным числом нейронов приближает любую непрерывную функцию на ограниченном замкнутом множестве с любой точностью (Лешно и др., 1993: подходит любая непрерывная активация, не являющаяся многочленом). Для ReLU это видно буквально: ломаные — из шарниров, многогранные поверхности — из складок.
ReLU в обучении: сеть рисует ломаную
Обучим один скрытый слой $\hat y(x)=\sum_{k=1}^{H}v_k\operatorname{ReLU}(w_kx+b_k)+c$ на точках синусоиды. Каждый нейрон — шарнир с изломом в $x=-b_k/w_k$; градиентный спуск сдвигает изломы туда, где кривая изгибается, и подбирает наклоны.
Градиент по параметрам нейрона приходит только от тех точек, где нейрон включён. Если таких точек нет совсем, нейрон перестаёт учиться — это и есть «умирание».
Сеть из ReLU не умеет рисовать гладкое — только ломаные. Из 6 нейронов к шагу 1500 живы 5, и их изломы стоят примерно в точках $-2{,}5$, $-1{,}2$, $-0{,}4$, $0{,}3$ и $1{,}0$: у вершин синусоиды (около $\pm1$ и у левого края) и по краям её почти прямого участка вокруг нуля. Лишние нейроны не обязательно помогают: при 12 нейронах часть умирает, а часть дублирует соседей (изломы в $-1{,}2$ и $-1{,}0$, в $-0{,}25$ и $-0{,}09$).
Умирающий ReLU
Нейрон «мёртв», если на всех обучающих примерах $w^\top x+b\le0$. Тогда его выход всегда 0, градиенты по $w$ и $b$ всегда 0 (см. формулу выше), и градиентный шаг сам по себе его не оживит. Для нейрона первого слоя, чьи входы — неизменные данные, это навсегда (при обычном SGD). В глубоких слоях вход нейрона меняется вместе с предыдущими слоями, а инерция momentum и Adam ещё какое-то время двигает параметры, поэтому нейроны изредка оживают — но рассчитывать на это нельзя.
Как это происходит: один большой шаг градиентного спуска сильно уменьшает сдвиг $b$ или поворачивает $w$ так, что гиперплоскость нейрона уходит за пределы облака данных. Чем больше шаг обучения, тем чаще это случается.
Как лечить:
- умеренный шаг обучения, разогрев (warm-up) и обрезка градиента;
- нормализация и адаптивные оптимизаторы: BatchNorm перед активацией центрирует вход каждого нейрона на батче, а Adam ограничивает шаг каждого параметра величиной порядка $\eta$, так что один огромный градиент не уносит сдвиг далеко (риск это снижает, но не исключает);
- активации с ненулевым наклоном слева — Leaky ReLU, PReLU, ELU, GELU, SiLU: градиент слева не равен нулю, и нейрон может вернуться;
- аккуратная инициализация: сдвиги 0 (иногда небольшой положительный), веса по Хе. Сильно отрицательные сдвиги убивают нейроны ещё до обучения.
Инициализация Хе: откуда двойка
Пусть $z=\sum_{j=1}^{n}w_jh_j$, веса независимы, $\mathbb Ew_j=0$, $\operatorname{Var}w_j=c/n$. Тогда $\operatorname{Var}z=c\cdot q$, где $q=\mathbb E[h^2]$ — средний квадрат входов. Если $z$ симметрична относительно нуля, ReLU обнуляет ровно половину её распределения, и
При $c=1$ (как для tanh) сигнал вдвое слабеет на каждом слое, при $c=3$ — растёт в полтора раза. Сохраняет масштаб только $c=2$: это инициализация Хе (He et al., 2015), $\operatorname{Var}w=2/n_\text{in}$. Обратный проход устроен так же (с $n_\text{out}$ вместо $n_\text{in}$; при одинаковой ширине слоёв это одно и то же), поэтому градиенты тоже не затухают и не взрываются.
Идея выпрямителя давняя: её использовал ещё Фукусима (1969). В глубокое обучение ReLU вошёл в 2010–2011 годах (Наир и Хинтон; Глоро, Борд и Бенжио), а в статье об AlexNet (2012) четырёхслойная свёрточная сеть с ReLU дошла до ошибки 25% на обучающей выборке CIFAR-10 в 6 раз быстрее, чем такая же сеть с tanh. В 2015 году Хе и соавторы вывели инициализацию $2/n$ и показали, что с ней с нуля обучается даже 30-слойная ReLU-сеть, которая с инициализацией Ксавье не учится.
В коде
ReLU не переполняется и не теряет точность: сравнение с нулём точно в любой арифметике. Внимание стоит уделить другому: соглашению в нуле, мёртвым нейронам и инициализации.
pythonimport numpy as np
def relu(x):
return np.maximum(0.0, x)
def relu_grad(x):
# субградиент: в точке 0 берём 0, как PyTorch и TensorFlow
return (x > 0).astype(float)
x = np.array([-3.0, 0.0, 2.5])
print(relu(x), relu_grad(x)) # [0. 0. 2.5] [0. 0. 1.]
# «Мёртвые» нейроны: ни одного положительного входа на всём наборе данных
rng = np.random.default_rng(0)
X = rng.normal(size=(1000, 20))
W = rng.normal(size=(20, 64)) * np.sqrt(2 / 20) # инициализация Хе
for b0 in (0.0, -5.0):
Z = X @ W + b0
dead = np.mean((Z > 0).sum(axis=0) == 0)
print(b0, f"{dead:.0%}") # 0.0 0% и -5.0 66%
pythonimport torch
import torch.nn as nn
x = torch.tensor([-1.0, 0.0, 2.0], requires_grad=True)
torch.relu(x).sum().backward()
print(x.grad) # tensor([0., 0., 1.]) — в нуле 0
# Инициализация Хе: Var w = 2 / fan_in
layer = nn.Linear(512, 512)
nn.init.kaiming_normal_(layer.weight, mode="fan_in", nonlinearity="relu")
nn.init.zeros_(layer.bias)
# Блок FFN исходного Transformer: Linear → ReLU → Linear
ffn = nn.Sequential(nn.Linear(512, 2048), nn.ReLU(), nn.Linear(2048, 512))
# nn.ReLU(inplace=True) экономит память, но портит вход, если он ещё нужен
ReLU — плюс инициализация Хе (kaiming_normal_ с nonlinearity='relu'), сдвиги 0, разумный шаг обучения. Время от времени проверяйте долю нейронов, которые ни разу не включились на батче: если она растёт, уменьшите шаг или перейдите на Leaky ReLU / GELU.
Частые ошибки
- ReLU на выходе регрессии, где цель может быть отрицательной. Сеть физически не сможет выдать $y<0$. На выходе регрессии — линейный слой; ReLU на выходе уместен только для заведомо неотрицательных величин (и даже тогда часто лучше softplus: у ReLU на выходе при отрицательном входе нулевой градиент).
- Инициализация как для tanh. С $\operatorname{Var}w=1/n$ сигнал в глубокой ReLU-сети затухает как $2^{-L}$: через 30 слоёв в $2^{30}\approx10^9$ раз (рисунок 7). Берите инициализацию Хе.
- Слишком большой шаг обучения. Массово убивает нейроны, и восстановить их нельзя (рисунок 6). Симптом — потери застыли, а доля нулевых активаций близка к 100%.
- «Производная ReLU в нуле равна 1/2» или «не определена — значит, ошибка». Математически в нуле есть субдифференциал $[0;1]$, любое его значение допустимо; библиотеки берут 0. На обучение это практически не влияет.
inplace=Trueтам, где вход нужен дальше. Операция затирает вход; если он используется в остаточной связи или для обратного прохода другой операции, PyTorch выдаст ошибку или результат будет неверным.
Связи с другими формулами
- Leaky ReLU: $\max(\alpha x,x)$ — ненулевой наклон $\alpha$ слева лечит умирание.
- GELU и SiLU: $x\Phi(x)$ и $x\sigma(x)$ — гладкие «вентили» вместо жёсткого $x\cdot\mathbb 1[x>0]$; вдали от нуля ведут себя как ReLU.
- Сигмоида: производная softplus — это $\sigma(\beta x)$; ReLU вытеснил сигмоиду из скрытых слоёв из-за насыщения.
- tanh: насыщается с обеих сторон; для tanh — инициализация Ксавье, для ReLU — Хе.
- Huber и Triplet loss: срезка $\max(0,\cdot)$ встречается и в функциях потерь.
- Adam и SGD: от выбора оптимизатора и шага зависит, сколько нейронов умрёт.
Итоги
1) $\operatorname{ReLU}(x)=\max(0,x)=\frac{x+|x|}2$ — вентиль: вход умножается на $\mathbb 1[x>0]$. 2) Производная — ступенька 0/1, в нуле субдифференциал $[0;1]$, на практике 0; справа нет насыщения. 3) Сумма шарниров $v_k\operatorname{ReLU}(x-c_k)$ — любая ломаная; на плоскости сеть из ReLU — многогранник из линейных областей, глубина умножает их число. 4) softplus — гладкий ReLU, его производная — сигмоида. 5) Большой шаг обучения убивает нейроны навсегда. 6) Инициализация Хе $\operatorname{Var}w=2/n_\text{in}$ компенсирует то, что ReLU обнуляет половину сигнала.