Зачем он нужен
Сигмоида превращает число в долю от 0 до 1. Но внутри сети нам часто нужна не доля, а сигнал со знаком: «больше обычного» или «меньше обычного», «усилить» или «ослабить». Гиперболический тангенс (hyperbolic tangent) — это та же плавная S-кривая, но с выходом в интервале $(-1;\,1)$ и центром в нуле.
Где он встречается:
- рекуррентные сети — в простой RNN $h_t=\tanh(Wh_{t-1}+Ux_t+b)$, в LSTM и GRU tanh формирует кандидата в память, а в LSTM ещё и ограничивает выход ячейки;
- скрытые слои классических сетей — до эпохи ReLU tanh был стандартом и до сих пор хорош в маленьких сетях и физически информированных моделях (PINN), где нужна гладкость;
- выход генератора — если картинки нормированы в $[-1;\,1]$, последний слой генератора GAN (например, DCGAN) берёт tanh;
- ограничение действий и логитов — в обучении с подкреплением (SAC) действие сжимают в $(-1;\,1)$ через tanh, а в Gemma 2 логиты «мягко обрезают»: $c\cdot\tanh(z/c)$;
- внутри других активаций — популярное приближение GELU записано через tanh.
$\tanh$ сжимает всю числовую прямую в $(-1;\,1)$, проходит через начало координат и нечётна: $\tanh(-x)=-\tanh x$. Это растянутая сигмоида: $\tanh x=2\sigma(2x)-1$. Производная $1-\tanh^2x$ не больше 1 — в 4 раза больше максимума сигмоиды, — но на хвостах tanh так же насыщается, и градиент гаснет.
Интуиция: сигмоида, поставленная на ноль
Представьте регулятор громкости со знаком: ноль — тишина, вправо — громче, влево — громче в противофазе. Пока вы крутите возле нуля, выход послушно следует за входом: $\tanh x\approx x$. Чем дальше, тем туже ход: выход упирается в $\pm1$ и больше не растёт. Это насыщение (saturation).
Потяните точку. Оранжевая прямая — касательная, её наклон и есть производная. Серый пунктир — сигмоида: та же форма, но сдвинута вверх, вдвое ниже и вчетверо положе.
При $x=2$ tanh уже $0{,}964$, а производная — $0{,}071$, в 14 раз меньше, чем в центре. При $|x|>2{,}99$ производная падает ниже $0{,}01$: дальше вход растёт, а выход почти стоит на месте.
Формула по косточкам
В формуле две экспоненты: растущая $e^{x}$ и убывающая $e^{-x}$. Числитель — их разность, знаменатель — сумма. Половины этих выражений имеют собственные имена — гиперболический синус и косинус:
- $e^{x}-e^{-x}$
- разность нечётна: при замене $x\to-x$ меняет знак; при $x>0$ положительна;
- $e^{x}+e^{-x}$
- сумма всегда положительна и не меньше 2 — знаменатель никогда не обращается в ноль;
- $|\sinh x|<\cosh x$
- разность по модулю всегда меньше суммы, поэтому $|\tanh x|<1$;
- $x\to\pm\infty$
- одна из экспонент становится пренебрежимо малой, и дробь стремится к $\pm1$.
Умножив числитель и знаменатель на $e^{x}$ или на $e^{-x}$, получим формы, удобные для вычислений, а последняя форма связывает tanh с сигмоидой:
| $x$ | $\tanh x$ | $\tanh' x$ | $\sigma(x)$ |
|---|---|---|---|
| −3 | −0,9951 | 0,0099 | 0,0474 |
| −2 | −0,9640 | 0,0707 | 0,1192 |
| −1 | −0,7616 | 0,4200 | 0,2689 |
| −0,5 | −0,4621 | 0,7864 | 0,3775 |
| 0 | 0,0000 | 1,0000 | 0,5000 |
| 0,5 | 0,4621 | 0,7864 | 0,6225 |
| 1 | 0,7616 | 0,4200 | 0,7311 |
| 2 | 0,9640 | 0,0707 | 0,8808 |
| 3 | 0,9951 | 0,0099 | 0,9526 |
Таблица показывает нечётность: $\tanh(-x)=-\tanh x$, а производная — чётная функция. Рядом для сравнения сигмоида: её значения симметричны не относительно нуля, а относительно $0{,}5$.
Свойства и форма
- Область определения — все действительные числа; область значений — открытый интервал $(-1;\,1)$: значения $\pm1$ не достигаются.
- Нечётность: $\tanh(-x)=-\tanh x$, график симметричен относительно начала координат, $\tanh 0=0$.
- Монотонность: строго возрастает, потому что $\tanh' x=1-\tanh^2x>0$ при любом $x$.
- Асимптоты: $\lim_{x\to\pm\infty}\tanh x=\pm1$.
- Точка перегиба — единственная, $x=0$: при $x<0$ функция выпукла вниз, при $x>0$ — вверх.
- Липшицевость с константой 1: $|\tanh a-\tanh b|\le|a-b|$; в частности, $|\tanh x|\le|x|$, равенство только при $x=0$.
- Почти тождество около нуля: $\tanh x=x-\tfrac{x^3}{3}+\dots$ — при малых весах сеть из tanh ведёт себя почти как линейная.
Почему tanh x = 2σ(2x) − 1
Подставим определение сигмоиды $\sigma(u)=1/(1+e^{-u})$ при $u=2x$:
В предпоследнем шаге числитель и знаменатель умножены на $e^{x}$. Обратно: $\sigma(x)=\tfrac12\bigl(1+\tanh\tfrac x2\bigr)$. Значит, сеть со скрытыми tanh можно переписать в сеть со скрытыми сигмоидами той же выразительности — меняются только масштабы весов и сдвиги. Разница — в том, как идёт обучение (раздел о центрированности).
Обратная функция и формула сложения
Решим $y=\tanh x$ относительно $x$: из $y=\frac{e^{2x}-1}{e^{2x}+1}$ получаем $e^{2x}=\frac{1+y}{1-y}$, откуда
Например, $\operatorname{artanh}0{,}5\approx0{,}549$. Ещё одно полезное тождество — формула сложения:
Это ровно релятивистское сложение скоростей (в долях скорости света): $0{,}5c$ и $0{,}5c$ дают не $c$, а $\frac{0{,}5+0{,}5}{1+0{,}25}c=0{,}8c$. Сумма двух чисел из $(-1;\,1)$ «в мире tanh» никогда не выходит за его пределы.
Мягкий ограничитель: c · tanh(x / c)
Функция $c\tanh(x/c)$ около нуля почти не меняет вход ($\approx x$), а большие значения плавно прижимает к $\pm c$. В отличие от жёсткой обрезки $\operatorname{clip}(x,-c,c)$, у неё нет изломов и производная нигде не обнуляется скачком. Так в Gemma 2 ограничивают логиты внимания ($c=50$) и итоговые логиты ($c=30$), чтобы они не разрастались во время обучения.
Производная: tanh′ = 1 − tanh²
Главная формула страницы. Выведем её тремя способами — каждый пригодится в другом месте.
Способ 1. Производная частного
Пусть $u=e^{x}-e^{-x}$, $v=e^{x}+e^{-x}$. Тогда $u'=v$ и $v'=u$, и по правилу дифференцирования дроби:
Способ 2. Через основное гиперболическое тождество
Для гиперболических функций $\cosh^2x-\sinh^2x=1$ (проверьте подстановкой экспонент), $\sinh' x=\cosh x$ и $\cosh' x=\sinh x$. Тогда
Деля тождество на $\cosh^2x$, получаем $1-\tanh^2x=\operatorname{sech}^2x$ — та же формула в другой записи. Форма через $\operatorname{sech}^2$ полезна в коде при больших $|x|$.
Способ 3. Через сигмоиду
Из $\tanh x=2\sigma(2x)-1$ по правилу цепочки:
Отсюда сразу видно, почему максимум производной равен $4\cdot\tfrac14=1$, а не $\tfrac14$, как у сигмоиды: вдвое больший размах выхода и вдвое более сжатая шкала входа дают множитель 4.
На практике: на прямом проходе сеть уже посчитала $t=\tanh z$. На обратном проходе производная обходится одним умножением $1-t^2$ — без новых экспонент. Именно поэтому фреймворки хранят для обратного прохода выход tanh, а не его вход.
Вторая производная и самые крутые изгибы
Дифференцируя ещё раз: $\tanh'' x=-2\tanh x\,(1-\tanh^2x)$. Она равна нулю только при $x=0$ (точка перегиба), а экстремумы достигаются при $\tanh^2x=\tfrac13$, то есть $x=\pm\operatorname{artanh}\tfrac{1}{\sqrt3}\approx\pm0{,}658$; значения там $\mp\tfrac{4}{3\sqrt3}\approx\mp0{,}770$. В этих точках наклон уже $1-\tfrac13=\tfrac23$ и убывает быстрее всего: здесь прямая $y\approx x$ сменяется изгибом к насыщению.
Ряд Тейлора около нуля
Ряд сходится только при $|x|<\pi/2\approx1{,}571$: знаменатель $\cosh x$ обращается в ноль в комплексных точках $x=\pm i\pi/2$, и радиус сходимости равен расстоянию до ближайшей из них. Это в два раза меньше, чем у сигмоиды ($\pi$), — ведь tanh «сжат» по горизонтали в 2 раза.
Центрированность: почему tanh учится лучше сигмоиды
Рассмотрим нейрон следующего слоя: $z=\sum_i w_ia_i+b$, где $a_i$ — выходы предыдущего слоя. Градиент потери по весу равен
Если все $a_i>0$ (выходы сигмоиды), то на одном примере все компоненты градиента имеют один знак — знак $\delta$. Шаг SGD двигает все веса нейрона либо вверх, либо вниз. А если к оптимуму нужно одни веса увеличить, а другие уменьшить, остаётся идти зигзагом.
Второй взгляд — через форму поверхности потерь. Для линейного нейрона с квадратичной потерей $\tfrac12(w^\top a-y)^2$ матрица Гессе равна $\mathbb E[aa^\top]=\operatorname{Cov}(a)+\mu\mu^\top$, где $\mu$ — среднее входов. Ненулевое среднее добавляет одно большое собственное значение вдоль $\mu$, и «долина» вытягивается. Для входов $\sigma(z)$ ниже собственные значения $0{,}034$ и $0{,}530$ (число обусловленности 15,5), для $\tanh(z)$ — $0{,}340$ и $0{,}415$ (1,22).
Центрированные активации делают поверхность потерь следующего слоя «круглее», и градиентный спуск идёт к минимуму прямее. Это одна из причин, по которым tanh в скрытых слоях обучается быстрее сигмоиды (ЛеКун и др., «Efficient BackProp», 1998). Та же идея лежит в основе нормализации входов и BatchNorm.
Tanh на плоскости: складки, гребни и холмы
Нейрон с двумя входами считает $\tanh(w_1x_1+w_2x_2+b)$. На плоскости это складка: поверхность переходит от $-1$ к $+1$ поперёк прямой $w^\top x+b=0$ и не меняется вдоль неё. Сумма двух противоположных складок даёт гребень, а четыре складки и ещё один tanh на выходе — холм, отличный от $-1$ только в квадрате.
Так работает теорема об универсальной аппроксимации (Цыбенко, 1989; Хорник, 1991): сеть с одним скрытым слоем из достаточно большого числа нейронов с tanh приближает любую непрерывную функцию на ограниченном замкнутом множестве с любой точностью. Холмы складываются из складок, а из холмов можно собрать любой рельеф. Наш холм использует второй tanh на выходе ради наглядности, но теореме хватает и одного скрытого слоя с линейным выходом. Она говорит, что такие веса существуют, но не говорит, сколько нужно нейронов и найдёт ли их обучение.
Tanh в обучении: активации по слоям и подгонка кривой
Что происходит с сигналом в глубокой сети
Пусть веса слоя выбраны случайно с дисперсией $g^2/n$, где $n$ — число входов нейрона. Если $g$ мал, сигнал затухает от слоя к слою и tanh работает как почти линейная функция. Если $g$ велик, входы нейронов большие, и tanh уходит в насыщение: выходы прилипают к $\pm1$, производные почти нулевые.
Поэтому для tanh берут инициализацию Глоро (Xavier), $\operatorname{Var}w=\frac{2}{n_\text{in}+n_\text{out}}$, а PyTorch советует умножать её на усиление $g=5/3$ (calculate_gain('tanh')): множитель компенсирует то, что tanh сжимает сигнал. Для квадратного слоя это ровно случай $g=5/3$ на рисунке 6.
Сеть из tanh подгоняет кривую
Скрытый слой из $H$ нейронов и линейный выход: $\hat y(x)=\sum_{k=1}^{H}v_k\tanh(w_kx+b_k)+c$. Каждое слагаемое — «ступенька» с плавными краями; обучение двигает, растягивает и масштабирует ступеньки так, чтобы их сумма легла на данные.
Длинные плато на кривой потерь часто означают, что часть нейронов работает на плоских хвостах tanh: их производная мала, и градиент почти не сдвигает их параметры. Помогают нормализация входов, аккуратная инициализация и адаптивные оптимизаторы вроде Adam.
Tanh в рекуррентных сетях и LSTM
Простая рекуррентная сеть обновляет состояние по одной и той же формуле на каждом шаге: $h_t=\tanh(Wh_{t-1}+Ux_t+b)$. Tanh здесь работает как предохранитель: каким бы длинным ни был текст, состояние остаётся в $(-1;\,1)$ и не «взрывается». Но за ограниченность приходится платить градиентом (множители перемножаются от $s=T$ слева до $s=t+1$ справа):
Каждый множитель содержит $1-h_s^2\le1$. Если веса малы, произведение затухает экспоненциально. Если веса велики, состояния прижимаются к $\pm1$, $1-h_s^2\to0$ — и градиент тоже гаснет. Выживает он только в узком окне между этими режимами. В многомерной RNN у границы этого окна градиент может и взрываться (Паскану и др., 2013), поэтому вместе с tanh применяют обрезку нормы градиента.
LSTM решает эту проблему отдельной «магистралью» — состоянием ячейки $c_t$, которое обновляется сложением, а не через tanh:
Здесь $f_t,i_t,o_t\in(0;\,1)$ — вентили на сигмоидах, а tanh выполняет две роли: кандидат $g_t\in(-1;\,1)$ может и увеличить, и уменьшить память (сигмоида умела бы только добавлять), а $\tanh(c_t)$ ограничивает выход. Вдоль цепочки $c_{t-1}\to c_t$ градиент умножается на $f_t$ (если не учитывать зависимость вентилей от $h_{t-1}$), без множителя $\tanh'$, поэтому при $f_t\approx1$ он доходит до далёких шагов.
Ян ЛеКун в 1998 году советовал масштабированный тангенс $1{,}7159\tanh(2x/3)$: он даёт $f(\pm1)=\pm1$ и почти единичную дисперсию выхода. LSTM (Хохрайтер и Шмидхубер, 1997) сделала tanh стандартом рекуррентных сетей на два десятилетия. В свёрточных сетях его вытеснил ReLU: в статье об AlexNet (2012) четырёхслойная свёрточная сеть с ReLU достигла ошибки 25% на обучающей выборке CIFAR-10 в 6 раз быстрее такой же сети с tanh.
В коде: устойчиво и без сюрпризов
Наивная формула через экспоненты при $x=1000$ вычисляет $e^{1000}=\infty$, и получается $\infty/\infty=\text{nan}$. Встроенные np.tanh и torch.tanh устойчивы: при $x\gtrsim19$ они возвращают ровно $1{,}0$ в float64. Но тогда $1-\tanh^2 x$ даёт ровно 0, хотя истинное значение при $x=20$ — около $1{,}7\cdot10^{-17}$. Если нужна производная на далёких хвостах, считайте её через $\operatorname{sech}^2$ в устойчивой форме.
pythonimport numpy as np
def tanh_grad_from_output(t):
"""Производная через уже посчитанный выход t = tanh(x): одно умножение."""
return 1.0 - t * t
def tanh_grad(x):
"""sech²x = 4e^(−2|x|) / (1 + e^(−2|x|))²:
без переполнения и без потери точности."""
e = np.exp(-2.0 * np.abs(x))
return 4.0 * e / (1.0 + e) ** 2
def naive_tanh(x):
return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))
print(naive_tanh(1000.0)) # nan: inf / inf (и предупреждение о переполнении)
print(np.tanh(1000.0)) # 1.0 — встроенная функция устойчива
print(1 - np.tanh(20.0) ** 2) # 0.0: tanh(20) в float64 округляется до 1
print(tanh_grad(20.0)) # 1.6993417021166355e-17 — верное значение
pythonimport torch
import torch.nn as nn
x = torch.tensor([-2.0, 0.0, 2.0], requires_grad=True)
y = torch.tanh(x) # tensor([-0.9640, 0.0000, 0.9640])
y.sum().backward()
print(x.grad) # tensor([0.0707, 1.0000, 0.0707]) = 1 − tanh²
# Инициализация под tanh: усиление 5/3
layer = nn.Linear(256, 256)
nn.init.xavier_uniform_(layer.weight, gain=nn.init.calculate_gain("tanh"))
# Рекуррентная сеть с tanh и обрезка градиента от взрыва
rnn = nn.RNN(input_size=32, hidden_size=64, nonlinearity="tanh", batch_first=True)
out, h = rnn(torch.randn(8, 100, 32)) # 8 последовательностей длины 100
out.pow(2).mean().backward()
nn.utils.clip_grad_norm_(rnn.parameters(), max_norm=1.0)
Используйте встроенный tanh и автоматическое дифференцирование; на обратном проходе — формулу $1-t^2$ от сохранённого выхода. Для tanh-сетей — инициализация Глоро (Xavier) с усилением $5/3$, для RNN — обрезка нормы градиента.
Частые ошибки
- tanh на выходе вместо сигмоиды для вероятности. Выход tanh лежит в $(-1;\,1)$ и не является вероятностью. Для бинарной классификации нужна сигмоида и BCE; tanh на выходе уместен, если цели нормированы в $[-1;\,1]$.
- Производная по входу вместо выхода. Формула $1-t^2$ применяется к выходу $t=\tanh x$. Частая опечатка — $1-x^2$ от входа: при $x=2$ она даёт $-3$ вместо $0{,}071$.
- Ненормированные входы и крупные веса. Если признаки порядка сотен или веса слишком велики, tanh с первых шагов насыщен и почти не учится. Стандартизируйте данные и берите инициализацию под tanh.
- «tanh решает проблему затухания». Он лучше сигмоиды (производная до 1 и центрированность), но тоже насыщается. Для глубоких сетей — ReLU-семейство, нормализация и остаточные связи; для последовательностей — LSTM/GRU.
- Самописный tanh через exp. Даёт nan при больших $|x|$. Пользуйтесь
np.tanh,torch.tanh.
Связи с другими формулами
- Сигмоида: $\tanh x=2\sigma(2x)-1$ и $\sigma(x)=\tfrac12(1+\tanh\tfrac x2)$; производные связаны как $\tanh' x=4\sigma'(2x)$.
- ReLU: не насыщается при $x>0$ и вытеснил tanh из глубоких свёрточных сетей.
- GELU: популярное приближение $0{,}5x\bigl(1+\tanh\bigl(\sqrt{2/\pi}\,(x+0{,}044715x^3)\bigr)\bigr)$.
- SiLU: $x\sigma(x)=\tfrac x2\bigl(1+\tanh\tfrac x2\bigr)$ — та же S-кривая в роли «мягкого вентиля».
- MSE: естественная пара для выхода tanh при целях в $[-1;\,1]$.
- Adam: оптимизатор из рисунка 7; адаптивный шаг помогает проходить плато, созданные насыщением.
Итоги
1) $\tanh x=\frac{e^x-e^{-x}}{e^x+e^{-x}}=\frac{\sinh x}{\cosh x}=2\sigma(2x)-1$ отображает $\mathbb R$ в $(-1;\,1)$, нечётен и проходит через ноль. 2) $\tanh'=1-\tanh^2\le1$, максимум в нуле, на хвостах — насыщение. 3) Ряд Тейлора $x-\frac{x^3}{3}+\dots$ сходится при $|x|<\pi/2$. 4) Центрированные выходы делают обучение следующего слоя быстрее, чем у сигмоиды. 5) Суммы tanh-складок приближают любую непрерывную функцию на компакте; инициализация — Глоро (Xavier) с усилением $5/3$. 6) В RNN tanh держит состояние ограниченным, но градиент через время гаснет — отсюда LSTM.