关于L1、L2的范数、损失函数和正则化,之前一直混淆这几个概念,故对这几天看过的资料进行了学习总结。
范数(norm)是数学中的一种基本概念。在泛函分析中,它定义在赋范线性空间中,并满足一定的条件,即①非负性;②齐次性;③三角不等式。它常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小。
首先以L2范数为例对范数做一个简单的说明:
L2范数:
假设 X X X是n维的特征 X = ( x 1 , x 2 , x 3 , … , x n ) X=(x_1,x_2,x_3,…,x_n) X=(x1,x2,x3,…,xn)
则L2范数: ∥ X ∥ 2 = ∑ i = 1 n x i 2 \left \|X\right \|_2=\sqrt{\sum_{i=1}^{n}x_i^2} ∥X∥2=∑i=1nxi2
本部分内容大多来源于回归损失函数1:L1 loss, L2 loss以及Smooth L1 Loss的对比。
L 1 L_1 L1
公式: L 1 = ∣ f ( x ) − Y ∣ L_1=\left|f(x)-Y\right| L1=∣f(x)−Y∣
求导: L 1 ′ = ± f ′ ( x ) L'_1=\pm{f'(x)} L1′=±f′(x)
L 2 L_2 L2
公式: L 2 = ∣ f ( x ) − Y ∣ 2 L_2=\left |f(x)-Y\right |^2 L2=∣f(x)−Y∣2
求导: L 2 ′ = 2 f ′ ( x ) ( f ( x ) − Y ) L'_2=2f'(x)(f(x)-Y) L2′=2f′(x)(f(x)−Y)
S m o o t h L 1 Smooth\;L_1 SmoothL1
公式:
S m o o t h L 1 = { 0.5 ( f ( x ) − Y ) 2 if ∣ f ( x ) − Y ∣ < 1 ∣ f ( x ) − Y ∣ − 0.5 if f ( x ) − Y < − 1 o r f ( x ) − Y > 1 Smooth\;L_1=\begin{cases} 0.5(f(x)-Y)^2 & \text{ if } \left|f(x)-Y\right|<1 \\ \left|f(x)-Y\right|-0.5 & \text{ if } f(x)-Y<-1\; or\;f(x)-Y>1 \end{cases} SmoothL1={0.5(f(x)−Y)2∣f(x)−Y∣−0.5 if ∣f(x)−Y∣<1 if f(x)−Y<−1orf(x)−Y>1
求导:
S m o o t h L 1 ′ = { f ′ ( x ) ( f ( x ) − Y ) if ∣ f ( x ) − Y ∣ < 1 ± 1 if f ( x ) − Y < − 1 o r f ( x ) − Y > 1 Smooth\;L'_1=\begin{cases} f'(x)(f(x)-Y) & \text{ if } \left|f(x)-Y\right|<1 \\ \pm 1 & \text{ if } f(x)-Y<-1\; or\;f(x)-Y>1 \end{cases} SmoothL1′={f′(x)(f(x)−Y)±1 if ∣f(x)−Y∣<1 if f(x)−Y<−1orf(x)−Y>1
上述三个函数的图像对比如下:
L1 Loss即平均绝对误差(Mean Absolute Error,MAE) ,是指模型预测值𝑓(𝑥)和真实值𝑦之间距离的平均值,其公式如下: M A E = ∑ i = 1 n ∣ f ( x i ) − y i ∣ n MAE=\frac{\sum_{i=1}^{n}\left|f(x_i)-y_i\right|}{n} MAE=n∑i=1n∣f(xi)−yi∣ 𝐿1对𝑥的导数为常数,在训练的后期,预测值与ground truth差异很小时,𝐿1的导数的绝对值仍然为1,而 learning rate 如果不变,损失函数将在稳定值附近波动,难以继续收敛以达到更高精度。
tips:
平均绝对误差MAE
在0处不可导
对离群点不敏感
梯度稳定,不会导致梯度爆炸(对很小的损失值,梯度也很大)
L2 Loss即为均方误差(Mean Square Error,MSE),是模型预测值𝑓(𝑥)与真实样本值𝑦之间差值平方的平均值,其公式如下 M S E = ∑ i = 1 n ( f ( x i ) − y i ) 2 n MSE=\frac{\sum_{i=1}^{n}(f(x_i)-y_i)^2}{n} MSE=n∑i=1n(f(xi)−yi)2 其中, y i y_i yi和 f ( x i ) f(x_i) f(xi)分别表示第𝑖个样本的真实值及其对应的预测值,𝑛为样本的个数。
MSE的函数曲线光滑、连续,处处可导,便于使用梯度下降算法,是一种常用的损失函数。 而且,随着误差的减小,梯度也在减小,这有利于收敛,即使使用固定的学习速率,也能较快的收敛到最小值。
当𝑦和𝑓(𝑥)也就是真实值和预测值的差值大于1时,会放大误差;而当差值小于1时,则会缩小误差,这是平方运算决定的。MSE对于较大的误差(>1)给予较大的惩罚,较小的误差(<1)给予较小的惩罚。也就是说,对离群点比较敏感,受其影响较大。
tips:
函数曲线连续,处处可导
随着误差减小,梯度也减小,有利于快速收敛
常用于解决回归问题
从梯度的求解以及收敛上,MSE是优于MAE的。MSE处处可导,而且梯度值也是动态变化的,能够快速的收敛;而MAE在0点处不可导,且其梯度保持不变。对于很小的损失值其梯度也很大,在深度学习中,就需要使用变化的学习率,在损失值很小时降低学习率。
对离群(异常)值得处理上,MAE要明显好于MSE。
如果离群点(异常值)需要被检测出来,则可以选择MSE作为损失函数;如果离群点只是当做受损的数据处理,则可以选择MAE作为损失函数。
总之,MAE作为损失函数更稳定,并且对离群值不敏感,但是其导数不连续,求解效率低。另外,在深度学习中,收敛较慢。MSE导数求解速度高,但是其对离群值敏感,不过可以将离群值的导数设为0(导数值大于某个阈值)来避免这种情况。
在某些情况下,上述两种损失函数都不能满足需求。例如,若数据中90%的样本对应的目标值为150,剩下10%在0到30之间。那么使用MAE作为损失函数的模型可能会忽视10%的异常点,而对所有样本的预测值都为150。这是因为模型会按中位数来预测。而使用MSE的模型则会给出很多介于0到30的预测值,因为模型会向异常点偏移。
这种情况下,MSE和MAE都是不可取的,简单的办法是对目标变量进行变换,或者使用别的损失函数,例如:Huber,Log-Cosh以及分位数损失等。
在Faster R-CNN以及SSD中对边框的回归使用的损失函数都是Smooth L1 作为损失函数, S m o o t h L 1 = { 0.5 ( f ( x ) − Y ) 2 if ∣ f ( x ) − Y ∣ < 1 ∣ f ( x ) − Y ∣ − 0.5 otherwise Smooth\;L_1=\begin{cases} 0.5(f(x)-Y)^2 & \text{ if } \left|f(x)-Y\right|<1 \\ \left|f(x)-Y\right|-0.5 & \text{ otherwise } \end{cases} SmoothL1={0.5(f(x)−Y)2∣f(x)−Y∣−0.5 if ∣f(x)−Y∣<1 otherwise Smooth L1 能从两个方面限制梯度:
当预测框与 ground truth 差别过大时,梯度值不至于过大;当预测框与 ground truth 差别很小时,梯度值足够小。Smooth L1 实际上就是一个分段函数,在[-1,1]之间实际上就是L2损失,这样解决了L1的不光滑问题,在[-1,1]区间外,实际上就是L1损失,这样就解决了离群点梯度爆炸的问题。
也可以添加个参数beta 这样就可以控制,什么范围的误差使用MSE,什么范围内的误差使用MAE了。
def smooth_l1_loss(input, target, beta=1. / 9, reduction = 'none'): """ very similar to the smooth_l1_loss from pytorch, but with the extra beta parameter """ n = torch.abs(input - target) cond = n < beta ret = torch.where(cond, 0.5 * n ** 2 / beta, n - 0.5 * beta) if reduction != 'none': ret = torch.mean(ret) if reduction == 'mean' else torch.sum(ret) return ret对于大多数CNN网络,我们一般是使用L2-loss而不是L1-loss,因为L2-loss的收敛速度要比L1-loss要快得多。
对于边框预测回归问题,通常也可以选择平方损失函数(L2损失),但L2范数的缺点是当存在离群点(outliers)的时候,这些点会占loss的主要组成部分。比如说真实值为1,预测10次,有一次预测值为1000,其余次的预测值为1左右,显然loss值主要由1000决定。所以FastRCNN采用稍微缓和一点绝对损失函数(smooth L1损失),它是随着误差线性增长,而不是平方增长。
Smooth L1 和 L1 Loss 函数的区别在于,L1 Loss 在0点处导数不唯一,可能影响收敛。Smooth L1的解决办法是在 0 点附近使用平方函数使得它更加平滑。
Smooth L1的优点
相比于L1损失函数,可以收敛得更快。相比于L2损失函数,对离群点、异常值不敏感,梯度变化相对更小,训练时不容易跑飞。正规化是防止过拟合的一种重要技巧。正则化通过降低模型的复杂性, 达到避免过拟合的问题。
过拟合的时候,拟合函数的系数往往非常大,为什么?过拟合,就是拟合函数需要顾忌每一个点,最终形成的拟合函数波动很大。在某些很小的区间里,函数值的变化很剧烈。这就意味着函数在某些小区间里的导数值(绝对值)非常大,由于自变量值可大可小,所以只有系数足够大,才能保证导数值很大。
L1正则常被用来进行特征选择,主要原因在于L1正则化会使得较多的参数为0,从而产生稀疏解,我们可以将0对应的特征遗弃,进而用来选择特征。一定程度上L1正则也可以防止模型过拟合。
假设L(W)是未加正则项的损失,λ是一个超参,控制正则化项的大小。
则最终的损失函数: L = L ( W ) + λ ∑ i = 1 n ∣ w i ∣ L=L(W)+\lambda \sum_{i=1}^{n}\left|w_i\right| L=L(W)+λ∑i=1n∣wi∣
梯度衰减(weights decay),主要用来防止模型过拟合,直观上理解就是L2正则化是对于大数值的权重向量进行严厉惩罚。
则最终的损失函数: L = L ( W ) + λ ∑ i = 1 n w i 2 L=L(W)+\lambda \sum_{i=1}^{n}w_i^2 L=L(W)+λ∑i=1nwi2
可以通过损失函数对w求导来证明,当 w i w_i wi小于1的时候,L2的惩罚项会越来越小,而L1还是会非常大,所以L1会使参数为0,而L2很难。
求导公式待补充
L1和L2 详解(范数、损失函数、正则化)
回归损失函数1:L1 loss, L2 loss以及Smooth L1 Loss的对比
损失函数:L1 loss, L2 loss, smooth L1 loss