L1 loss, L2 loss以及Smooth L1 Loss的對比
總結對比下\(L_1\) 損失函式,\(L_2\) 損失函式以及\(\text{Smooth} L_1\) 損失函式的優缺點。
均方誤差MSE (\(L_2\) Loss)
均方誤差(Mean Square Error,MSE)是模型預測值\(f(x)\) 與真實樣本值\(y\) 之間差值平方的平均值,其公式如下
\[
MSE = \frac{\sum_{i=1}^n(f_{x_i} - y_i)^2}{n}
\]
其中,\(y_i\)和\(f(x_i)\)分別表示第\(i\)個樣本的真實值及其對應的預測值,\(n\)為樣本的個數。
忽略下標\(i\) ,設\(n=1\),以\(f(x) - y\)為橫軸,MSE的值為縱軸,得到函式的圖形如下:
MSE的函式曲線光滑、連續,處處可導,便於使用梯度下降演算法,是一種常用的損失函式。 而且,隨著誤差的減小,梯度也在減小,這有利於收斂,即使使用固定的學習速率,也能較快的收斂到最小值。
當\(y\)和\(f(x)\)也就是真實值和預測值的差值大於1時,會放大誤差;而當差值小於1時,則會縮小誤差,這是平方運算決定的。MSE對於較大的誤差(\(>1\))給予較大的懲罰,較小的誤差(\(<1\))給予較小的懲罰。也就是說,對離群點比較敏感,受其影響較大。
如果樣本中存在離群點,MSE會給離群點更高的權重,這就會犧牲其他正常點資料的預測效果,最終降低整體的模型效能。 如下圖:
可見,使用 MSE 損失函式,受離群點的影響較大,雖然樣本中只有 5 個離群點,但是擬合的直線還是比較偏向於離群點。
平均絕對誤差(\(L_1\) Loss)
平均絕對誤差(Mean Absolute Error,MAE) 是指模型預測值\(f(x)\)和真實值\(y\)之間距離的平均值,其公式如下:
\[
MAE = \frac{\sum_{n=1}^n\mid f(x_i) - y_i\mid}{n}
\]
忽略下標\(i\) ,設\(n=1\),以\(f(x) - y\)為橫軸,MAE的值為縱軸,得到函式的圖形如下:
MAE曲線連續,但是在\(y-f(x)=0\)處不可導。而且 MAE 大部分情況下梯度都是相等的,這意味著即使對於小的損失值,其梯度也是大的。這不利於函式的收斂和模型的學習。但是,無論對於什麼樣的輸入值,都有著穩定的梯度,不會導致梯度爆炸問題,具有較為穩健性的解。
相比於MSE,MAE有個優點就是,對於離群點不那麼敏感。因為MAE計算的是誤差\(y-f(x)\)的絕對值,對於任意大小的差值,其懲罰都是固定的。
針對上面帶有離群點的資料,MAE的效果要好於MSE。
顯然,使用 MAE 損失函式,受離群點的影響較小,擬合直線能夠較好地表徵正常資料的分佈情況。
MSE和MAE的選擇
從梯度的求解以及收斂上,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以及分位數損失等。
Smooth \(L_1\) Loss
在Faster R-CNN以及SSD中對邊框的迴歸使用的損失函式都是Smooth \(L_1\) 作為損失函式,
\[
\text{Smooth}{L_1}(x) =\left \{ \begin{array}{c} 0.5x^2 & if \mid x \mid <1 \\ \mid x \mid - 0.5 & otherwise \end{array} \right.
\]
其中,\(x = f(x_i) - y_i\) 為真實值和預測值的差值。
Smooth \(L_1\) 能從兩個方面限制梯度:
- 當預測框與 ground truth 差別過大時,梯度值不至於過大;
- 當預測框與 ground truth 差別很小時,梯度值足夠小。
對比\(L_1\) Loss 和 \(L_2\) Loss
其中\(x\)為預測框與groud truth之間的差異:
\[ \begin{align} L_2(x) &= x^2 \\ L_1(x) &= x \\ smooth_{L_1}(x) &=\left \{ \begin{array}{c} 0.5x^2 & if \mid x \mid <1 \\ \mid x \mid - 0.5 & otherwise \end{array} \right. \end{align} \]
上面損失函式對\(x\)的導數為:
\[
\begin{align}
\frac{\partial L_2(x)}{\partial x} &= 2x \\
\frac{\partial L_1(x)}{\partial x} &= \left \{ \begin{array}{c} 1 & \text{if } x \geq 0 \\ -1 & \text{otherwise} \end{array} \right. \\
\frac{\partial smooth_{L_1}(x)}{\partial x} &=\left \{ \begin{array}{c} x & if \mid x \mid <1 \\ \pm1 & otherwise \end{array} \right.
\end{align}
\]
上面導數可以看出:
根據公式-4,當\(x\)增大時,\(L_2\)的損失也增大。 這就導致在訓練初期,預測值與 groud truth 差異過於大時,損失函式對預測值的梯度十分大,訓練不穩定。
根據公式-5,\(L_1\)對\(x\)的導數為常數,在訓練的後期,預測值與ground truth差異很小時,\(L_1\)的導數的絕對值仍然為1,而 learning rate 如果不變,損失函式將在穩定值附近波動,難以繼續收斂以達到更高精度。
根據公式-6,\(\text{Smotth } L_1\)在\(x\)較小時,對\(x\)的梯度也會變小。 而當\(x\)較大時,對\(x\)的梯度的上限為1,也不會太大以至於破壞網路引數。\(Smooth L_1\)完美的避開了\(L_1\)和\(L_2\)作為損失函式的缺陷。
\(L_1\) Loss ,\(L_2\) Loss以及\(Smooth L_1\) 放在一起的函式曲線對比
從上面可以看出,該函式實際上就是一個分段函式,在[-1,1]之間實際上就是L2損失,這樣解決了L1的不光滑問題,在[-1,1]區間外,實際上就是L1損失,這樣就解決了離群點梯度爆炸的問題
實現 (PyTorch)
def _smooth_l1_loss(input, target, reduction='none'):
# type: (Tensor, Tensor) -> Tensor
t = torch.abs(input - target)
ret = torch.where(t < 1, 0.5 * t ** 2, t - 0.5)
if reduction != 'none':
ret = torch.mean(ret) if reduction == 'mean' else torch.sum(ret)
return ret
也可以添加個引數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損失函式,對離群點、異常值不敏感,梯度變化相對更小,訓練時不容易跑飛。