Шпаргалка формул нейросетей · Потери — регрессия

Функция потерь Хьюбера: мост между MSE и MAE

Парабола в середине и прямые по краям. Разбираем, почему у стыка совпадают и значения, и наклоны, как порог δ обрезает градиент выбросов, почему оценка Хьюбера — компромисс между средним и медианой, откуда берётся магическое 1,345σ и где эта потеря работает сегодня — от робастной регрессии до Fast R-CNN и DQN.

Javharbek Abdulatipov · 35 мин чтения
$$L_\delta(r)=\begin{cases}\tfrac12 r^2, & |r|\le\delta\\[1mm] \delta\bigl(|r|-\tfrac12\delta\bigr), & |r|>\delta\end{cases}$$

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

Регрессия учится на ошибках $r=y-\hat y$. Две классические потери отвечают на вопрос «как штрафовать ошибку» по-разному. MSE штрафует квадратом: она гладкая, её градиент пропорционален ошибке и плавно затухает у минимума, но один выброс с ошибкой 10 весит как сто ошибок размером 1. MAE штрафует модулем: выбросы ей почти безразличны, зато в нуле у неё излом, а градиент всегда одного размера — модели трудно «доводить» мелкие ошибки.

Питер Хьюбер в 1964 году предложил взять лучшее от обеих: парабола для малых ошибок и прямая для больших, с переключением на пороге $\delta$. Где эта идея работает сегодня:

  • робастная регрессия — HuberRegressor в scikit-learn, M-оценки (M-estimators) в статистике;
  • детекция объектов — Smooth L1 в Fast R-CNN и его потомках для регрессии координат рамок; это Хьюбер с точностью до множителя;
  • обучение с подкреплением — в DQN ошибку временной разности (temporal-difference error, TD) обрезают до $[-1;\,1]$, что равносильно потере Хьюбера с $\delta=1$;
  • градиентный бустинг — loss='huber' в scikit-learn, objective='huber' в LightGBM, псевдо-Хьюбер в XGBoost;
  • любые данные с аномалиями — цены недвижимости, показания датчиков, разметка с опечатками.
Главное за минуту

$L_\delta(r)$ равна $\tfrac12r^2$ при $|r|\le\delta$ и $\delta(|r|-\tfrac12\delta)$ дальше. В точке $|r|=\delta$ совпадают и значения ($\tfrac12\delta^2$), и наклоны ($\delta$). Производная $\psi(r)=\operatorname{clip}(r,-\delta,\delta)$ ограничена: выброс тянет модель не сильнее, чем на $\delta$. Малое $\delta$ — ближе к MAE, большое — к MSE.

Интуиция: парабола с прямыми хвостами

Представьте пружину, которая тянет прогноз к ответу. Пока ошибка мала, пружина обычная: чем дальше растянута, тем сильнее тянет — это парабола $\tfrac12r^2$. Но у пружины есть предохранитель: после растяжения $\delta$ сила перестаёт расти и остаётся равной $\delta$. Энергия такой пружины дальше растёт уже линейно — это прямые хвосты.

Потяните точку по графику и подвигайте $\delta$. Синяя кривая лежит на серой параболе внутри бирюзовой полосы $|r|\le\delta$ и на пунктирной прямой $\delta(|r|-\delta/2)$ снаружи. Оранжевая касательная проходит стык без излома.

Рисунок 1. Потеря Хьюбера $L_\delta(r)$ и её производные. Внизу: оранжевая $\psi(r)=L'_\delta(r)$ — наклонная внутри полосы и горизонтальная снаружи; фиолетовая $L''_\delta$ — ступенька: 1 внутри, 0 снаружи. При $\delta=1$ и $r=2$: $L=1{,}5$ вместо $\tfrac12r^2=2$, а наклон равен 1, а не 2.
Что заметить

На стыке $|r|=\delta$ кривая переходит с параболы на прямую плавно: прямая $\delta(|r|-\delta/2)$ — это касательная к параболе в точке $r=\pm\delta$. Излом есть только у второй производной: кривизна прыгает с 1 до 0.

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

$$L_\delta(r)=\begin{cases}\tfrac12 r^2, & |r|\le\delta,\\[1mm] \delta\bigl(|r|-\tfrac12\delta\bigr), & |r|>\delta,\end{cases}\qquad r=y-\hat y$$
$r=y-\hat y$
остаток (residual): насколько ответ $y$ выше прогноза $\hat y$; потеря зависит только от $|r|$, знак не важен;
$\delta>0$
порог: ошибки меньше $\delta$ считаются «обычным шумом», больше — подозрительными; измеряется в единицах $y$;
$\tfrac12 r^2$
квадратичная ветвь — ровно половина квадрата ошибки, как в MSE; множитель $\tfrac12$ делает производную равной $r$;
$\delta|r|$
линейная ветвь — модуль ошибки с весом $\delta$, как в MAE;
$-\tfrac12\delta^2$
сдвиг вниз, который сшивает ветви: без него прямая $\delta|r|$ при $|r|=\delta$ давала бы $\delta^2$, а парабола — $\tfrac12\delta^2$.

Проверим сшивку. При $|r|=\delta$ квадратичная ветвь даёт $\tfrac12\delta^2$, линейная — $\delta(\delta-\tfrac12\delta)=\tfrac12\delta^2$: значения равны. Производные: $r=\delta$ у параболы и $\delta\operatorname{sign}r=\delta$ у прямой — равны и наклоны. Константу $-\tfrac12\delta^2$ выбрали именно так, чтобы прямая стала касательной к параболе.

$r$$\tfrac12r^2$$|r|$$L_1(r)$$\psi_1(r)$
00000
0,50,1250,50,1250,5
10,510,51
2221,51
34,532,51
512,554,51
1050109,51

Таблица для $\delta=1$ показывает главное: при ошибке 10 квадрат даёт 50, а Хьюбер — 9,5; при этом производная (последний столбец) никогда не превышает 1.

Сквозной пример

Возьмём пример из шпаргалки: $y=(3;\,5;\,8)$, $\hat y=(2{,}5;\,5;\,10)$, ошибки $r=(0{,}5;\,0;\,-2)$. При $\delta=1$ первая ошибка попадает в параболу: $\tfrac12\cdot0{,}5^2=0{,}125$; вторая — ноль; третья, $|r|=2>1$, — в прямую: $1\cdot(2-0{,}5)=1{,}5$. Среднее $(0{,}125+0+1{,}5)/3\approx0{,}542$.

Интереснее градиенты. В половине MSE они равны самим ошибкам: $(0{,}5;\,0;\,-2)$ — выброс тянет вчетверо сильнее первой точки. У Хьюбера $\psi=(0{,}5;\,0;\,-1)$ — только вдвое: большой промах не может перекричать остальных.

Масштаб: одна кривая на все δ

Если измерять ошибку в единицах порога, все потери Хьюбера — одна и та же кривая:

$$L_\delta(r)=\delta^2\,L_1\!\left(\frac{r}{\delta}\right)$$

Поэтому $\delta$ нельзя выбрать «вообще»: он зависит от единиц $y$. Ошибка в 1 рубль и в 1 миллион рублей — разные вещи. Обычно $\delta$ задают в долях типичного разброса шума $\sigma$ (раздел про выбор $\delta$).

Свойства

  • Неотрицательна и чётна: $L_\delta(r)\ge0$, $L_\delta(-r)=L_\delta(r)$, минимум $0$ только при $r=0$.
  • Выпукла: парабола и касательная к ней склеены без «впадины»; значит, у линейной регрессии с потерей Хьюбера нет ложных локальных минимумов.
  • Гладкость $C^1$, но не $C^2$: первая производная непрерывна, вторая прыгает с 1 на 0 при $|r|=\delta$.
  • Зажата между параболой и прямой: $\delta|r|-\tfrac12\delta^2\le L_\delta(r)\le\tfrac12r^2$; разность с каждой из них равна $\tfrac12(|r|-\delta)^2$ там, где кривая с ней не совпадает.
  • Ограниченная производная: $|L'_\delta(r)|\le\delta$ — главное свойство для робастности.
  • Пределы: при $\delta\to\infty$ $L_\delta(r)\to\tfrac12r^2$ (MSE), при $\delta\to0$ $L_\delta(r)/\delta\to|r|$ (MAE).
Почему кривая зажата и откуда пределы

При $|r|>\delta$: $\tfrac12r^2-\bigl(\delta|r|-\tfrac12\delta^2\bigr)=\tfrac12(|r|-\delta)^2\ge0$, то есть прямая лежит под параболой. При $|r|\le\delta$ то же выражение показывает, что парабола лежит над прямой. Значит, $L_\delta$ всегда между ними и совпадает с каждой на своём участке.

Пределы: если $\delta\ge|r|$, то $L_\delta(r)=\tfrac12r^2$ ровно — достаточно большого порога. Если $\delta<|r|$, то $L_\delta(r)/\delta=|r|-\tfrac12\delta\to|r|$ при $\delta\to0$.

Хьюбер как «смягчённый модуль» (огибающая Моро)

Есть изящная эквивалентная запись: потеря Хьюбера — это лучший компромисс, если часть ошибки $z$ разрешено «списать» по цене модуля:

$$L_\delta(r)=\min_{z\in\mathbb R}\Bigl(\tfrac12(r-z)^2+\delta|z|\Bigr)$$

Минимум достигается при мягком пороге $z^*=\operatorname{sign}(r)\max(|r|-\delta,\,0)$. Если $|r|\le\delta$, то $z^*=0$ и остаётся $\tfrac12r^2$. Иначе $z^*=r-\delta\operatorname{sign}r$, и получаем $\tfrac12\delta^2+\delta(|r|-\delta)=\delta|r|-\tfrac12\delta^2$. В выпуклом анализе это называют огибающей Моро (Moreau envelope) функции $\delta|\cdot|$: так из негладкого модуля получают гладкую функцию с тем же поведением на бесконечности.

Модельная интерпретация: $y=\hat y+\text{шум}+z$, где $z$ — редкая «аномалия». Потеря Хьюбера сама решает, какую часть ошибки объяснить аномалией, а какую — гауссовым шумом.

Производная: обрезанный остаток

Производную по остатку в статистике обозначают $\psi$ и называют ψ-функцией оценки; ей пропорциональна функция влияния (influence function) $\mathrm{IF}(x)=\psi(x-\mu)/\mathbb E\,\psi'$. Обе показывают, с какой силой одна точка тянет оценку.

$$\psi_\delta(r)=L'_\delta(r)=\begin{cases}r, & |r|\le\delta,\\ \delta\operatorname{sign}r, & |r|>\delta\end{cases}=\operatorname{clip}(r,\,-\delta,\,\delta)$$
Вывод по шагам

Внутри полосы $(\tfrac12r^2)'=r$. Снаружи $|r|$ дифференцируем как $\operatorname{sign}r$, поэтому $\bigl(\delta|r|-\tfrac12\delta^2\bigr)'=\delta\operatorname{sign}r$. В точках $r=\pm\delta$ левая и правая производные совпадают ($\pm\delta$), значит, производная существует и непрерывна.

По прогнозу — цепное правило: $\dfrac{\partial L_\delta}{\partial\hat y}=\psi_\delta(r)\cdot\dfrac{\partial r}{\partial\hat y}=-\psi_\delta(y-\hat y)$.

Вторая производная: $L''_\delta(r)=1$ при $|r|<\delta$ и $0$ при $|r|>\delta$; в точках $\pm\delta$ её нет — левая и правая не совпадают.

$$\frac{\partial L_\delta}{\partial\hat y}=-\operatorname{clip}\bigl(y-\hat y,\,-\delta,\,\delta\bigr)$$

Сравните три потери. У MSE ($\tfrac12r^2$) тяга $\psi=r$ растёт без предела. У MAE тяга постоянна. У Хьюбера она растёт, пока точка «своя», и замирает на уровне $\delta$, когда точка подозрительна. Вторая полезная картинка — вес точки $w(r)=\psi(r)/r$: какую долю «голоса» точка получает по сравнению с обычным методом наименьших квадратов (МНК).

Рисунок 2. Слева — тяга $\psi(r)$, справа — вес $w(r)=\psi(r)/r$. Точка с ошибкой $r=4$ при $\delta=1$ тянет в MSE с силой 4, у Хьюбера — с силой 1, то есть получает вес $0{,}25$. Внутри полосы $|r|\le\delta$ вес равен 1: обычные точки Хьюбер не трогает.
Почему ψ важнее самой потери

Оптимум модели определяется уравнением $\sum_i\psi(r_i)\,\partial\hat y_i/\partial\theta=0$, а не значением потери. Поэтому робастность — это свойство $\psi$: ограниченная $\psi$ значит, что никакой одиночный выброс по $y$ не может сдвинуть решение сколь угодно далеко (выбросы в признаках — другая история, см. «Частые ошибки»). У MSE $\psi$ не ограничена, и один выброс сдвигает среднее куда угодно.

Поверхность L(r, δ) в 3D

Посмотрим на потерю как на функцию двух переменных — ошибки $r$ и порога $\delta$. Это помогает увидеть сразу всё семейство кривых и то, как порог меняет форму.

Рисунок 3. Слева — поверхность $L_\delta(r)$ (её можно вращать), оранжевые линии — стык $|r|=\delta$, синяя — срез при выбранном $\delta$. Справа — вид сверху с линиями уровня. Внутри «клина» $|r|\le\delta$ линии вертикальны, снаружи изгибаются. Переключите на псевдо-Хьюбера: стыка больше нет, поверхность гладкая всюду.

Две вещи видны сразу. Во-первых, внутри «клина» $|r|\le\delta$ поверхность не зависит от $\delta$: там всегда $\tfrac12r^2$, и линии уровня $L=c$ — вертикальные отрезки $r=\pm\sqrt{2c}$ (при $\delta\ge\sqrt{2c}$). Во-вторых, снаружи линия уровня $L=c$ — это $|r|=c/\delta+\delta/2$: чем меньше порог, тем дальше нужно уйти, чтобы набрать ту же потерю.

Многомерный случай

Когда ответ — вектор (например, четыре координаты рамки в детекции), потерю Хьюбера обычно считают по каждой координате и складывают: $\sum_jL_\delta(r_j)$. Линии уровня такой суммы на плоскости $(r_1,r_2)$ — квадраты со скруглёнными углами, а градиент обрезается по каждой координате отдельно. Это не то же самое, что $L_\delta(\|r\|)$, где обрезается длина всего вектора ошибки.

Оценка Хьюбера и выбор δ

Хьюбер придумал свою функцию для простейшей задачи статистики — оценки центра выборки $x_1,\dots,x_n$. Если минимизировать $\sum(x_i-\mu)^2$, получится среднее; если $\sum|x_i-\mu|$ — медиана. Оценка Хьюбера $\hat\mu$ минимизирует $\sum L_\delta(x_i-\mu)$, то есть решает уравнение

$$\sum_{i=1}^{n}\psi_\delta(x_i-\hat\mu)=0$$

Точки внутри зоны $|x_i-\hat\mu|\le\delta$ участвуют как в среднем, а дальние — только знаком, с силой $\delta$, как в медиане.

Рисунок 4. 13 значений вокруг 5 и два выброса (красные; правый можно тянуть). Высота столбика — вес точки в оценке. При $\delta=1$: среднее $6{,}079$, медиана $5{,}557$, оценка Хьюбера $5{,}369$ — ближе всех к истинному центру 5. Справа — путь $\hat\mu(\delta)$: при $\delta\to0$ оценка стремится к медиане, а при $\delta\ge7{,}421$ совпадает со средним.

Обратите внимание на правый график: путь $\hat\mu(\delta)$ не обязан лежать между медианой и средним — при $\delta=1$ оценка ниже обоих. Предельные значения точные: при $\delta\to0$ получается медиана, а как только $\delta$ превышает расстояние от среднего до самой дальней точки (здесь $13{,}5-6{,}079\approx7{,}421$), все точки в квадратичной зоне и $\hat\mu$ равна среднему.

Сколько стоит робастность: правило 1,345σ

Если данные на самом деле нормальные, без выбросов, лучшая оценка — среднее. Насколько Хьюбер хуже? Это измеряют асимптотической эффективностью (asymptotic efficiency): отношением дисперсии среднего к дисперсии оценки. Для $\psi$ с порогом $k$ (в единицах $\sigma$) при стандартной нормальной $X$:

$$\operatorname{Var}\hat\mu\approx\frac{\sigma^2}{n}\cdot\frac{\mathbb E\,\psi_k(X)^2}{\bigl(\mathbb E\,\psi'_k(X)\bigr)^2},\qquad \mathbb E\,\psi'_k=2\Phi(k)-1,\quad \mathbb E\,\psi_k^2=2\Phi(k)-1-2k\varphi(k)+2k^2\bigl(1-\Phi(k)\bigr)$$

Решая «эффективность $=95\%$», получаем $k\approx1{,}345$. Отсюда классический выбор $\delta=1{,}345\,\sigma$: всего 5% потерь на чистых данных в обмен на защиту от выбросов. У медианы эффективность $2/\pi\approx64\%$.

Рисунок 5. Дисперсия оценки центра (в единицах $\sigma^2/n$) для смеси $(1-\varepsilon)N(0,1)+\varepsilon N(0,10^2)$. При $k=1{,}345$ эффективность на чистых данных — $95{,}0\%$. При $\varepsilon=0{,}05$ дисперсия среднего $5{,}95$, медианы $1{,}722$, Хьюбера с $k=1{,}345$ — $1{,}229$; лучший порог для этой смеси $k\approx1{,}48$ (полый кружок).
Минимакс Хьюбера

В статье 1964 года Хьюбер доказал больше: если неизвестно, какие именно выбросы встретятся, а известна лишь их доля $\varepsilon$, то среди M-оценок оценка с $\psi_k$ минимизирует наихудшую асимптотическую дисперсию по всем симметричным засорениям $(1-\varepsilon)N(0,1)+\varepsilon H$. Порог связан с долей уравнением $2\varphi(k)/k-2\Phi(-k)=\varepsilon/(1-\varepsilon)$: для $\varepsilon=0{,}05$ это $k\approx1{,}40$, для $\varepsilon=0{,}01$ — $k\approx1{,}95$.

σ тоже нужно оценить робастно

Правило $\delta=1{,}345\sigma$ бесполезно, если $\sigma$ посчитать обычным стандартным отклонением: выбросы раздуют его. Используют медианное абсолютное отклонение: $\hat\sigma=\operatorname{MAD}/0{,}6745\approx1{,}4826\cdot\operatorname{median}|r_i-\operatorname{median}(r)|$. В HuberRegressor масштаб оценивается совместно с коэффициентами, а epsilon=1.35 по умолчанию — это и есть $k$.

Хьюбер в обучении

Обучим прямую градиентным спуском двумя способами — на половине MSE и на потере Хьюбера — по одним и тем же данным: 30 точек вокруг $y=1+0{,}5x$ с шумом $\sigma=0{,}5$ и три выброса внизу справа. Порог $\delta=0{,}7\approx1{,}345\cdot0{,}5$.

Рисунок 6. Нажмите «Пуск». Обе модели стартуют с прямой $y=0$ и делают одинаковые шаги ($\eta=0{,}15$). MSE быстро сходится к наклону $0{,}363$ — выбросы опрокидывают прямую. Хьюбер сначала идёт медленнее (все ошибки большие, и каждая тянет не сильнее $\delta$), но приходит к наклону $0{,}511$ при истинном $0{,}5$. Перетащите крайний выброс — во время обучения или до него.

Шаг спуска показывает механизм: каждая точка тянет параметры пропорционально $\psi(r_i)$. Пока прямая далеко от всех точек, у Хьюбера все тяги равны $\pm\delta$ — он движется как MAE, с постоянной скоростью. Когда прямая подходит к основной массе точек, их ошибки попадают в квадратичную зону и спуск становится обычным МНК — уже без выбросов, которые так и остались «на привязи» $\delta$.

$$\theta\leftarrow\theta+\eta\,\frac1n\sum_{i=1}^{n}\psi_\delta\bigl(y_i-\hat y_i\bigr)\,\frac{\partial\hat y_i}{\partial\theta}$$
IRLS: Хьюбер как МНК с весами

Для линейной модели $\hat y_i=x_i^\top\beta$ условие оптимума $\sum_i\psi(r_i)x_i=0$ можно переписать как $\sum_iw_ir_ix_i=0$ с весами $w_i=\psi(r_i)/r_i=\min(1,\delta/|r_i|)$. Если веса заморозить, это нормальные уравнения взвешенного МНК, решаемые явно:

$$\beta^{(t+1)}=\bigl(X^\top W^{(t)}X\bigr)^{-1}X^\top W^{(t)}y,\qquad W^{(t)}=\operatorname{diag}\bigl(w_i(\beta^{(t)})\bigr)$$

Итерации «посчитать остатки → обновить веса → решить МНК» (iteratively reweighted least squares) сходятся к оценке Хьюбера за десяток шагов. Веса здесь те же, что на рисунке 2 справа.

Где ещё Хьюбер работает внутри обучения

  • Градиентный бустинг. Каждое новое дерево учится на антиградиенте потери. Для Хьюбера это $\psi(r_i)$ — обрезанные остатки, поэтому одно аномальное значение не заставляет дерево тратить лист на выброс. В scikit-learn порог $\delta$ на каждой итерации берут как $\alpha$-квантиль $|r_i|$ (по умолчанию $\alpha=0{,}9$).
  • DQN. В статье DeepMind (2015) ошибку временной разности обрезали до $[-1;\,1]$. Обрезанный градиент — это ровно $\psi_1$, то есть обучение на потере Хьюбера с $\delta=1$: единичная огромная ошибка TD (например, когда целевая сеть резко сменилась) не даёт взрывного шага, и обучение устойчивее.
  • Fast R-CNN. Для регрессии координат рамки Гиршик (2015) взял Smooth L1: она «менее чувствительна к выбросам, чем L2» и не требует аккуратной настройки темпа обучения, чтобы избежать взрыва градиентов.

Гладкие родственники: псевдо-Хьюбер, log-cosh, Smooth L1

Скачок второй производной не мешает градиентному спуску, но мешает методам второго порядка. XGBoost и LightGBM делают шаг Ньютона: лист получает значение $-\sum g_i/\sum h_i$, где $h_i$ — вторые производные. Истинная вторая производная Хьюбера для всех выбросов равна нулю, и если в лист попали только они, знаменатель обнуляется (в XGBoost от него остаётся лишь регуляризатор $\lambda$). Поэтому реализации либо подменяют её константой (так поступает LightGBM в objective='huber'), либо берут гладкий вариант.

$$\text{псевдо-Хьюбер: }\;\delta^2\Bigl(\sqrt{1+(r/\delta)^2}-1\Bigr),\qquad \text{log-cosh: }\;\delta^2\ln\cosh\frac{r}{\delta},\qquad \text{Smooth L1: }\;\frac{L_\beta(r)}{\beta}$$
Рисунок 7. Хьюбер и его родственники при одинаковом $\delta$. Псевдо-Хьюбер и log-cosh тоже ведут себя как $\tfrac12r^2$ у нуля и как $\delta|r|$ на хвостах, но переход плавный, а вторая производная (галочка внизу) непрерывна. При $\delta=1$, $r=3$: Хьюбер $2{,}5$, псевдо-Хьюбер $2{,}162$, log-cosh $2{,}309$.
  • Псевдо-Хьюбер (в компьютерном зрении с точностью до множителя $\delta$ — потеря Шарбоннье $\sqrt{r^2+\delta^2}-\delta$): производная $r/\sqrt{1+(r/\delta)^2}$ стремится к $\pm\delta$ медленно; вторая производная $(1+(r/\delta)^2)^{-3/2}$ всюду положительна. В XGBoost — objective='reg:pseudohubererror' с параметром huber_slope ($=\delta$).
  • log-cosh: производная $\delta\tanh(r/\delta)$ — гладкое «обрезание»; на хвостах $\delta^2\ln\cosh(r/\delta)\approx\delta|r|-\delta^2\ln2$.
  • Smooth L1: это Хьюбер, делённый на $\beta$: $\tfrac{0{,}5r^2}{\beta}$ при $|r|<\beta$ и $|r|-\tfrac12\beta$ дальше. При $\beta\to0$ она стремится к $|r|$ (а Хьюбер — к нулю). В PyTorch: HuberLoss(delta=δ) = δ · SmoothL1Loss(beta=δ).

В коде

Сама формула — одна строка с np.where. Градиент — np.clip. Ниже — реализация, проверка на сквозном примере и регрессия Хьюбера через IRLS.

pythonimport numpy as np

def huber(r, delta=1.0):
    """Потеря Хьюбера для остатков r = y − ŷ (поэлементно)."""
    a = np.abs(r)
    return np.where(a <= delta, 0.5 * r**2, delta * (a - 0.5 * delta))

def huber_grad(r, delta=1.0):
    """ψ(r) = dL/dr — остаток, обрезанный до [−δ, δ]. По ŷ — со знаком минус."""
    return np.clip(r, -delta, delta)

def pseudo_huber(r, delta=1.0):
    return delta**2 * (np.sqrt(1.0 + (r / delta)**2) - 1.0)

y     = np.array([3.0, 5.0, 8.0])
y_hat = np.array([2.5, 5.0, 10.0])
r = y - y_hat               # [ 0.5  0.  -2. ]
print(huber(r))             # [0.125 0.    1.5  ]
print(huber(r).mean())      # 0.5416666666666666
print(huber_grad(r))        # [ 0.5  0.  -1. ]
pythondef huber_regression(X, y, delta=1.345, iters=50):
    """Регрессия Хьюбера методом IRLS: МНК с весами w_i = min(1, δ·s/|r_i|)."""
    X1 = np.column_stack([np.ones(len(X)), X])
    beta = np.linalg.lstsq(X1, y, rcond=None)[0]           # старт — обычный МНК
    for _ in range(iters):
        r = y - X1 @ beta
        s = np.median(np.abs(r - np.median(r))) / 0.6745   # робастный масштаб (MAD)
        w = np.minimum(1.0, delta * s / np.maximum(np.abs(r), 1e-12))
        sw = np.sqrt(w)
        beta = np.linalg.lstsq(X1 * sw[:, None], y * sw, rcond=None)[0]
    return beta

rng = np.random.default_rng(0)
x = np.linspace(0, 10, 30)
y = 1 + 0.5 * x + rng.normal(0, 0.5, 30)
y[-3:] -= 6                                                # три выброса
X1 = np.column_stack([np.ones(30), x])
print(np.linalg.lstsq(X1, y, rcond=None)[0].round(3))      # [1.931 0.182] — МНК
print(huber_regression(x, y).round(3))                     # [1.134 0.442] — Хьюбер
pythonimport torch
import torch.nn as nn

y_hat = torch.tensor([2.5, 5.0, 10.0], requires_grad=True)
y = torch.tensor([3.0, 5.0, 8.0])

loss = nn.HuberLoss(delta=1.0)(y_hat, y)   # среднее: 0.5417
loss.backward()
print(y_hat.grad)       # tensor([-0.1667,  0.0000,  0.3333]) = ψ(ŷ − y) / n

# Smooth L1 из Fast R-CNN — это Хьюбер, делённый на β (β = δ):
huber2 = nn.HuberLoss(delta=2.0)(y_hat, y)        # 0.7083
sl1_2 = nn.SmoothL1Loss(beta=2.0)(y_hat, y)       # 0.3542 = 0.7083 / 2
Готовые реализации

PyTorch: nn.HuberLoss(delta), nn.SmoothL1Loss(beta). Keras: keras.losses.Huber(delta). scikit-learn: HuberRegressor(epsilon=1.35), GradientBoostingRegressor (loss='huber', alpha=0.9). LightGBM: objective='huber' (порог — параметр alpha). XGBoost: objective='reg:pseudohubererror'.

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

  1. δ без учёта масштаба. $\delta=1$ для цен в долларах и для цен в миллионах — совершенно разные потери. Нормируйте целевую переменную или задавайте $\delta$ в единицах робастного разброса.
  2. Путаница Huber и Smooth L1. При одинаковом пороге они отличаются множителем: Smooth L1 $=$ Хьюбер$/\beta$, поэтому при $\beta>1$ её потеря и градиент меньше, а при $\beta<1$ — больше (при $\beta=1/9$, как в RPN Faster R-CNN, — в 9 раз). Меняя одну на другую, пересчитайте темп обучения.
  3. Оценка σ обычным std для правила $1{,}345\sigma$ — выбросы раздувают std, порог получается слишком большим, и защита исчезает. Берите MAD.
  4. Ожидание, что Хьюбер спасёт от выбросов в признаках. Он ограничивает влияние большого остатка $r$, но точка с экстремальным $x$ (высокий рычаг, leverage) всё равно может развернуть прямую. Для этого нужны другие методы (например, веса по $x$).
  5. Хьюбер в бустинге с методом Ньютона без проверки: нулевые вторые производные выбросов делают шаги листьев нестабильными. Используйте псевдо-Хьюбера или реализацию, которая это учитывает.
  6. Сравнение значений потерь при разных δ. Значение $L_\delta$ растёт с $\delta$ при прочих равных; сравнивайте модели по внешней метрике (MAE, RMSE на валидации), а не по самой потере.
  • MSE: при $\delta\ge\max|r_i|$ потеря Хьюбера равна половине квадрата ошибки; если все остатки МНК-решения не превышают $\delta$, оценка Хьюбера совпадает с МНК.
  • MAE: при $\delta\to0$ $L_\delta/\delta\to|r|$; оценка центра стремится к медиане.
  • RMSE: метрика, которую чаще всего портят выбросы; Хьюбер позволяет обучаться устойчиво, а отчитываться по RMSE на чистых данных.
  • ReLU и обрезание: $\psi_\delta(r)=\operatorname{clip}(r,-\delta,\delta)$ — та же идея «линейно до порога», что и в ReLU6 и gradient clipping.
  • Focal Loss — противоположная философия: Хьюбер ослабляет самые большие ошибки (считая их выбросами), а focal loss усиливает вес трудных примеров относительно лёгких.

Итоги

1) $L_\delta(r)$ — парабола $\tfrac12r^2$ при $|r|\le\delta$ и касательная к ней прямая $\delta(|r|-\tfrac12\delta)$ дальше; функция выпукла и принадлежит $C^1$, но не $C^2$. 2) Производная $\psi=\operatorname{clip}(r,-\delta,\delta)$ ограничена — выброс не тянет сильнее $\delta$; вес точки $\min(1,\delta/|r|)$. 3) $\delta\to\infty$ — MSE и среднее, $\delta\to0$ — MAE и медиана. 4) $\delta=1{,}345\sigma$ (σ по MAD) даёт 95% эффективности на нормальных данных. 5) Гладкие версии — псевдо-Хьюбер и log-cosh — нужны методам второго порядка; Smooth L1 — тот же Хьюбер, делённый на β.

Проверь себя

1. Чему равна $L_1(3)$ — потеря Хьюбера с $\delta=1$ при ошибке 3?
2. Какое наибольшее значение может принять $|\partial L_\delta/\partial\hat y|$?
3. Что происходит в точке $|r|=\delta$?
4. К чему стремится оценка центра Хьюбера при $\delta\to0$ и при очень большом $\delta$?
5. Почему порог часто берут равным $1{,}345\sigma$?