scipy.special.pseudo_huber#

scipy.special.pseudo_huber(delta, r, выход=None) = 'pseudo_huber'>#

Функция потерь Псевдо-Хубера.

\[\mathrm{pseudo\_huber}(\delta, r) = \delta^2 \left( \sqrt{ 1 + \left( \frac{r}{\delta} \right)^2 } - 1 \right)\]
Параметры:
deltaarray_like

Входной массив, указывающий точку перехода мягкой квадратичной и линейной потерь.

rarray_like

Входной массив, возможно, представляющий остатки.

выходndarray, необязательно

Необязательный выходной массив для результатов функции

Возвращает:
resскаляр или ndarray

Вычисленные значения функции потерь Псевдо-Хубера.

Смотрите также

huber

Похожая функция, которую эта функция аппроксимирует

Примечания

Как huber, pseudo_huber часто служит робастной функцией потерь в статистике или машинном обучении для уменьшения влияния выбросов. В отличие от huber, pseudo_huber является гладкой.

Обычно, r представляет остатки, разницу между предсказанием модели и данными. Тогда для \(|r|\leq\delta\), pseudo_huber напоминает квадрат ошибки и для \(|r|>\delta\) абсолютная ошибка. Таким образом, псевдо-функция потерь Хьюбера часто достигает быстрой сходимости при подгонке модели для малых остатков, как и квадратичная функция потерь, и всё ещё уменьшает влияние выбросов (\(|r|>\delta\)) как абсолютная ошибка потерь. Как \(\delta\) является границей между режимами квадратичной и абсолютной ошибки, его необходимо тщательно настраивать для каждой задачи. pseudo_huber также является выпуклой, что делает её подходящей для градиентной оптимизации. [1] [2]

Добавлено в версии 0.15.0.

Ссылки

[1]

Hartley, Zisserman, “Multiple View Geometry in Computer Vision”. 2003. Cambridge University Press. p. 619

[2]

Charbonnier et al. “Deterministic edge-preserving regularization in computed imaging”. 1997. IEEE Trans. Image Processing. 6 (2): 298 - 311.

Примеры

Импортируйте все необходимые модули.

>>> import numpy as np
>>> from scipy.special import pseudo_huber, huber
>>> import matplotlib.pyplot as plt

Вычислить функцию для delta=1 в r=2.

>>> pseudo_huber(1., 2.)
1.2360679774997898

Вычислить функцию в r=2 для разных delta предоставив список или массив NumPy для delta.

>>> pseudo_huber([1., 2., 4.], 3.)
array([2.16227766, 3.21110255, 4.        ])

Вычислить функцию для delta=1 в нескольких точках путем предоставления списка или массива NumPy для r.

>>> pseudo_huber(2., np.array([1., 1.5, 3., 4.]))
array([0.47213595, 1.        , 3.21110255, 4.94427191])

Функция может быть вычислена для различных delta и r путем предоставления массивов для обоих с совместимыми формами для вещания.

>>> r = np.array([1., 2.5, 8., 10.])
>>> deltas = np.array([[1.], [5.], [9.]])
>>> print(r.shape, deltas.shape)
(4,) (3, 1)
>>> pseudo_huber(deltas, r)
array([[ 0.41421356,  1.6925824 ,  7.06225775,  9.04987562],
       [ 0.49509757,  2.95084972, 22.16990566, 30.90169944],
       [ 0.49846624,  3.06693762, 27.37435121, 40.08261642]])

Построить график функции для различных delta.

>>> x = np.linspace(-4, 4, 500)
>>> deltas = [1, 2, 3]
>>> linestyles = ["dashed", "dotted", "dashdot"]
>>> fig, ax = plt.subplots()
>>> combined_plot_parameters = list(zip(deltas, linestyles))
>>> for delta, style in combined_plot_parameters:
...     ax.plot(x, pseudo_huber(delta, x), label=rf"$\delta={delta}$",
...             ls=style)
>>> ax.legend(loc="upper center")
>>> ax.set_xlabel("$x$")
>>> ax.set_title(r"Pseudo-Huber loss function $h_{\delta}(x)$")
>>> ax.set_xlim(-4, 4)
>>> ax.set_ylim(0, 8)
>>> plt.show()
../../_images/scipy-special-pseudo_huber-1_00_00.png

Наконец, проиллюстрируем разницу между huber и pseudo_huber путём построения их и их градиентов по r. График показывает что pseudo_huber непрерывно дифференцируема, в то время как huber не находится в точках \(\pm\delta\).

>>> def huber_grad(delta, x):
...     grad = np.copy(x)
...     linear_area = np.argwhere(np.abs(x) > delta)
...     grad[linear_area]=delta*np.sign(x[linear_area])
...     return grad
>>> def pseudo_huber_grad(delta, x):
...     return x* (1+(x/delta)**2)**(-0.5)
>>> x=np.linspace(-3, 3, 500)
>>> delta = 1.
>>> fig, ax = plt.subplots(figsize=(7, 7))
>>> ax.plot(x, huber(delta, x), label="Huber", ls="dashed")
>>> ax.plot(x, huber_grad(delta, x), label="Huber Gradient", ls="dashdot")
>>> ax.plot(x, pseudo_huber(delta, x), label="Pseudo-Huber", ls="dotted")
>>> ax.plot(x, pseudo_huber_grad(delta, x), label="Pseudo-Huber Gradient",
...         ls="solid")
>>> ax.legend(loc="upper center")
>>> plt.show()
../../_images/scipy-special-pseudo_huber-1_01_00.png