ML中所有算法都需要一个最大化或者最小化一个函数,这个函数被称为“目标函数”。

其中一般把最小化的一类函数称为“损失函数”,它能根据预测结果衡量出预测模型的好坏。

实际情况中选取损失函数会受到诸多因素的制约,比如时候有异常值、算法选择、梯度下降的时间复杂度、求导难易程度以及预测值置信度等等。

损失函数可以大致分为两类:分类问题的损失函数回归问题的损失函数

分类问题的损失函数种类有:

  • Log Loss
  • Focal Loss
  • KL Divergence / Relative Entropy
  • Exponential Loss
  • Hinge Loss
  • 待补充

回归问题的损失函数种类有:

  • Mean Square Error / Quadratic Loss
  • Mean Absolute Error
  • Huber Loss / Smooth Mean Absolute Error
  • Log Cosh Loss
  • Quantile Loss

回归问题损失函数

平均绝对误差(MAE / L1)

MAE=i=1nyiyip MAE = \sum_{i=1}^n |y_i - y_i^p|

MAE衡量了预测值误差的平均模长,不考虑方向,取值范围为[0, INF],真实值处最小。

一般设x=yiyipx = y_i - y_i^p,即
L1(x)=xL1(x)={1x>=01x<0 L1(x) = \sum|x| \\ L1^{'}(x) = \begin{cases} 1 & x >= 0 \\ -1 & x < 0 \end{cases}
可以看出,L1的导数非1即-1,在训练后期x较小的时候且lr(Learing rate)不变,损失函数会在稳定值附近波动,较难收敛到更高精度。

均方误差(MSE / L2)

MSE=i=1n(yiyip)2 MSE = \sum_{i=1}^n {(y_i - y_i^p)}^2

MSE是求预测值与真实值之间距离的平方和,取值为[0, INF],真实值处最小。这里设x=yiyipx = y_i - y_i^p,同样有
L2(x)=x2L2(x)=2x L2(x) = \sum x^2 \\ L2^{'}(x) = 2x
可以看出,当训练开始的时候,由于差异值很大,导数会很大,因此在训练初期不稳定。

由于L2是误差的平方,也就是说会赋予异常点更大的权重,对比L1更容易受到异常点的影响,但是可以得到更为准确的结果;

L1受异常点的影响没有L2那么大,但也还是会往异常点偏移;一般最后得到的则是样本点目标值的中位数

Smooth L1(Huber Loss的特殊形式)

SmoothL1(x)={0.5x2x<1x0.5SmoothL1(x)={xx<1±1other Smooth_{L1}(x) = \begin{cases} 0.5x^2 & |x|<1 \\ |x| - 0.5 \end{cases} \\ Smooth_{L1}^{'}(x) = \begin{cases} x & |x| < 1 \\ \pm1 & other \end{cases}

仔细观察对比公式可以看出,SmoothL1避开了L1训练后期不易收敛以及L2初期训练不稳定的问题,同时对异常值的敏感也如L1一样,是优于L1和L2的。

机器学习损失函数小结

图形如上图所示,红色为L1,蓝色为L2,绿色为SmoothL1。

这里再给出Huber Loss的一般形式
Lδ(y,f(x))={0.5(yf(x))2yf(x)δδyf(x)0.5δ2other L_{\delta}(y, f(x)) = \begin{cases} 0.5{(y-f(x))}^2 & |y-f(x)| \leq \delta \\ \delta|y-f(x)| - 0.5\delta^2 & other \end{cases}
是不是和Smooth L1很像,Smooth L1就是Huber Loss当超参数δ=1\delta=1时的形式。

Log-Cosh Loss

L(y,yp)=i=1nlogcosh(yipyi)cosh(x)=ex+ex2 L(y, y^p) = \sum_{i=1}^n log(cosh(y_i^p - y_i))\\ cosh(x) = \frac{e^x + e^{-x}}{2}

Log-Cosh损失是另一种应用于回归问题中比L2更为平滑的损失函数,计算方式是预测误差的双曲线余弦的对数

机器学习损失函数小结

对于较小误差其近似于MSE,但对于较大误差其近似于MAE - log(2),这意味着对异常值敏感度不高,类比Huber Loss其不需要设定超参数即可达到Huber Loss的所有点,且cosh其二阶可微,可以支持一些需要二阶导数信息的优化方法,缺点很明显,log-cosh求导复杂计算量大,远没有huber loss的简洁。

Quantile Loss

Lγ(y,yp)=i:yi<yip(1γ)yiyip+i:yiyipγyiyip L_{\gamma}(y, y^p) = \sum_{i:y_i < y_i^p} (1-\gamma)|y_i-y_i^p| + \sum_{i:y_i \geq y_i^p} \gamma |y_i - y_i^p|

γ[0,1]\gamma \in [0, 1],称为分位数

机器学习损失函数小结
许多商业问题的决策通常希望了解预测中的不确定性,更关注区间预测而不是点预测时,分位数损失函数就很有用。

使用最小二乘回归进行区间预测,基于的假设是残差yypy-y^p是独立变量,且方差保持不变,一旦违背此假设,则线性回归模型不成立。满足假设时,可以使用分位数损失和分位数回归,因为即便对于具有变化方差或非正态分布的残差,基于分位数损失的回归也能给出合理的预测区间。

机器学习损失函数小结

上图虚线表示分位数为0.05和0.95分位数损失函数的回归。

如何选取合适的分为数取决于对于正误差和反误差的重视程度。损失函数可以通过分位值对高估和低估给与不同的惩罚。例如γ=0.25\gamma=0.25时,高估权重为0.75而低估权重为0.25。

这个损失函数也可以在神经网络或基于树的模型中预测区间。比如使用梯度提升树回归模型时,使用分位数损失可以得到90%的预测区间,其中γ[0.05,0.95]\gamma \in [0.05, 0.95]

分类损失函数

分类问题一般真实值时离散分布的,分类损失函数主要是计算预测出的概率与对应的真实值的相符合程度。

Log Loss

Losslog=iNjMyijlog(pij) Loss_{log} = -\sum_i^N\sum_j^M y_{ij}log(p_{ij})

其中N是输入样本的数量或者实例的数量,M是某一个样本可能的分类数量。

yijy_{ij}代表某个样本i属于分类j的标签(离散分布一般是0或者1),类似pijp_{ij}代表样本i为分类j的概率。

Log Loss旨在惩罚错误分类,对于完全正确的分类(yij=1=pijy_{ij}=1=p_{ij})显然其对loss的贡献为0。

运用Log Loss的典型分类器是Logistic回归算法,其对于二分类问题:
Loss=iN(yilog(pi)+(1yi)log(1pi)) Loss = -\sum_i^N (y_ilog(p_i) + (1-y_i)log(1-p_i))
yi[0,1]y_i \in [0, 1]pip_i为1的概率为(正样本数/样本总数),为0的概率为(负样本/样本总数),此时M=2,一般整个公式还需要除以N取平均。

KL-divergence / Cross entropy / Logistic Loss

相对熵(KL-divergence / relative entropy)

相对熵是一种用来评价两种概率分布差异程度的方法。

给定字符集X={x}X = \{x\},通过某种方法预测其概率分布为q(x)q(x),但是其实际概率分布为p(x)p(x),如何评价二者差异呢?

设最优方案下字符编码长度为(香农信息论)
l(x)=log1p(x)  H(x)=xp(x)log1p(x) l(x) = log\frac{1}{p(x)} \\ 期望为 \ \ H(x) = \sum_x p(x)log\frac{1}{p(x)}
而在预测概率分布下字符编码为
l(x)=log1q(x)   H(x)=xp(x)log1q(x) l(x) = log \frac{1}{q(x)} \\ 期望为 \ \ \ H^{'}(x) = \sum_x p(x) log\frac{1}{q(x)}
很显然H(X)>H(X)H^{'}(X) > H(X),因为最优编码是编码长度最短的,即定义
DKL(pq)=H(x)H(x) D_{KL}(p|q) = H^{'}(x) - H(x)
可得
DKL(pq)=xp(x)logp(x)q(x)=x(p(x)logp(x)p(x)logq(x))=H(p)xp(x)logq(x)=H(p)+H(p,q) \begin{aligned} D_{KL}(p|q) &= \sum_x p(x) log \frac{p(x)}{q(x)} \\ &= \sum_x (p(x)logp(x) - p(x)logq(x)) \\ &= -H(p) - \sum_xp(x)logq(x) \\ &= -H(p) + H(p, q) \end{aligned}
可以发现,相对熵是不对称的。其实就是编码长度期望的差值。

交叉熵(Cross entropy)

交叉熵是从相对熵来的,将目标本来的类别作为p(x)p(x),预测层输出的概率分布q(x)q(x),就可以用相对熵来计算q(x)q(x)的好坏了。但是注意,H(p)=xp(x)logp(x)H(p) = \sum_x p(x)logp(x)是常数(因为p(x)已经知道),所以简化模型就得到了交叉熵了
H(p,q)=xp(x)logq(x) H(p, q) = -\sum_xp(x)logq(x)
对于二分类问题有
CE(p,y)={log(p)y=1log(1p)other   pt={py=11pother CE(p, y) = \begin{cases} -log(p) & y = 1\\ -log(1-p) & other \end{cases} \\ 令\ \ \ p_t = \begin{cases} p & y = 1\\ 1-p & other \end{cases}
最终有
C(p,y)=CE(pt)=log(pt) C(p, y) = CE(p_t) = -log(p_t)
这里提出一个问题,既然要让p(x)p(x)q(x)q(x)的差异很小,直接使用(p(x)q(x))2(p(x) - q(x))^2不行吗?

答案是不行,因为二次代价函数有一个缺点,而交叉熵代价函数没有。简单说就是二次代价在反向传播的时候,梯度的传递会受到**函数的影响,比如使用sigmoid函数会受到其梯度饱和的影响导致反向梯度无法传播更新,训练缓慢,而交叉熵正好可以抵消**函数的影响,直接由p(x)p(x)q(x)q(x)的差异作为梯度进行传播,具体例子可以看这里,这里不过多解释。

Focal Loss

FL(pt)=at(1pt)γlog(pt)CE(pt)=log(pt)   pt={py=11pother   at={ay=11aother FL(p_t) = -a_t(1 - p_t)^\gamma log(p_t) \\ CE(p_t) = -log(p_t) \\ \\ 令\ \ \ p_t = \begin{cases} p & y = 1\\ 1-p & other \end{cases} \\ 令\ \ \ a_t = \begin{cases} a & y = 1\\ 1-a & other \end{cases}

上图中,γ,a\gamma,a都是超参数。有
FL(pt)=at(1pt)γCE(pt) FL(p_t) = -a_t(1-p_t)^\gamma CE(p_t)
这样

  • 当一个样本被分错的时候即y=1pty=1,p_t很小的时候(1pt)γ(1-p_t)^\gamma会趋向于1,即相比原来loss变化不大
  • 当一个样本正确分类是y=1,pty=1,p_t也接近1时,(1pt)γ(1-p_t)^\gamma会几乎等于0,属于ease example,几乎不贡献损失
  • 当一个样本不管分类是什么,但是ptp_t的值难以预测处于[0.4, 0.6]的时候,(1pt)γ(1-p_t)^\gamma会趋于0,即权重降低,贡献的损失可能只有原来CE中的1/3甚至更低(取决于γ\gamma的设置)

机器学习损失函数小结

如上图,蓝色的是原本的CE,可以发现,随着γ\gamma的增大,0.3到0.8中的损失被降低了,这有什么好处呢?

在训练的样本集中,样本数量不平衡是比较常见的,大量的困难样本(预测值处于0.5左右)的loss会主导梯度下降的方向(即使此时对于正例的判别能力已经有了,但还是会变得往区分负样本的方向偏离),淹没了少年正样本的影响,反之依然。

所以首先通过ata_t来控制正负例之间的平衡,然后通过(1pt)γ(1-p_t)^\gamma来控制困难样本和简单样本之间的平衡,即
FL(pt)=at(1pt)γCE(pt) FL(p_t) = -a_t(1-p_t)^\gamma CE(p_t)
Focal Loss的提出是Object Detection One Stage Detector RetinaNet提出来的,其目的就是处理网络中大量负样本以及困难样本和正样本之间的平衡问题,通过了增加权重的方式减少了数量不平衡的影响,之后被广泛应用于处理样本不平衡的情况下。

Hinge Loss

l(y)=max(1,1yy^) l(y) = max(1, 1-y*\hat{y})

Hinge Loss通常被用于最大间隔算法(maximum-margin),而最大间隔算法又是SVM用的核心之一(PS:SVM两种解释:间隔最大化拉格朗日对偶、Hinge Loss)

Hinge Loss专用于二分类问题,y=±1,y^[0,1]y = \pm 1, \hat{y} \in [0, 1],此处仅简单介绍。

Exponential Loss

L(Yf(x))=exp[yf(x)] L(Y|f(x)) = exp[-yf(x)]

指数损失的典型应用是AdaBoost算法

// 待补充以及扩展

参考地址:

https://blog.csdn.net/clover_my/article/details/96482194 分类损失函数

https://blog.csdn.net/clover_my/article/details/90777964 回归损失函数

相关文章: