🔴 Сложный ⏱️ 55 минут

Функции активации

📋 Содержание урока

Функции активации ⚡

В уроке 328 ты уже увидел сигмоиду и ReLU в деле — как два конкретных варианта нелинейности $f$ в формуле $a=f(Wx+b)$, и даже успел заметить, что у сигмоиды есть проблема затухающего градиента на краях, а у ReLU — риск «умирания» нейронов. Но выбор функции активации на практике — это не мелкая техническая деталь, которую можно оставить «по умолчанию» и забыть. Это один из первых архитектурных вопросов, который встаёт перед тобой при проектировании любой сети: какую нелинейность поставить в скрытые слои, чтобы сеть вообще обучалась глубоко и быстро, и какую — на выход, чтобы её результат осмысленно интерпретировался как вероятность, класс или число.

Сегодняшний урок закрывает эту тему полностью. Мы пройдём весь путь исторического развития функций активации: от сигмоиды и гиперболического тангенса (tanh), которые доминировали в девяностых и двухтысячных, через ReLU, совершившую революцию в 2010-х и сделавшую возможным обучение по-настоящему глубоких сетей, до её усовершенствованных потомков — Leaky ReLU, Parametric ReLU (PReLU), ELU — и, наконец, до современных гладких активаций GELU и Swish, которые сегодня стоят в основе трансформеров вроде BERT и GPT. Отдельно разберём softmax — не как абстрактную формулу из урока 313, а именно как функцию активации выходного слоя многоклассового классификатора.

Ключевая идея, которая свяжет все разделы урока воедино, — это градиент. Функция активации участвует в вычислении предсказания сети (forward pass, урок 328), но её производная участвует в обучении (backpropagation, урок 330) — именно она определяет, насколько эффективно сигнал ошибки распространяется назад через сеть. Плохая с точки зрения градиента активация может сделать глубокую сеть необучаемой в принципе, даже если архитектура в остальном идеальна. Поэтому весь урок построен вокруг одного сквозного численного эксперимента: мы будем считать производные разных активаций в одних и тех же точках и сравнивать, что происходит с градиентом на практике.

К концу урока у тебя будет не абстрактный список формул, а рабочая интуиция: какую активацию ставить в скрытые слои прямо сейчас (спойлер — почти всегда какой-то вариант ReLU), какую — на выход в зависимости от задачи, и почему в самых современных архитектурах побеждают гладкие функции вроде GELU. Дальше в уроке 330 мы наконец разберём backpropagation — алгоритм, который использует именно те производные активаций, которые ты сегодня научишься считать вручную.

История

Сигмоида была стандартной активацией нейросетей с самого начала эпохи backpropagation в 1986 году (урок 328) и оставалась доминирующей практически два десятилетия — её гладкость и интерпретируемость как «вероятности срабатывания» биологического нейрона делали её естественным выбором. Гиперболический тангенс tanh, центрированный в нуле в отличие от сигмоиды, постепенно набирал популярность в девяностых как эмпирически более удачная альтернатива для скрытых слоёв, хотя формально он тоже родом из семейства сигмоидальных функций и наследует ту же фундаментальную проблему затухающего градиента.

Переломный момент наступил в 2011–2012 годах. В 2011 году Ксавье Глоро (Xavier Glorot) с соавторами опубликовал работу, показавшую, что простая кусочно-линейная функция ReLU не только не хуже, но зачастую значительно лучше сигмоиды и tanh для обучения глубоких сетей — потому что она не насыщается на положительной стороне и вычисляется почти мгновенно (одно сравнение с нулём против дорогой экспоненты в сигмоиде). А в 2012 году свёрточная сеть AlexNet Алекса Крижевского, Ильи Суцкевера и Джеффри Хинтона, использовавшая ReLU в скрытых слоях, выиграла соревнование ImageNet с огромным отрывом от конкурентов, впервые массово продемонстрировав мощь глубокого обучения на практике. Авторы AlexNet прямо писали, что переход на ReLU ускорил обучение их сети в несколько раз по сравнению с tanh — с этого момента ReLU стала фактическим стандартом индустрии.

Но ReLU принесла собственную проблему — умирающие нейроны, — и следующее десятилетие исследователи потратили на её смягчение. В 2013 году появилась Leaky ReLU, в 2015-м — Parametric ReLU (PReLU) от исследователей Microsoft и в том же году ELU (Exponential Linear Unit). Каждый следующий вариант пытался сохранить главное достоинство ReLU (дешевизна, отсутствие затухания на положительной стороне) и одновременно устранить её главный недостаток (нулевой градиент на отрицательной стороне). Финальный поворот случился в 2016–2018 годах, когда для архитектуры трансформеров (о которой ты подробнее узнаешь в продвинутых блоках курса) потребовалась более гладкая активация, чем угловатая ReLU, — так родилась GELU (Gaussian Error Linear Unit), опубликованная Дэном Хендрикс и Кевином Гимпелом в 2016 году, а следом — похожая по духу Swish, найденная исследователями Google в 2017 году с помощью автоматизированного поиска архитектур. Обе эти гладкие функции сегодня стоят в основе моделей BERT, GPT и большинства других современных трансформерных архитектур — то есть буквально в основе тех систем, ради понимания которых многие сегодня и изучают глубокое обучение.

Сигмоида и tanh: гладкие, но затухающие

Интуиция

Сигмоида сжимает любое вещественное число в интервал $(0,1)$ — удобная интерпретация «вероятности» или «степени активации» сделала её первым естественным выбором для искусственного нейрона. Гиперболический тангенс tanh делает почти то же самое, но сжимает вход в интервал $(-1,1)$ и, что важнее, центрирован в нуле: при $z=0$ он выдаёт ровно $0$, а не $0{,}5$, как сигмоида. Это на первый взгляд небольшое отличие имеет практическое значение: если выходы слоя центрированы вокруг нуля, следующему слою легче обучаться, потому что входящие в него сигналы не смещены систематически в одну сторону — именно поэтому tanh на практике почти всегда работает в скрытых слоях лучше сигмоиды, если ты вообще выбираешь из этого сигмоидального семейства. Но обе функции разделяют одну и ту же фундаментальную болезнь: на краях области определения, при больших по модулю $z$, обе функции становятся почти плоскими, а значит их производная стремится к нулю.

Формула

Сигмоида. $\sigma(z) = \dfrac{1}{1+e^{-z}}$, область значений $(0,1)$, производная $\sigma'(z) = \sigma(z)\bigl(1-\sigma(z)\bigr)$, максимум производной в точке $z=0$ равен $0{,}25$.

Гиперболический тангенс. $\tanh(z) = \dfrac{e^{z}-e^{-z}}{e^{z}+e^{-z}} = 2\sigma(2z)-1$, область значений $(-1,1)$, производная $\tanh'(z) = 1-\tanh^2(z)$, максимум производной в точке $z=0$ равен $1$.

Разбор примеров

Пример 1 (сравнение значений сигмоиды и tanh в одних и тех же точках). Возьмём три точки: $z=0$, $z=2$, $z=5$. При $z=0$: $\sigma(0)=0{,}5$, $\tanh(0)=0$. При $z=2$: $\sigma(2)=\dfrac{1}{1+e^{-2}}\approx0{,}8808$, $\tanh(2)=\dfrac{e^{2}-e^{-2}}{e^{2}+e^{-2}}=\dfrac{7{,}389-0{,}1353}{7{,}389+0{,}1353}\approx\dfrac{7{,}254}{7{,}524}\approx0{,}9640$. При $z=5$: $\sigma(5)\approx0{,}9933$, $\tanh(5)\approx0{,}9999$. Видно, что tanh «насыщается» (приближается к предельному значению $1$) быстрее сигмоиды при том же $z$ — его диапазон вдвое шире, а форма кривой круче в центре.

Пример 2 (сквозное численное сравнение градиентов сигмоиды, tanh и ReLU в одной и той же точке — ключевой расчёт урока). Возьмём точку $z=3$, которую сеть вполне может встретить на практике после умеренно уверенного нейрона. Сигмоида: $\sigma(3)=\dfrac{1}{1+e^{-3}}\approx0{,}9526$, производная $\sigma'(3)=0{,}9526\cdot(1-0{,}9526)=0{,}9526\cdot0{,}0474\approx0{,}0452$. Tanh: $\tanh(3)\approx0{,}9951$, производная $\tanh'(3)=1-0{,}9951^2\approx1-0{,}9902\approx0{,}0098$. ReLU: $\mathrm{ReLU}(3)=3$, производная $\mathrm{ReLU}'(3)=1$ (константа для любого положительного $z$). Сведём в таблицу:

Активация $f(3)$ $f'(3)$
Сигмоида $0{,}9526$ $0{,}0452$
Tanh $0{,}9951$ $0{,}0098$
ReLU $3$ $1$

Разница ошеломляющая: производная ReLU в этой точке в $22$ раза больше производной сигмоиды и более чем в $100$ раз больше производной tanh. Более того, у tanh в точке $z=3$ градиент оказывается даже меньше, чем у сигмоиды, — потому что tanh, будучи «круче» в центре, быстрее насыщается на краях. Это не противоречит тому, что tanh обычно лучше сигмоиды для скрытых слоёв в целом (за счёт центрирования в нуле, которое помогает на умеренных значениях $z$, близких к нулю) — но при больших $z$ обе сигмоидальные функции проигрывают ReLU с большим отрывом.

Пример 3 (тот же расчёт в точке насыщения — чем глубже сеть, тем разрушительнее эффект). Возьмём $z=6$, ситуацию, вполне достижимую в сети с несколькими скрытыми слоями без нормализации активаций. Сигмоида: $\sigma(6)\approx0{,}9975$, $\sigma'(6)\approx0{,}9975\cdot0{,}0025\approx0{,}00246$. Tanh: $\tanh(6)\approx0{,}99999$, $\tanh'(6)\approx1-0{,}99998\approx0{,}00002$. ReLU: производная по-прежнему ровно $1$. Теперь представь сеть с пятью последовательными сигмоидными слоями, каждый из которых работает в этой зоне насыщения: по цепному правилу (урок 330) итоговый градиент, дошедший до первого слоя, будет пропорционален произведению пяти таких маленьких чисел — $0{,}00246^5\approx9\cdot10^{-13}$, практически неотличимо от нуля. У сети с ReLU в тех же условиях произведение пяти единиц остаётся равным единице — градиент не затухает вовсе. Это и есть механизм, из-за которого глубокие сети с сигмоидой или tanh практически не обучались до появления ReLU: чем больше слоёв, тем катастрофичнее перемножение маленьких производных.

Почему это важно

Пример 3 объясняет напрямую, почему революция ReLU в 2011–2012 годах не была случайным трендом, а решала конкретную математическую проблему: затухающий градиент (vanishing gradient) буквально останавливает обучение ранних слоёв глубокой сети, потому что сигнал ошибки, посчитанный на выходе, экспоненциально гаснет по мере прохождения назад через насыщенные сигмоидные или tanh-слои. При этом обе функции не исчезли из практики полностью: сигмоида остаётся стандартом для выходного слоя бинарной классификации именно благодаря интервалу $(0,1)$, интерпретируемому как вероятность, а tanh иногда используется в специфических архитектурах (например, в рекуррентных сетях LSTM для внутренних вентилей) именно из-за центрирования в нуле. Но как активация скрытых слоёв глубокой сети обе они сегодня уступили место ReLU и её потомкам — к которым мы и переходим.

ReLU и проблема умирающих нейронов

Интуиция

ReLU — предельно простая идея: если вход положительный, пропусти его без изменений; если отрицательный, замени на ноль. Никакой экспоненты, никакого насыщения на положительной стороне — производная там всегда ровно единица, сколь угодно большой ни был бы вход. Именно эта простота даёт два практических преимущества: вычислительную дешевизну (сравнение с нулём и обнуление — на порядки быстрее вычисления экспоненты на каждом нейроне каждого слоя миллионы раз за проход) и отсутствие затухания градиента для активных нейронов, что ты только что увидел в примере 3 предыдущего раздела. Но у этой же простоты есть обратная сторона: если веса нейрона сложились так, что его вход $z$ отрицателен для всех примеров обучающей выборки, производная ReLU в этой точке всегда равна нулю — и градиент, необходимый для обновления весов этого нейрона, тоже всегда равен нулю. Нейрон замирает навсегда, сколько бы шагов обучения ни прошло дальше.

Формула

ReLU (Rectified Linear Unit). $\mathrm{ReLU}(z) = \max(0,z)$, производная $\mathrm{ReLU}'(z) = \begin{cases}1, & z>0\\0, & z<0\end{cases}$ (в точке $z=0$ производная формально не определена, на практике полагается $0$ или $1$).

Разбор примеров

Пример 1 (положительная сторона — градиент не затухает даже на большой глубине). Возьмём сеть из десяти последовательных ReLU-слоёв, в которой каждый нейрон на пути от входа к выходу имеет положительный вход (то есть активен). Производная каждого такого слоя равна $1$, и по цепному правилу итоговый множитель градиента равен $1^{10}=1$ — полное отсутствие затухания, независимо от глубины сети. Сравни это с сигмоидной сетью из примера 3 предыдущего раздела, где даже пять слоёв в зоне насыщения гасили градиент до $9\cdot10^{-13}$. Это ключевое инженерное преимущество ReLU: она физически позволяет обучать сети с сотнями слоёв, что было практически невозможно с сигмоидой.

Пример 2 (конкретный численный пример умирающего нейрона). Возьмём нейрон скрытого слоя с весами $w=(-3,-2)$ и смещением $b=-1$, который получает на вход два признака $x_1,x_2$, оба неотрицательные (например, нормализованные в $[0,1]$ пиксельные значения или выход предыдущего ReLU-слоя, который по определению не может быть отрицательным). Тогда $z=-3x_1-2x_2-1$. Поскольку $x_1,x_2\ge0$, слагаемые $-3x_1$ и $-2x_2$ всегда неположительны, значит $z\le-1<0$ для абсолютно любых допустимых входов. Проверим на трёх конкретных примерах из датасета: при $x=(0,0)$: $z=-1$; при $x=(0{,}5;\,0{,}3)$: $z=-3\cdot0{,}5-2\cdot0{,}3-1=-1{,}5-0{,}6-1=-3{,}1$; при $x=(1,1)$: $z=-3-2-1=-6$. Во всех трёх случаях $z<0$, значит $\mathrm{ReLU}(z)=0$ и $\mathrm{ReLU}'(z)=0$ на каждом из них. При обучении градиент по весам $w_1,w_2,b$ этого нейрона (по цепному правилу, урок 330) содержит множитель $\mathrm{ReLU}'(z)=0$ — значит и всё произведение равно нулю, обновление весов не происходит никогда, независимо от того, насколько сеть в целом ещё ошибается.

Пример 3 (почему это может произойти массово — большой шаг обучения как причина). Одна из типичных причин умирания ReLU-нейронов на практике — слишком большая скорость обучения (learning rate): резкое обновление весов на одном неудачном батче данных может «перебросить» веса нейрона в область, где $z<0$ для всех входов сразу, после чего нейрон уже никогда не получит градиента, чтобы выбраться обратно. Возьмём нейрон с весами $w=(0{,}5,0{,}3)$, $b=0{,}1$ до обновления — вполне «живой» нейрон, срабатывающий на многих входах. Допустим, резкое обновление с большим шагом сдвинуло веса до $w=(-4,-3)$, $b=-2$ (аналогично примеру 2). Если после этого сдвига входные признаки датасета всегда неотрицательны, новый набор весов гарантированно даёт $z<0$ на всём датасете — нейрон умер одним-единственным неудачным шагом обучения. На практике именно поэтому осторожная инициализация весов (например, He-инициализация, разработанная специально под ReLU) и умеренная скорость обучения — не второстепенные детали, а прямая защита от массового умирания нейронов.

Почему это важно

Умирающий ReLU — не гипотетическая опасность, а реальная проблема, с которой сталкивается почти каждый, кто обучает глубокую сеть: на практике сообщается, что от 10% до 50% ReLU-нейронов в некоторых сетях со временем становятся постоянно неактивными, особенно при высокой скорости обучения. Важно понимать: умерший нейрон не «портит» предсказания сети катастрофически (он просто выдаёт константный ноль, как будто его вовсе не существует в этом слое), но он снижает эффективную ёмкость модели — часть параметров сети становится бесполезным балластом, который занимает память и вычисления, ничего не давая взамен. Именно эта проблема мотивировала следующее поколение активаций, которое мы разберём дальше.

Leaky ReLU, PReLU, ELU, GELU и Swish

Интуиция

Идея решения проблемы умирающего ReLU удивительно проста: вместо того чтобы обнулять отрицательную часть входа полностью, дай ей небольшой ненулевой наклон. Тогда даже если вход нейрона отрицателен, производная не равна нулю — она равна маленькому положительному числу, и градиент, пусть и слабый, всё же проходит через нейрон, позволяя весам постепенно выбраться из «мёртвой» зоны. Leaky ReLU задаёт этот наклон фиксированным небольшим числом, Parametric ReLU (PReLU) идёт на шаг дальше и делает этот наклон обучаемым параметром — сеть сама подбирает, насколько «протекающей» должна быть активация каждого нейрона. ELU заменяет прямую линию отрицательной части на плавную экспоненциальную кривую, что делает саму функцию гладкой в нуле (а не с изломом, как у ReLU и Leaky ReLU). GELU и Swish идут ещё дальше по пути гладкости: вместо жёсткого порога в нуле они умножают вход на плавно нарастающий множитель от $0$ до $1$, из-за чего сама функция становится бесконечно дифференцируемой на всей области определения, без единого излома.

Формула

Leaky ReLU. $\mathrm{LReLU}(z) = \begin{cases}z, & z>0\\\alpha z, & z\le0\end{cases}$, где $\alpha$ — маленькая фиксированная константа (типично $\alpha=0{,}01$).

Parametric ReLU (PReLU). Та же формула, но $\alpha$ — обучаемый параметр, подстраиваемый градиентным спуском вместе с остальными весами сети.

ELU (Exponential Linear Unit). $\mathrm{ELU}(z) = \begin{cases}z, & z>0\\\alpha(e^{z}-1), & z\le0\end{cases}$, обычно $\alpha=1$; при $z\le0$ функция плавно стремится к пределу $-\alpha$.

GELU (Gaussian Error Linear Unit, приближённая формула). $\mathrm{GELU}(z) \approx 0{,}5z\Bigl(1+\tanh\bigl[\sqrt{2/\pi}\,(z+0{,}044715z^3)\bigr]\Bigr)$.

Swish (он же SiLU). $\mathrm{Swish}(z) = z\cdot\sigma(z) = \dfrac{z}{1+e^{-z}}$.

Разбор примеров

Пример 1 (Leaky ReLU спасает нейрон из примера 2 предыдущего раздела). Возьмём тот же умерший нейрон с $z=-6$ (вход $x=(1,1)$ из предыдущего раздела). С обычным ReLU: $\mathrm{ReLU}(-6)=0$, производная $0$ — градиент полностью заблокирован. С Leaky ReLU при $\alpha=0{,}01$: $\mathrm{LReLU}(-6)=0{,}01\cdot(-6)=-0{,}06$ — не ноль, а маленькое отрицательное число, и производная в этой точке равна $\alpha=0{,}01$, а не $0$. Это в сто раз меньше, чем производная на положительной стороне (равная $1$), но принципиально отлично от нуля: при обучении градиент, пусть и слабый, всё же дойдёт до весов этого нейрона, и со временем они смогут сдвинуться обратно в область, где нейрон снова активен на части входов.

Пример 2 (ELU и GELU в конкретных отрицательных точках — сравнение гладкости). Посчитаем значения в точке $z=-2$. ELU при $\alpha=1$: $\mathrm{ELU}(-2)=1\cdot(e^{-2}-1)=0{,}1353-1=-0{,}8647$. Leaky ReLU при $\alpha=0{,}01$: $\mathrm{LReLU}(-2)=-0{,}02$. GELU по приближённой формуле: сначала $z+0{,}044715z^3=-2+0{,}044715\cdot(-8)=-2-0{,}3577=-2{,}3577$, умножаем на $\sqrt{2/\pi}\approx0{,}7979$: $0{,}7979\cdot(-2{,}3577)\approx-1{,}881$, $\tanh(-1{,}881)\approx-0{,}9546$, тогда $\mathrm{GELU}(-2)\approx0{,}5\cdot(-2)\cdot(1-0{,}9546)=-1\cdot0{,}0454\approx-0{,}0454$. Обрати внимание: в отличие от ELU, которая асимптотически стремится к пределу $-1$ и никогда не даёт положительный выход для отрицательного входа, GELU (как и Swish) — немонотонная функция: она может давать небольшие отрицательные значения для умеренно отрицательных $z$, но при этом плавно, без единого излома, переходит от «почти ноль» к «почти $z$» вокруг нуля, что и обеспечивает её гладкость на всей области определения.

Пример 3 (Swish и GELU почти совпадают, и обе гладкие в нуле, в отличие от ReLU и Leaky ReLU). Посчитаем Swish в нескольких точках рядом с нулём: $\mathrm{Swish}(-1)=-1\cdot\sigma(-1)=-1\cdot0{,}2689\approx-0{,}2689$; $\mathrm{Swish}(0)=0\cdot\sigma(0)=0$; $\mathrm{Swish}(1)=1\cdot\sigma(1)=1\cdot0{,}7311\approx0{,}7311$. Сравни с ReLU в тех же точках: $\mathrm{ReLU}(-1)=0$, $\mathrm{ReLU}(0)=0$, $\mathrm{ReLU}(1)=1$ — у ReLU в точке $z=0$ резкий излом (производная слева равна $0$, справа $1$, то есть производная разрывна), тогда как у Swish и GELU производная плавно меняется через ноль без всякого излома. Именно эта гладкость — не украшение ради красоты графика, а практическое преимущество: при обучении очень глубоких сетей (в частности, трансформеров с десятками и сотнями слоёв) резкие изломы в функции активации могут создавать шум в ландшафте функции потерь, слегка затрудняя оптимизацию, тогда как гладкая функция даёт более предсказуемое поведение градиента при малых изменениях входа.

Почему это важно

Эволюция от ReLU к Leaky ReLU/PReLU/ELU и дальше к GELU/Swish — это не мода, а последовательное решение конкретных инженерных проблем: сначала устранили умирание нейронов (Leaky ReLU, PReLU, ELU), затем — уже для сверхглубоких архитектур, где важна максимальная гладкость оптимизационного ландшафта, — перешли к бесконечно дифференцируемым функциям (GELU, Swish). Именно поэтому GELU стала активацией по умолчанию в трансформерах: она используется в оригинальной архитектуре BERT (2018), а затем и в семействе GPT, а также в большинстве современных больших языковых моделей. Если сегодня тебе понадобится читать или писать код архитектуры трансформера, ты почти наверняка встретишь nn.GELU() в определении слоёв прямого распространения (feed-forward, внутри каждого блока внимания) — и теперь ты понимаешь, откуда взялась эта формула и почему она предпочтительнее простой ReLU именно в таких архитектурах.

Softmax и правила выбора активации на практике

Интуиция

До сих пор весь разговор шёл про активации скрытых слоёв. Но у выходного слоя своя отдельная логика выбора, полностью подчинённая типу решаемой задачи, а не общим соображениям о затухании градиента. Для многоклассовой классификации (когда объект нужно отнести ровно к одному из $K>2$ классов) стандартный выбор — softmax, с которой ты уже встречался в уроке 313 как с функцией потерь логистической регрессии для многих классов. Здесь важно взглянуть на неё именно как на функцию активации выходного слоя: она превращает произвольный вектор сырых чисел (логитов) с выхода последнего линейного слоя в вектор вероятностей, которые неотрицательны и в сумме дают ровно единицу — то есть в математически корректное распределение вероятностей по классам.

Формула

Softmax. Для вектора логитов $z=(z_1,\dots,z_K)$ на выходном слое $K$-классового классификатора

$$\mathrm{softmax}(z)_i = \frac{e^{z_i}}{\sum_{j=1}^K e^{z_j}}, \qquad i=1,\dots,K$$

так что $\mathrm{softmax}(z)_i \in (0,1)$ для каждого $i$ и $\sum_{i=1}^K \mathrm{softmax}(z)_i = 1$.

Разбор примеров

Пример 1 (softmax на конкретных логитах трёхклассового классификатора). Пусть выходной слой сети для задачи классификации изображения на «кошка», «собака», «птица» выдал логиты $z=(2{,}0;\ 1{,}0;\ 0{,}1)$. Посчитаем экспоненты: $e^{2{,}0}\approx7{,}389$, $e^{1{,}0}\approx2{,}718$, $e^{0{,}1}\approx1{,}105$. Сумма: $7{,}389+2{,}718+1{,}105=11{,}212$. Вероятности: $p_{кошка}=7{,}389/11{,}212\approx0{,}659$, $p_{собака}=2{,}718/11{,}212\approx0{,}242$, $p_{птица}=1{,}105/11{,}212\approx0{,}099$. Сумма $0{,}659+0{,}242+0{,}099=1{,}000$ — softmax действительно превратил произвольные числа в корректное распределение вероятностей, и сеть максимально уверена в классе «кошка».

Пример 2 (связь softmax с сигмоидой — частный случай при двух классах). Возьмём бинарный случай с логитами $z=(z_1,z_2)$. По формуле softmax: $\mathrm{softmax}(z)_1 = \dfrac{e^{z_1}}{e^{z_1}+e^{z_2}}$. Разделим числитель и знаменатель на $e^{z_1}$: получим $\dfrac{1}{1+e^{z_2-z_1}} = \sigma(z_1-z_2)$ — это в точности формула сигмоиды от разности логитов. Проверим на числах: $z_1=3$, $z_2=1$. Прямой расчёт softmax: $e^3\approx20{,}09$, $e^1\approx2{,}718$, сумма $\approx22{,}80$, $p_1\approx20{,}09/22{,}80\approx0{,}881$. Через сигмоиду: $\sigma(3-1)=\sigma(2)\approx0{,}8808$ — числа совпадают (с точностью до округления). Отсюда практический вывод: для строго двух классов сигмоида на одном выходном нейроне и softmax на двух выходных нейронах — математически эквивалентные подходы, но на практике для бинарной классификации почти всегда выбирают более экономную сигмоиду с одним нейроном на выходе.

Пример 3 (числовая устойчивость — зачем на практике вычитают максимум из логитов). Пусть логиты оказались большими: $z=(1000, 999, 998)$. Прямое вычисление $e^{1000}$ переполнит практически любой формат чисел с плавающей точкой (числовое переполнение, overflow). Стандартный трюк — вычесть из всех логитов их максимум перед экспонированием: $z'=z-\max(z)=(0,-1,-2)$. Результат softmax при этом математически идентичен, потому что $\dfrac{e^{z_i-c}}{\sum_j e^{z_j-c}} = \dfrac{e^{z_i}}{\sum_j e^{z_j}}$ для любой константы $c$ (множитель $e^{-c}$ сокращается и в числителе, и в знаменателе). Считаем на устойчивых числах: $e^0=1$, $e^{-1}\approx0{,}368$, $e^{-2}\approx0{,}135$, сумма $\approx1{,}503$, $p_1\approx1/1{,}503\approx0{,}665$, $p_2\approx0{,}368/1{,}503\approx0{,}245$, $p_3\approx0{,}135/1{,}503\approx0{,}090$. Именно поэтому все промышленные реализации (torch.nn.functional.softmax, tf.nn.softmax) уже содержат этот трюк внутри и не требуют ручного вмешательства, но полезно понимать, откуда он взялся.

Почему это важно

Выбор активации выходного слоя — это не вопрос вкуса, а прямое следствие типа задачи, и на практике почти всегда действует простое правило. Для скрытых слоёв: используй ReLU как разумный выбор по умолчанию, при подозрении на массовое умирание нейронов переходи на Leaky ReLU или PReLU, а для очень глубоких архитектур (трансформеры и подобные) — на GELU или Swish. Для выходного слоя правило зависит от задачи: бинарная классификация — сигмоида на одном нейроне (выход интерпретируется как вероятность положительного класса); многоклассовая классификация с ровно одним верным классом — softmax на $K$ нейронах (выход — распределение вероятностей по классам); многометочная классификация, где объект может одновременно принадлежать нескольким классам, — независимая сигмоида на каждом из $K$ выходных нейронов (не softmax, потому что классы здесь не взаимоисключающие); регрессия (предсказание вещественного числа без ограничений, например цены квартиры) — линейная активация, то есть фактически отсутствие какой-либо нелинейности на выходе, потому что сигмоида или tanh искусственно ограничили бы диапазон предсказываемых значений.

Практика: 30 заданий

Базовые задания (1–10)

Задание 1: Вычисли $\sigma(1)$ для сигмоиды $\sigma(z)=\dfrac{1}{1+e^{-z}}$.


Задание 2: Вычисли $\tanh(0)$ и $\mathrm{ReLU}(0)$.


Задание 3: Найди производную сигмоиды в точке $z=0$, используя формулу $\sigma'(z)=\sigma(z)(1-\sigma(z))$.


Задание 4: Вычисли Leaky ReLU при $\alpha=0{,}01$ для $z=-5$ и $z=5$.


Задание 5 (машинное обучение): Почему выходной слой бинарного классификатора обычно использует сигмоиду, а не ReLU?


Задание 6: Дан вектор логитов $z=(1,2)$ для бинарной классификации через softmax на двух нейронах. Найди $\mathrm{softmax}(z)_1$.


Задание 7: Проверь результат задания 6, вычислив $\sigma(z_1-z_2)=\sigma(1-2)=\sigma(-1)$.


Задание 8: Дан нейрон с весами $w=(-2,-1)$, $b=-0{,}5$, входы всегда неотрицательны ($x_1,x_2\ge0$). Найди максимально возможное значение $z$.


Задание 9: Вычисли $\mathrm{Swish}(0)$, используя $\mathrm{Swish}(z)=z\cdot\sigma(z)$.


Задание 10 (машинное обучение): Сеть решает задачу регрессии — предсказание температуры воздуха (число от $-40$ до $+50$ градусов). Подходит ли сигмоида для выходного слоя? Почему?

Средние задания (11–20)

Задание 11: Вычисли производную $\mathrm{ReLU}'(z)$ и $\sigma'(z)$ в точке $z=4$ и сравни их.


Задание 12: Вычисли $\tanh(1)$ и сравни с $\sigma(1)$ из задания 1.


Задание 13: Дан вектор логитов трёхклассового классификатора $z=(0,0,0)$. Найди все три значения softmax без вычислений экспоненты (используй симметрию).


Задание 14 (машинное обучение): ReLU-нейрон умер (веса $w=(-3,-2)$, $b=-1$, входы всегда $\ge0$, как в разборе урока). Объясни, почему замена активации на Leaky ReLU с $\alpha=0{,}01$ решает проблему без изменения весов.


Задание 15: Вычисли $\mathrm{ELU}(-1)$ при $\alpha=1$, используя $\mathrm{ELU}(z)=\alpha(e^z-1)$ для $z\le0$.


Задание 16: Сравни производные $\sigma'(z)$ в точках $z=0$ и $z=4$ (используй результаты заданий 3 и 11). Во сколько раз производная уменьшилась?


Задание 17 (машинное обучение): Сеть для многометочной классификации должна одновременно определить, есть ли на фото «кошка», «собака» и «машина» (объекты не исключают друг друга). Какую активацию выходного слоя выбрать — softmax или сигмоиду на каждом нейроне — и почему?


Задание 18: Вычисли $\mathrm{GELU}(2)$ по приближённой формуле $\mathrm{GELU}(z)\approx0{,}5z(1+\tanh[\sqrt{2/\pi}(z+0{,}044715z^3)])$.


Задание 19: Логиты четырёхклассового классификатора $z=(5,3,1,-1)$ очень большие. Вычти максимум и запиши устойчивый вектор $z'$ для дальнейшего вычисления softmax.


Задание 20 (машинное обучение): Почему PReLU в некоторых задачах работает лучше, чем Leaky ReLU с фиксированным $\alpha=0{,}01$?

Продвинутые задания (21–30)

Задание 21: Дан скрытый слой с тремя нейронами и предвызовами $z=(-3,0{,}5,2)$. Примени ReLU и Leaky ReLU ($\alpha=0{,}1$) к каждому и сравни результаты.


Задание 22: Сеть выдала на выходном слое (сигмоида, бинарная классификация) $z_{out}=-4$. Найди вероятность положительного класса и объясни, что произойдёт с градиентом при обучении на этом примере, если предсказание неверное.


Задание 23 (машинное обучение): Объясни на численном примере, почему композиция нескольких сигмоидных слоёв (без промежуточных ReLU) делает очень глубокую сеть практически необучаемой, используя результат примера 3 раздела про сигмоиду и tanh.


Задание 24: Дан нейрон с весами $w=(1,-4)$, $b=0{,}5$ и датасет, где $x_1\in[0,1]$, а $x_2\in[0,1]$. Определи, может ли этот нейрон «умереть» при ReLU, и обоснуй ответ, проверив крайние значения входа.


Задание 25 (машинное обучение): Почему для очень глубокой архитектуры трансформера предпочитают GELU, а не обычный ReLU, хотя ReLU вычислительно дешевле?


Задание 26: Логиты пятиклассового классификатора $z=(2,2,2,2,2)$ (все равны). Не вычисляя экспоненты явно, определи все пять значений softmax, используя рассуждение из задания 13.


Задание 27: Сравни Swish и ReLU в точке $z=-0{,}5$: $\mathrm{Swish}(z)=z\cdot\sigma(z)$.


Задание 28 (машинное обучение): Ты проектируешь сеть для классификации рукописных цифр (10 классов, ровно одна верная метка на изображение). Опиши полную схему выбора активаций: скрытые слои и выходной слой, с обоснованием каждого выбора.


Задание 29: Дан выходной слой регрессии с единственным нейроном без активации (линейный выход), веса $v=(2,-1,0{,}5)$, $c=1$, вход $a=(3,4,-2)$. Найди итоговое предсказание $\hat y$.


Задание 30 (машинное обучение): Обобщи: почему нельзя одной универсальной активацией закрыть все три роли сразу (скрытые слои глубокой сети, бинарная классификация на выходе, многоклассовая классификация на выходе)?


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

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

Путать softmax и сигмоиду на выходном слое: ставить softmax для бинарной классификации на одном нейроне (формула softmax предполагает нормировку по нескольким выходам и не имеет смысла для единственного числа) или использовать сигмоиду на нескольких независимых выходных нейронах там, где классы взаимоисключающие и нужна именно нормировка через softmax.

Игнорировать умирание ReLU-нейронов как «маловероятную теоретическую проблему» — на практике при слишком большой скорости обучения или неудачной инициализации весов значительная доля нейронов сети (иногда десятки процентов) может перестать реагировать на входы уже на ранних эпохах обучения, и без специального мониторинга это легко упустить.

Ставить нелинейную ограниченную активацию (сигмоиду или tanh) на выходной слой сети, решающей задачу регрессии без ограничений диапазона, — из-за чего сеть физически не сможет предсказать значения за пределами $(0,1)$ или $(-1,1)$, какими бы точными ни были веса.

Забывать про числовую устойчивость softmax при работе с большими логитами напрямую (без вычитания максимума) — на практике это редко всплывает при использовании готовых библиотечных реализаций, но становится критичной ошибкой при написании softmax вручную «с нуля».

Считать, что более новая и «модная» активация (GELU, Swish) автоматически лучше во всех случаях — для многих небольших сетей и классических задач разница между ReLU и GELU статистически незначима, а дополнительная вычислительная стоимость (экспонента вместо сравнения с нулём) может быть неоправданна.

Главное запомнить

Сигмоида сжимает вход в $(0,1)$ и страдает от затухающего градиента на краях — на практике сегодня используется почти исключительно на выходном слое бинарной классификации, а не в скрытых слоях.

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

ReLU $=\max(0,z)$ решает затухание градиента на положительной стороне (производная всегда ровно $1$ для $z>0$) и вычислительно значительно дешевле сигмоиды и tanh.

Проблема умирающего ReLU возникает, когда веса нейрона попадают в область, где вход отрицателен для всех примеров датасета, — тогда производная и градиент навсегда равны нулю, и веса больше не обновляются.

Leaky ReLU и PReLU решают умирание ReLU, добавляя небольшой ненулевой наклон для отрицательных входов — фиксированный в Leaky ReLU, обучаемый в PReLU.

ELU, GELU и Swish — более гладкие альтернативы без резкого излома в нуле; GELU и Swish дополнительно немонотонны вблизи нуля и бесконечно дифференцируемы на всей области определения.

GELU — активация по умолчанию в большинстве современных трансформерных архитектур, включая BERT и семейство GPT, благодаря своей гладкости, важной для стабильности обучения очень глубоких сетей.

Softmax на выходном слое превращает произвольный вектор логитов в корректное распределение вероятностей (неотрицательное, с суммой $1$) для многоклассовой классификации с взаимоисключающими классами.

Общее правило выбора: скрытые слои — ReLU или её варианты; бинарная классификация на выходе — сигмоида; многоклассовая классификация на выходе — softmax; регрессия без ограничений — линейная активация (её отсутствие).

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

Связь с темами курса

В уроке 328 ты уже кратко встретил сигмоиду и ReLU как примеры активации $f$ в формуле полносвязного слоя $a=f(Wx+b)$ и увидел, как обе они используются в forward pass многослойной сети. Сегодняшний урок разобрал ту же пару функций (плюс их родственников и потомков) гораздо глубже — с точным численным сравнением градиентов, что напрямую готовит тебя к следующей теме курса.

В уроке 330 ты разберёшь алгоритм backpropagation — то, как сеть вычисляет градиент функции потерь по каждому весу, используя цепное правило дифференцирования. Производные функций активации, которые ты сегодня считал вручную ($\sigma'(z)$, $\mathrm{ReLU}'(z)$ и другие), окажутся ровно теми множителями, которые входят в это цепное правило на каждом слое, — без сегодняшнего урока формулы backpropagation выглядели бы абстрактными символами, а не конкретными числами, которые ты уже умеешь считать.

Интересные факты

GELU была впервые предложена в 2016 году исследователями Дэном Хендриксом и Кевином Гимпелом изначально не для трансформеров (которые тогда ещё не существовали в современном виде — статья «Attention Is All You Need» вышла только в 2017 году), а как общая альтернатива ReLU; лишь позже она оказалась настолько удачной именно для трансформерных архитектур, что стала в них практическим стандартом — сегодня она встроена в определения слоёв BERT, GPT и множества других языковых моделей.

Swish была найдена не вручную, а с помощью автоматизированного поиска архитектур (neural architecture search): исследователи Google в 2017 году запустили алгоритм, перебиравший комбинации простых математических операций в поисках наилучшей функции активации, и именно он «открыл» формулу $z\cdot\sigma(z)$ как одну из самых удачных находок — по любопытному совпадению позже выяснилось, что эта же функция независимо изучалась и раньше под названием SiLU (Sigmoid Linear Unit).

Производная ReLU формально не определена ровно в точке $z=0$ (слева она равна $0$, справа $1$), но на практике это почти никогда не создаёт проблем: вероятность того, что вход нейрона окажется равным ровно нулю с точностью до бита в вычислениях с плавающей точкой, исчезающе мала, а стандартные библиотеки просто договариваются полагать производную в этой точке равной $0$ или $1$ и двигаются дальше.

Победа сети AlexNet на соревновании ImageNet в 2012 году с использованием ReLU вместо стандартной на тот момент tanh часто называется одним из ключевых моментов, запустивших современный бум глубокого обучения, — авторы прямо отмечали в статье, что переход на ReLU позволил обучить их сеть в несколько раз быстрее.

Лайфхаки

Если не знаешь, с чего начать выбор активации для скрытых слоёв новой сети, — начни с ReLU. Это разумный выбор по умолчанию для подавляющего большинства архитектур, вычислительно дешёвый и хорошо изученный.

Если во время обучения замечаешь, что доля «мёртвых» ReLU-нейронов (постоянно выдающих ноль на всём датасете) растёт и остаётся высокой, — попробуй сначала уменьшить скорость обучения, а если не помогает, перейди на Leaky ReLU или PReLU вместо обычного ReLU.

Для сверхглубоких архитектур (десятки и сотни слоёв, особенно трансформерного типа) начинай сразу с GELU или Swish — эмпирически они стабильнее на такой глубине, чем обычный ReLU, несмотря на бо́льшую вычислительную стоимость.

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

Всегда сверяй активацию выходного слоя с типом задачи по простому правилу: один класс из многих взаимоисключающих — softmax; вероятность одного признака (или каждого признака независимо) — сигмоида; число без ограничений — линейный выход без активации вовсе.

Если пишешь softmax вручную (а не через готовую библиотечную функцию), всегда вычитай максимум из логитов перед экспонированием — это защищает от числового переполнения и не меняет результат.

При отладке подозрительно медленного обучения глубокой сети в первую очередь проверь, не насыщены ли активации в средних слоях (не близки ли выходы сигмоиды или tanh систематически к $0$ или $1$) — это один из самых частых и легко диагностируемых источников затухающего градиента.

Функция активации — это не «косметическая» настройка модели, а один из немногих архитектурных выборов, который напрямую определяет, сможет ли твоя сеть вообще обучиться на достаточной глубине. Сегодня ты научился считать градиенты разных активаций вручную и понимать, откуда берётся и как решается проблема затухания и умирания нейронов, — а в следующем уроке эти самые производные станут строительными блоками алгоритма backpropagation, который заставляет всю эту конструкцию обучаться на реальных данных.

Понял тему? Закрепи в боте! 🚀

Попрактикуйся на задачах и получи персональные рекомендации от AI

💪 Начать тренировку
💬 Есть вопрос? Спроси бота!