一文读懂深度学习中的损失函数(Loss Function):回归损失、二分类损失和多分类损失
文章目錄
- 1 回歸損失(Regression Loss)
- 1.1 均方誤差(Mean Square Error,MSE)/ 二次損失(Quadratic loss) / L2損失(L2 Loss)
- 1.2 平均絕對誤差(Mean Absolute Error,MAE) / L1損失(L1 Loss)
- 1.3 MSE vs. MAE (L2 loss vs. L1 loss)
- 1.4 Huber Loss / Smooth Mean Absolute Error
- 1.5 Log-Cosh Loss
- 1.6 分位數(shù)損失(Quantile Loss)
- 1.7 對比研究
- 2 二分類損失(Binary Classification Loss)
- 2.1 二元交叉熵損失(Binary Cross Entropy Loss)
- 2.2 鉸鏈損失(Hinge Loss)
- 3 多分類損失(Multi-Class Classification Loss)
- 3.1 多分類交叉熵損失(Multi-Class Cross Entropy Loss)
- 3.2 KL散度(KL-Divergence)
- 參考
深度學(xué)習(xí)中的所有算法都依賴于最小化或最大化一個函數(shù),我們稱之為損失函數(shù)(loss function),或“目標函數(shù)”、“代價函數(shù)”。損失函數(shù)是衡量預(yù)測模型在預(yù)測預(yù)期結(jié)果方面做得有多好。求函數(shù)最小點最常用的方法是梯度下降法。損失函數(shù)就像起伏的山,梯度下降就像從山上滑下來到達最底部的點。
沒有一個單一的損失函數(shù)可以完美適用于所有類型的數(shù)據(jù)。它取決于許多因素,包括異常值的存在、深度學(xué)習(xí)算法的選擇、梯度下降的時間效率等等。本文的目的是了解不同的損失函數(shù),以及它們的原理。
損失函數(shù)大致可分為兩類:分類損失和回歸損失,其中分類損失根據(jù)類別數(shù)量又可分為二分類損失和多分類損失。需要注意的是:回歸函數(shù)預(yù)測數(shù)量,分類函數(shù)預(yù)測標簽。
1 回歸損失(Regression Loss)
1.1 均方誤差(Mean Square Error,MSE)/ 二次損失(Quadratic loss) / L2損失(L2 Loss)
均方誤差(MSE)是最常用的回歸損失函數(shù)。MSE是目標變值和預(yù)測值之間距離的平方之和。
下圖是MSE的函數(shù)圖,真實目標值為100,預(yù)測值在-10000到10000之間。MSE損失(y軸)在預(yù)測(x軸)為100時達到最小值。范圍是0到∞\infty∞。
1.2 平均絕對誤差(Mean Absolute Error,MAE) / L1損失(L1 Loss)
平均絕對誤差(MAE)是另一個用于回歸模型的損失函數(shù)。MAE是目標值和預(yù)測值之間的絕對差的總和。所以它測量的是一系列預(yù)測的平均誤差大小,而不考慮它們的方向,范圍也是0到∞\infty∞。如果考慮方向,那將被稱為平均偏差(Mean Bias Error,MBE),它是殘差/誤差的總和。
1.3 MSE vs. MAE (L2 loss vs. L1 loss)
簡言之:使用平方誤差MSE更容易收斂,但使用絕對誤差MAE對異常值更穩(wěn)健。接下來理解一下原因。
當(dāng)我們訓(xùn)練一個模型時,我們的目標是找到使損失函數(shù)取最小值的點。當(dāng)然,當(dāng)預(yù)測值與真實值完全相等時,兩個函數(shù)都達到最小值。下面是這兩種損失的python代碼,我們可以編寫自己的函數(shù),也可以使用sklearn的內(nèi)置函數(shù):
# true: Array of true target variable # pred: Array of predictions def mse(true, pred): return np.sum((true - pred)**2)def mae(true, pred):return np.sum(np.abs(true - pred))# also available in sklearnfrom sklearn.metrics import mean_squared_errorfrom sklearn.metrics import mean_absolute_error讓我們看看兩種情況下的MAE和均方根誤差(RMSE,它只是MSE的平方根,使MSE與MAE在相同的尺度上)的值。在第一種情況下,預(yù)測值接近真實值,且在所有樣本之間誤差的方差很小。在第二種情況下,觀察到有一個異常值,誤差很大。
由于MSE平方誤差(y-y_predicted = e),當(dāng)e>1時,誤差(e)的值大大增加;如果數(shù)據(jù)中有一個離群值,e的值就會很高,e^2就會>>|e|。這將使有MSE損失的模型比有MAE損失的模型給離群點更多的權(quán)值。在第2種情況下,以RMSE為損失函數(shù)的模型將以其他常見示例為代價進行調(diào)整,以最大程度減少單個異常的情況,這會降低模型的整體性能。
如果訓(xùn)練數(shù)據(jù)被異常值破壞(例如,我們在訓(xùn)練環(huán)境中錯誤地接收到巨大的負/正值,而不是在測試環(huán)境中),MAE損失是有用的。
直觀地說,我們可以這樣想:如果我們只需要對所有試圖使MSE最小化的觀察結(jié)果給出一個預(yù)測,那么這個預(yù)測應(yīng)該是所有目標值的平均值。但如果我們試圖最小化MAE,這個預(yù)測將是所有觀測值的中值。我們知道中值比均值對離群值更穩(wěn)健,這使得MAE比MSE對離群值更穩(wěn)健。
使用MAE損失的一個大問題是,它的梯度始終是相同的,這意味著即使損失很小,梯度也會很大,這對學(xué)習(xí)沒有好處。為了解決這個問題,我們可以使用動態(tài)學(xué)習(xí)率,它會隨著我們接近最小值而降低。在這種情況下,MSE表現(xiàn)得很好,即使在一個固定的學(xué)習(xí)速率下也會收斂。當(dāng)損失值越大,MSE損失的梯度越大,當(dāng)損失接近0時,MSE損失的梯度越小,使得訓(xùn)練結(jié)束時MSE損失的梯度更精確(見下圖)。
決定使用哪個損失函數(shù)
如果異常值代表的異常對業(yè)務(wù)是重要的,應(yīng)該被檢測到,那么我們應(yīng)該使用MSE。另一方面,如果我們認為離群值僅僅代表損壞的數(shù)據(jù),那么我們應(yīng)該選擇MAE作為損失。
L1損失對異常值具有更強的魯棒性,但其導(dǎo)數(shù)不連續(xù),使得求解效率低下。L2損失對異常值是敏感的,但給出了一個更穩(wěn)定和封閉形式的解決方案(通過設(shè)置其導(dǎo)數(shù)為0)。
兩者的問題:可能存在這兩種損失函數(shù)都不能給出理想預(yù)測的情況。例如,如果我們的數(shù)據(jù)中90%的觀察值的真實目標值為150,其余10%的目標值在0~30之間。然后,一個以MAE作為損失的模型可以為所有觀測值預(yù)測150,忽略10%的異常情況,因為它將嘗試向中值靠攏。在同樣的情況下,一個使用MSE的模型會在0到30的范圍內(nèi)給出許多預(yù)測,因為它會偏向于離群值。這兩種結(jié)果在許多商業(yè)案例中都是不可取的。
在這種情況下該怎么辦?一個簡單的解決方法是轉(zhuǎn)換目標變量。另一種方法是嘗試不同的損失函數(shù)。這就是我們的第三個損失函數(shù),Huber Loss背后的動機。
1.4 Huber Loss / Smooth Mean Absolute Error
與平方誤差損失相比,Huber Loss對數(shù)據(jù)中的異常值不那么敏感。它在0處也是可微的。它基本上是絕對誤差,當(dāng)誤差很小的時候就變成了二次值。誤差有多小才能變成二次值取決于一個超參數(shù)δ\deltaδ,這個超參數(shù)是可以調(diào)整的。Huber損失在δ\deltaδ~ 0時接近MSE,在δ\deltaδ~∞\infty∞(大數(shù)值)時接近MAE。
delta的選擇是至關(guān)重要的,因為它決定了你愿意將哪些內(nèi)容視為異常值。大于delta的殘差在L1中最小(L1對大的異常值不那么敏感),而小于delta的殘差在L2中適當(dāng)最小。
為什么使用Huber Loss?
使用MAE訓(xùn)練神經(jīng)網(wǎng)絡(luò)的一個大問題是它的持續(xù)大梯度,這可能會導(dǎo)致在使用梯度下降訓(xùn)練結(jié)束時丟失最小值。對于MSE,當(dāng)損失接近其最小值時,梯度減小,使其更加精確。
在這種情況下,Huber損失是非常有用的,因為它在減小梯度的最小值附近彎曲。它比MSE對離群值更穩(wěn)健。因此,它結(jié)合了MSE和MAE的優(yōu)良性能。然而,Huber損失的問題是我們可能需要訓(xùn)練超參數(shù)delta,這是一個迭代過程。
1.5 Log-Cosh Loss
Log-cosh是回歸任務(wù)中使用的另一個比L2更平滑的函數(shù)。Log-cosh是預(yù)測誤差的雙曲余弦的對數(shù)。
**優(yōu)點:**對于小的x, log(cosh(x))近似等于(x ** 2) / 2,對于大的x,近似等于abs(x) - log(2)。這意味著“l(fā)ogcosh”的工作方式與均方誤差類似,但不會受到偶爾出現(xiàn)的嚴重錯誤預(yù)測的強烈影響。它具有Huber損失的所有優(yōu)點,而且它在任何地方都是可微的,不像Huber損失。
為什么需要二階導(dǎo)數(shù)?許多ML模型實現(xiàn)如XGBoost使用牛頓法來尋找最優(yōu)值,這就是為什么需要二階導(dǎo)數(shù)(Hessian)。對于像XGBoost這樣的ML框架,兩次可微函數(shù)更合適。
但是Log-cosh損失并不是完美的。對于非常大的偏離目標的預(yù)測是恒定的,它仍然受到梯度和Hessian問題的困擾,因此導(dǎo)致XGBoost缺少分割。
1.6 分位數(shù)損失(Quantile Loss)
在大多數(shù)現(xiàn)實世界的預(yù)測問題中,我們經(jīng)常對我們預(yù)測中的不確定性感興趣。了解預(yù)測的范圍,而不是只了解點估計,可以顯著改善許多業(yè)務(wù)問題的決策制定過程。
分位數(shù)損失函數(shù)在預(yù)測區(qū)間而不僅僅是預(yù)測點時是有用的。最小二乘回歸的預(yù)測區(qū)間是基于殘差(y-y_hat)在自變量值之間具有恒定方差的假設(shè)。我們不能相信違背這一假設(shè)的線性回歸模型。我們也不能拋棄擬合線性回歸模型作為基線的想法,說這種情況總是可以用非線性函數(shù)或基于樹的模型更好地建模。這就是分位數(shù)損失和分位數(shù)回歸發(fā)揮作用的地方,因為基于分位數(shù)損失的回歸甚至為方差非常或非正態(tài)分布的殘差提供了合理的預(yù)測區(qū)間。
讓我們看一個工作示例,以更好地理解為什么基于分位數(shù)損失的回歸在異方差數(shù)據(jù)中表現(xiàn)良好。
理解分位數(shù)損失函數(shù)
基于分位數(shù)的回歸是在預(yù)測變量給定值的情況下估計響應(yīng)變量的條件分位數(shù)。分位數(shù)損失實際上只是MAE的一個擴展(當(dāng)分位數(shù)是50%時,它就是MAE)。
其思想是選擇分位數(shù)值是基于我們想給正誤差更多的值還是負誤差更多的值。損失函數(shù)試圖根據(jù)所選擇的分位數(shù)(γ\gammaγ)的值,對高估和低估給予不同的懲罰。例如,分位數(shù)損失函數(shù)(γ=0.25\gamma = 0.25γ=0.25)對過高估計給予更多懲罰,并試圖保持預(yù)測值略低于中值。
γ\gammaγ是必需的分位數(shù),其值在0和1之間。
我們也可以使用這個損失函數(shù)來計算神經(jīng)網(wǎng)絡(luò)或基于樹的模型的預(yù)測區(qū)間。下面是一個例子,Sklearn實現(xiàn)梯度增強樹回歸。
上圖顯示了sklearn庫的GradientBoostingRegression中可用的分位數(shù)損失函數(shù)計算出的90%的預(yù)測區(qū)間。上界構(gòu)造為γ=0.95\gamma= 0.95γ=0.95,下界構(gòu)造為γ=0.05\gamma = 0.05γ=0.05。
1.7 對比研究
將所有的損失繪制在一張圖上。
2 二分類損失(Binary Classification Loss)
這個名字很容易解釋。二分類是指將一個對象分配到兩個類中的一個。這種分類基于應(yīng)用于輸入特征向量的規(guī)則。例如,根據(jù)郵件的主題行將其分類為垃圾郵件或非垃圾郵件是二分類。
舉個例子:我們希望根據(jù)平均半徑、面積、周長等特征將腫瘤分類為惡性或良性。為了簡化,我們只使用兩個輸入特征(X1X_1X1?和X2X_2X2?)進行分類,即最差區(qū)域和平均對稱。目標值Y可以是0(惡性)或1(良性)。下面是數(shù)據(jù)的散點圖:
2.1 二元交叉熵損失(Binary Cross Entropy Loss)
讓我們從理解熵這個術(shù)語開始。通常,我們用熵來表示無序或不確定性,它是對概率分布為p(X)的隨機變量X進行測量的:
負號是用來使總數(shù)量為正的。
一個概率分布的熵值越大,表明該分布的不確定性越大。同樣,值越小,分布越確定。
這使得二元交叉熵適合作為損失函數(shù)來最小化它的值。對于輸出概率p的分類模型,我們使用二元交叉熵損失。
元素屬于1類(或正類)的概率= p那么,元素屬于0類(或負類)的概率= 1 - p
那么,定義輸出標簽y(可以取0和1)和預(yù)測概率p的交叉熵損失為:
這也叫做對數(shù)損失。為了計算概率p,我們可以使用Sigmoid函數(shù)。這里,z是輸入特征的函數(shù):
Sigmoid函數(shù)的取值范圍為[0,1],適合計算概率。
下面為權(quán)重更新函數(shù)update_weight的代碼。
使用不同的alpha值1000次迭代的權(quán)重更新規(guī)則,得到下圖:
2.2 鉸鏈損失(Hinge Loss)
鉸鏈損耗主要與分類標簽為-1和1的支持向量機(SVM)分類器一起使用。因此,請確保將數(shù)據(jù)集中的負類的標簽從0更改為-1。
Hinge損失不僅會懲罰錯誤的預(yù)測,也會懲罰不確定的正確預(yù)測。
輸入輸出對(x, y)的Hinge損失為:
def update_weights_Hinge(m1, m2, b, X1, X2, Y, learning_rate):m1_deriv = 0m2_deriv = 0b_deriv = 0N = len(X1)for i in range(N):# Calculate partial derivativesif Y[i]*(m1*X1[i] + m2*X2[i] + b) <= 1:m1_deriv += -X1[i] * Y[i]m2_deriv += -X2[i] * Y[i]b_deriv += -Y[i]# else derivatives are zero# We subtract because the derivatives point in direction of steepest ascentm1 -= (m1_deriv / float(N)) * learning_ratem2 -= (m2_deriv / float(N)) * learning_rateb -= (b_deriv / float(N)) * learning_ratereturn m1, m2, b在使用三個不同的alpha值運行更新函數(shù)2000次迭代后,得到了這張圖:
Hinge損失簡化了支持向量機的數(shù)學(xué)運算,同時使損失最大化(與對數(shù)損失相比)。當(dāng)我們要做出實時決策而又不急于提高準確性時,可以使用它。
3 多分類損失(Multi-Class Classification Loss)
一個例子:電子郵件不僅僅被劃分為垃圾郵件或非垃圾郵件(這已經(jīng)不是90年代了!)他們被分為工作、家庭、社交、晉升等不同的類別。這是一個多分類問題。
我們將使用Iris數(shù)據(jù)集來理解剩下的兩個損失函數(shù)。我們將使用2個特征X1X_1X1?即萼片長度和X2X_2X2?花瓣寬度來預(yù)測鳶尾花Setosa, Versicolor或Virginica的級別。
我們的任務(wù)是使用神經(jīng)網(wǎng)絡(luò)模型和Keras中的內(nèi)置Adam優(yōu)化器來實現(xiàn)分類器。這是因為隨著參數(shù)數(shù)量的增加,數(shù)學(xué)和代碼將變得難以理解。
下面是這些數(shù)據(jù)的散點圖:
3.1 多分類交叉熵損失(Multi-Class Cross Entropy Loss)
多類交叉熵損失是二元交叉熵損失的推廣。輸入向量XiX_iXi?和對應(yīng)的單編碼目標向量YiY_iYi?的損失為:
我們使用softmax函數(shù)來求概率pijp_{ij}pij?:
“Softmax是通過輸出層之前的神經(jīng)網(wǎng)絡(luò)層實現(xiàn)的。Softmax層必須有與輸出層相同數(shù)量的節(jié)點。”
“Softmax is implemented through a neural network layer just before the output layer. The Softmax layer must have the same number of nodes as the output layer.”
Google Developer’s Blog
最終,我們的輸出是對給定輸入具有最大概率的類。
我們使用輸入層和輸出層建立一個模型,并以不同的學(xué)習(xí)率訓(xùn)練它。在model.compile()語句中將損失參數(shù)指定為categorical_crossentropy。
# importing requirements from keras.layers import Dense from keras.models import Sequential from keras.optimizers import adam# alpha = 0.001 as given in the lr parameter in adam() optimizer# build the model model_alpha1 = Sequential() model_alpha1.add(Dense(50, input_dim=2, activation='relu')) model_alpha1.add(Dense(3, activation='softmax'))# compile the model opt_alpha1 = adam(lr=0.001) model_alpha1.compile(loss='categorical_crossentropy', optimizer=opt_alpha1, metrics=['accuracy'])# fit the model # dummy_Y is the one-hot encoded # history_alpha1 is used to score the validation and accuracy scores for plotting history_alpha1 = model_alpha1.fit(dataX, dummy_Y, validation_data=(dataX, dummy_Y), epochs=200, verbose=0)下面是經(jīng)過200個epoch訓(xùn)練后的成本和準確度的分別圖:
3.2 KL散度(KL-Divergence)
Kullback-Liebler散度是一個概率分布與另一個分布差異的度量,KL散度為零表示分布是相同的。
注意散度函數(shù)是不對稱的。這就是為什么KL散度不能用作距離度量的原因。
本文將描述使用KL散度作為損失函數(shù)的基本方法,而不涉及它的數(shù)學(xué)原理。由于KL散度是不對稱的,我們可以用兩種方法來做這件事:
第一種方法用于監(jiān)督學(xué)習(xí),第二種方法用于強化學(xué)習(xí)。KL散度在函數(shù)上類似于多類交叉熵,也稱為P相對于Q的相對熵:
我們在compile()函數(shù)中指定kullback_leibler_divergence作為損失參數(shù)的值,就像前面處理多類交叉熵損失時所做的那樣。
# importing requirements from keras.layers import Dense from keras.models import Sequential from keras.optimizers import adam# alpha = 0.001 as given in the lr parameter in adam() optimizer# build the model model_alpha1 = Sequential() model_alpha1.add(Dense(50, input_dim=2, activation='relu')) model_alpha1.add(Dense(3, activation='softmax'))# compile the model opt_alpha1 = adam(lr=0.001) model_alpha1.compile(loss='kullback_leibler_divergence', optimizer=opt_alpha1, metrics=['accuracy'])# fit the model # dummy_Y is the one-hot encoded # history_alpha1 is used to score the validation and accuracy scores for plotting history_alpha1 = model_alpha1.fit(dataX, dummy_Y, validation_data=(dataX, dummy_Y), epochs=200, verbose=0)
與多類分類相比,KL-散度更常用于近似復(fù)雜函數(shù)。 我們在使用深度自動生成模型(如變分自動編碼器(VAE))時經(jīng)常遇到KL-散度。
參考
[1] https://heartbeat.fritz.ai/5-regression-loss-functions-all-machine-learners-should-know-4fb140e9d4b0
[2] https://medium.com/analytics-vidhya/a-detailed-guide-to-7-loss-functions-for-machine-learning-algorithms-26e11b6e700b
總結(jié)
以上是生活随笔為你收集整理的一文读懂深度学习中的损失函数(Loss Function):回归损失、二分类损失和多分类损失的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 神经网络损失函数汇总
- 下一篇: 深度学习入门与快速实践