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()
Наконец, проиллюстрируем разницу между
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()