机器学习大牛是如何选择回归损失函数的?
無論在機(jī)器學(xué)習(xí)還是深度領(lǐng)域中,損失函數(shù)都是一個(gè)非常重要的知識點(diǎn)。損失函數(shù)(Loss Function)是用來估量模型的預(yù)測值 f(x) 與真實(shí)值 y 的不一致程度。我們的目標(biāo)就是最小化損失函數(shù),讓 f(x) 與 y 盡量接近。通常可以使用梯度下降算法尋找函數(shù)最小值。
關(guān)于梯度下降最直白的解釋可以看我的這篇文章:
簡單的梯度下降算法,你真的懂了嗎?
損失函數(shù)有許多不同的類型,沒有哪種損失函數(shù)適合所有的問題,需根據(jù)具體模型和問題進(jìn)行選擇。一般來說,損失函數(shù)大致可以分成兩類:回歸(Regression)和分類(Classification)。今天,紅色石頭將要總結(jié)回歸問題中常用的 3 種損失函數(shù),希望對你有所幫助。
回歸模型中的三種損失函數(shù)包括:均方誤差(Mean Square Error)、平均絕對誤差(Mean Absolute Error,MAE)、Huber Loss。
1. 均方誤差(Mean Square Error,MSE)
均方誤差指的就是模型預(yù)測值 f(x) 與樣本真實(shí)值 y 之間距離平方的平均值。其公式如下所示:
其中,yi 和 f(xi) 分別表示第 i 個(gè)樣本的真實(shí)值和預(yù)測值,m 為樣本個(gè)數(shù)。
為了簡化討論,忽略下標(biāo) i,m = 1,以 y-f(x) 為橫坐標(biāo),MSE 為縱坐標(biāo),繪制其損失函數(shù)的圖形:
MSE 曲線的特點(diǎn)是光滑連續(xù)、可導(dǎo),便于使用梯度下降算法,是比較常用的一種損失函數(shù)。而且,MSE 隨著誤差的減小,梯度也在減小,這有利于函數(shù)的收斂,即使固定學(xué)習(xí)因子,函數(shù)也能較快取得最小值。
平方誤差有個(gè)特性,就是當(dāng)?yi 與 f(xi) 的差值大于 1 時(shí),會(huì)增大其誤差;當(dāng)?yi 與 f(xi) 的差值小于 1 時(shí),會(huì)減小其誤差。這是由平方的特性決定的。也就是說, MSE 會(huì)對誤差較大(>1)的情況給予更大的懲罰,對誤差較小(<1)的情況給予更小的懲罰。從訓(xùn)練的角度來看,模型會(huì)更加偏向于懲罰較大的點(diǎn),賦予其更大的權(quán)重。
如果樣本中存在離群點(diǎn),MSE 會(huì)給離群點(diǎn)賦予更高的權(quán)重,但是卻是以犧牲其他正常數(shù)據(jù)點(diǎn)的預(yù)測效果為代價(jià),這最終會(huì)降低模型的整體性能。我們來看一下使用 MSE?解決含有離群點(diǎn)的回歸模型。
import numpy as np import matplotlib.pyplot as plt x = np.linspace(1, 20, 40) y = x + [np.random.choice(4) for _ in range(40)] y[-5:] -= 8 X = np.vstack((np.ones_like(x),x)) ? ?# 引入常數(shù)項(xiàng) 1 m = X.shape[1] # 參數(shù)初始化 W = np.zeros((1,2))# 迭代訓(xùn)練 num_iter = 20 lr = 0.01 J = [] for i in range(num_iter):y_pred = W.dot(X)loss = 1/(2*m) * np.sum((y-y_pred)**2)J.append(loss)W = W + lr * 1/m * (y-y_pred).dot(X.T)# 作圖 y1 = W[0,0] + W[0,1]*1 y2 = W[0,0] + W[0,1]*20 plt.scatter(x, y) plt.plot([1,20],[y1,y2]) plt.show()擬合結(jié)果如下圖所示:
可見,使用 MSE 損失函數(shù),受離群點(diǎn)的影響較大,雖然樣本中只有 5 個(gè)離群點(diǎn),但是擬合的直線還是比較偏向于離群點(diǎn)。這往往是我們不希望看到的。
2.?平均絕對誤差(Mean Absolute Error,MAE)
平均絕對誤差指的就是模型預(yù)測值 f(x) 與樣本真實(shí)值 y 之間距離的平均值。其公式如下所示:
為了簡化討論,忽略下標(biāo) i,m = 1,以 y-f(x) 為橫坐標(biāo),MAE 為縱坐標(biāo),繪制其損失函數(shù)的圖形:
直觀上來看,MAE 的曲線呈 V 字型,連續(xù)但在 y-f(x)=0 處不可導(dǎo),計(jì)算機(jī)求解導(dǎo)數(shù)比較困難。而且 MAE 大部分情況下梯度都是相等的,這意味著即使對于小的損失值,其梯度也是大的。這不利于函數(shù)的收斂和模型的學(xué)習(xí)。
值得一提的是,MAE 相比 MSE 有個(gè)優(yōu)點(diǎn)就是 MAE 對離群點(diǎn)不那么敏感,更有包容性。因?yàn)?MAE 計(jì)算的是誤差?y-f(x) 的絕對值,無論是?y-f(x)>1 還是?y-f(x)<1,沒有平方項(xiàng)的作用,懲罰力度都是一樣的,所占權(quán)重一樣。針對 MSE 中的例子,我們來使用 MAE 進(jìn)行求解,看下擬合直線有什么不同。
X = np.vstack((np.ones_like(x),x)) ? ?# 引入常數(shù)項(xiàng) 1 m = X.shape[1] # 參數(shù)初始化 W = np.zeros((1,2))# 迭代訓(xùn)練 num_iter = 20 lr = 0.01 J = [] for i in range(num_iter):y_pred = W.dot(X)loss = 1/m * np.sum(np.abs(y-y_pred))J.append(loss)mask = (y-y_pred).copy()mask[y-y_pred > 0] = 1mask[mask <= 0] = -1W = W + lr * 1/m * mask.dot(X.T)# 作圖 y1 = W[0,0] + W[0,1]*1 y2 = W[0,0] + W[0,1]*20 plt.scatter(x, y) plt.plot([1,20],[y1,y2],'r--') plt.xlabel('x') plt.ylabel('y') plt.title('MAE') plt.show()注意上述代碼中對 MAE 計(jì)算梯度的部分。
擬合結(jié)果如下圖所示:
顯然,使用 MAE 損失函數(shù),受離群點(diǎn)的影響較小,擬合直線能夠較好地表征正常數(shù)據(jù)的分布情況。這一點(diǎn),MAE 要優(yōu)于 MSE。二者的對比圖如下:
選擇 MSE 還是 MAE 呢?
實(shí)際應(yīng)用中,我們應(yīng)該選擇 MSE 還是 MAE 呢?從計(jì)算機(jī)求解梯度的復(fù)雜度來說,MSE 要優(yōu)于 MAE,而且梯度也是動(dòng)態(tài)變化的,能較快準(zhǔn)確達(dá)到收斂。但是從離群點(diǎn)角度來看,如果離群點(diǎn)是實(shí)際數(shù)據(jù)或重要數(shù)據(jù),而且是應(yīng)該被檢測到的異常值,那么我們應(yīng)該使用MSE。另一方面,離群點(diǎn)僅僅代表數(shù)據(jù)損壞或者錯(cuò)誤采樣,無須給予過多關(guān)注,那么我們應(yīng)該選擇MAE作為損失。
3.?Huber Loss
既然 MSE 和 MAE 各有優(yōu)點(diǎn)和缺點(diǎn),那么有沒有一種激活函數(shù)能同時(shí)消除二者的缺點(diǎn),集合二者的優(yōu)點(diǎn)呢?答案是有的。Huber Loss 就具備這樣的優(yōu)點(diǎn),其公式如下:
Huber Loss 是對二者的綜合,包含了一個(gè)超參數(shù) δ。δ 值的大小決定了 Huber Loss 對 MSE 和 MAE 的側(cè)重性,當(dāng) |y?f(x)| ≤?δ?時(shí),變?yōu)?MSE;當(dāng) |y?f(x)| >?δ?時(shí),則變成類似于 MAE,因此 Huber Loss 同時(shí)具備了 MSE 和 MAE 的優(yōu)點(diǎn),減小了對離群點(diǎn)的敏感度問題,實(shí)現(xiàn)了處處可導(dǎo)的功能。
通常來說,超參數(shù)?δ 可以通過交叉驗(yàn)證選取最佳值。下面,分別取?δ = 0.1、δ = 10,繪制相應(yīng)的 Huber Loss,如下圖所示:
Huber Loss 在?|y?f(x)| >?δ?時(shí),梯度一直近似為 δ,能夠保證模型以一個(gè)較快的速度更新參數(shù)。當(dāng)?|y?f(x)| ≤?δ?時(shí),梯度逐漸減小,能夠保證模型更精確地得到全局最優(yōu)值。因此,Huber Loss 同時(shí)具備了前兩種損失函數(shù)的優(yōu)點(diǎn)。
下面,我們用 Huber Loss 來解決同樣的例子。
X = np.vstack((np.ones_like(x),x)) ? ?# 引入常數(shù)項(xiàng) 1 m = X.shape[1] # 參數(shù)初始化 W = np.zeros((1,2))# 迭代訓(xùn)練 num_iter = 20 lr = 0.01 delta = 2 J = [] for i in range(num_iter):y_pred = W.dot(X)loss = 1/m * np.sum(np.abs(y-y_pred))J.append(loss)mask = (y-y_pred).copy()mask[y-y_pred > delta] = deltamask[mask < -delta] = -deltaW = W + lr * 1/m * mask.dot(X.T)# 作圖 y1 = W[0,0] + W[0,1]*1 y2 = W[0,0] + W[0,1]*20 plt.scatter(x, y) plt.plot([1,20],[y1,y2],'r--') plt.xlabel('x') plt.ylabel('y') plt.title('MAE') plt.show()注意上述代碼中對 Huber Loss 計(jì)算梯度的部分。
擬合結(jié)果如下圖所示:
可見,使用 Huber Loss 作為激活函數(shù),對離群點(diǎn)仍然有很好的抗干擾性,這一點(diǎn)比 MSE 強(qiáng)。另外,我們把這三種損失函數(shù)對應(yīng)的 Loss 隨著迭代次數(shù)變化的趨勢繪制出來:
MSE:
MAE:
Huber Loss:
對比發(fā)現(xiàn),MSE 的 Loss 下降得最快,MAE 的 Loss 下降得最慢,Huber Loss 下降速度介于 MSE 和 MAE 之間。也就是說,Huber Loss 彌補(bǔ)了此例中 MAE 的 Loss 下降速度慢的問題,使得優(yōu)化速度接近 MSE。
最后,我們把以上介紹的回歸問題中的三種損失函數(shù)全部繪制在一張圖上。
好了,以上就是紅色石頭對回歸問題 3 種常用的損失函數(shù)包括:MSE、MAE、Huber Loss 的簡單介紹和詳細(xì)對比。這些簡單的知識點(diǎn)你是否已經(jīng)完全掌握了呢?
參考文獻(xiàn):
http://www.10tiao.com/html/782/201806/2247495489/1.html
https://www.cnblogs.com/massquantity/p/8964029.html
推薦閱讀
我的深度學(xué)習(xí)入門路線
【干貨】我的機(jī)器學(xué)習(xí)入門路線圖
長文!機(jī)器學(xué)習(xí)筆試精選 100 題【附詳細(xì)解析】
總結(jié)
以上是生活随笔為你收集整理的机器学习大牛是如何选择回归损失函数的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何能能够学好软件编程技术
- 下一篇: 确定不收藏?机器学习必备的分类损失函数速