介紹
想象一下-你已經(jīng)在給定的數(shù)據(jù)集上訓(xùn)練了機(jī)器學(xué)習(xí)模型,并準(zhǔn)備好將它交付給客戶。但是,你如何確定該模型能夠提供最佳結(jié)果?是否有指標(biāo)或技術(shù)可以幫助你快速評(píng)估數(shù)據(jù)集上的模型?
當(dāng)然是有的,簡(jiǎn)而言之,機(jī)器學(xué)習(xí)中損失函數(shù)可以解決以上問(wèn)題。
損失函數(shù)是我們喜歡使用的機(jī)器學(xué)習(xí)算法的核心。但大多數(shù)初學(xué)者和愛(ài)好者不清楚如何以及在何處使用它們。
它們并不難理解,反而可以增強(qiáng)你對(duì)機(jī)器學(xué)習(xí)算法的理解。那么,什么是損失函數(shù),你如何理解它們的意義?
在本文中,我將討論機(jī)器學(xué)習(xí)中使用的7種常見(jiàn)損失函數(shù),并解釋每種函數(shù)的使用方法。
目錄
- 什么是損失函數(shù)?
- 回歸損失函數(shù)
- 平方誤差損失
- 絕對(duì)誤差損失
- Huber損失
- 二分類損失函數(shù)
- 二分類交叉熵
- Hinge損失
- 多分類損失函數(shù)
- 多分類交叉熵?fù)p失
- KL散度(Kullback Leibler Divergence Loss)
1. 什么是損失函數(shù)?
假設(shè)你在山頂,需要下山。你如何決定走哪個(gè)方向?
我要做的事情如下:
- 環(huán)顧四周,看看所有可能的路徑
- 拒絕那些上升的路徑。這是因?yàn)檫@些路徑實(shí)際上會(huì)消耗更多的體力并使下山任務(wù)變得更加艱難
- 最后,走我認(rèn)為的坡度最大的路徑
關(guān)于我判斷我的決策是否好壞的直覺(jué),這正是損失函數(shù)能夠提供的功能。
損失函數(shù)將決策映射到其相關(guān)成本
決定走上坡的路徑將耗費(fèi)我們的體力和時(shí)間。決定走下坡的路徑將使我們受益。因此,下坡的成本是更小的。
在有監(jiān)督的機(jī)器學(xué)習(xí)算法中,我們希望在學(xué)習(xí)過(guò)程中最小化每個(gè)訓(xùn)練樣例的誤差。這是使用梯度下降等一些優(yōu)化策略完成的。而這個(gè)誤差來(lái)自損失函數(shù)。
損失函數(shù)(Loss Function)和成本函數(shù)(Cost Function)之間有什么區(qū)別?
在此強(qiáng)調(diào)這一點(diǎn),盡管成本函數(shù)和損失函數(shù)是同義詞并且可以互換使用,但它們是不同的。
損失函數(shù)用于單個(gè)訓(xùn)練樣本。它有時(shí)也稱為誤差函數(shù)(error function)。另一方面,成本函數(shù)是整個(gè)訓(xùn)練數(shù)據(jù)集的平均損失(average function)。優(yōu)化策略旨在最小化成本函數(shù)。
2. 回歸損失函數(shù)
此時(shí)你必須非常熟悉線性回歸。它涉及對(duì)因變量Y和幾個(gè)獨(dú)立變量 X_i 之間的線性關(guān)系進(jìn)行建模。因此,我們?cè)诳臻g中對(duì)這些數(shù)據(jù)擬合出一條直線或者超平面。
Y = a0 + a1 * X1 + a2 * X2 + ....+ an * Xn
我們將使用給定的數(shù)據(jù)點(diǎn)來(lái)找到系數(shù)a0,a1,…,an。
我們將使用著名的波士頓住房數(shù)據(jù)集來(lái)理解這個(gè)概念。為了簡(jiǎn)單起見(jiàn),我們將只使用一個(gè)特征-每個(gè)住宅的平均房間數(shù)(Average number of rooms per dwelling)(X)來(lái)預(yù)測(cè)因變量-1000美元價(jià)位的房屋的中位數(shù)價(jià)值(Median Value)(Y)。
我們將使用梯度下降(Gradient Descent)作為優(yōu)化策略來(lái)查找回歸線。我不會(huì)詳細(xì)介紹Gradient Descent的細(xì)節(jié),但這里提醒一下權(quán)重更新規(guī)則:
這里,θ_j 是要更新的權(quán)重,α 是學(xué)習(xí)率,J 是成本函數(shù)。成本函數(shù)由 θ 參數(shù)化。我們的目標(biāo)是找到產(chǎn)生最小總成本的 θ 值。
我已經(jīng)為下面的每個(gè)損失函數(shù)定義了我們將遵循的步驟:
- 寫出預(yù)測(cè)函數(shù)f(X)的表達(dá)式,并確定我們需要找到的參數(shù)
- 確定每個(gè)訓(xùn)練樣本計(jì)算得到的損失
- 找到成本函數(shù)(所有樣本的平均損失)的表達(dá)式
- 找到與每個(gè)未知參數(shù)相關(guān)的成本函數(shù)的梯度
- 確定學(xué)習(xí)率并在固定次數(shù)中進(jìn)行迭代執(zhí)行權(quán)重更新規(guī)則
2.1. 平方誤差損失
每個(gè)訓(xùn)練樣本的平方誤差損失(也稱為L2 Loss)是實(shí)際值和預(yù)測(cè)值之差的平方:
相應(yīng)的成本函數(shù)是這些平方誤差的平均值(MSE)。
推薦你引用以下代碼時(shí)先嘗試自己計(jì)算出梯度
def update_weights_MSE(m, b, X, Y, learning_rate): m_deriv = 0 b_deriv = 0 N = len(X) for i in range(N): # 計(jì)算偏導(dǎo)數(shù)為 # -2x(y - (mx + b)) m_deriv += -2*X[i] * (Y[i] - (m*X[i] + b)) # -2(y - (mx + b)) b_deriv += -2*(Y[i] - (m*X[i] + b)) # 我們減去它,因?yàn)閷?dǎo)數(shù)指向最陡的上升方向 m -= (m_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m, b
在波士頓住房數(shù)據(jù)上,在不同的學(xué)習(xí)率中分別迭代了500次得到下圖:
讓我們?cè)僬務(wù)凪SE損失函數(shù),它是一個(gè)二次函數(shù)(形式為ax^2+bx+c),并且值大于等于0。二次函數(shù)的圖形如下圖所示:
二次函數(shù)僅具有全局最小值。由于沒(méi)有局部最小值,所以我們永遠(yuǎn)不會(huì)陷入它。因此,可以保證梯度下降將收斂到全局最小值(如果它完全收斂)。
MSE損失函數(shù)通過(guò)平方誤差來(lái)懲罰模型犯的大錯(cuò)誤。把一個(gè)比較大的數(shù)平方會(huì)使它變得更大。但有一點(diǎn)需要注意,這個(gè)屬性使MSE成本函數(shù)對(duì)異常值的健壯性降低。因此,如果我們的數(shù)據(jù)容易出現(xiàn)許多的異常值,則不應(yīng)使用這個(gè)它。
2.2. 絕對(duì)誤差損失
每個(gè)訓(xùn)練樣本的絕對(duì)誤差是預(yù)測(cè)值和實(shí)際值之間的距離,與符號(hào)無(wú)關(guān)。絕對(duì)誤差也稱為L1 Loss:
正如我之前提到的,成本是這些絕對(duì)誤差的平均值(MAE)。
與MSE相比,MAE成本對(duì)異常值更加健壯。但是,在數(shù)學(xué)方程中處理絕對(duì)或模數(shù)運(yùn)算符并不容易。我們可以認(rèn)為這是MAE的缺點(diǎn)。
以下是MAE成本更新權(quán)重的代碼
def update_weights_MAE(m, b, X, Y, learning_rate): m_deriv = 0 b_deriv = 0 N = len(X) for i in range(N): #計(jì)算偏導(dǎo)數(shù) # -x(y - (mx + b)) / |mx + b| m_deriv += - X[i] * (Y[i] - (m*X[i] + b)) / abs(Y[i] - (m*X[i] + b)) # -(y - (mx + b)) / |mx + b| b_deriv += -(Y[i] - (m*X[i] + b)) / abs(Y[i] - (m*X[i] + b)) #我們減去它,因?yàn)閷?dǎo)數(shù)指向最陡的上升方向 m -= (m_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m, b
在不同學(xué)習(xí)速率中分別迭代500次后,我們得到以下圖:
2.3. Huber損失
Huber損失結(jié)合了MSE和MAE的最佳特性。對(duì)于較小的誤差,它是二次的,否則是線性的(對(duì)于其梯度也是如此)。Huber損失需要確定 δ 參數(shù):
def update_weights_Huber(m, b, X, Y, delta, learning_rate): m_deriv = 0 b_deriv = 0 N = len(X) for i in range(N): # 小值的二次導(dǎo)數(shù),大值的線性導(dǎo)數(shù) if abs(Y[i] - m*X[i] - b) <= delta: m_deriv += -X[i] * (Y[i] - (m*X[i] + b)) b_deriv += - (Y[i] - (m*X[i] + b)) else: m_deriv += delta * X[i] * ((m*X[i] + b) - Y[i]) / abs((m*X[i] + b) - Y[i]) b_deriv += delta * ((m*X[i] + b) - Y[i]) / abs((m*X[i] + b) - Y[i]) #我們減去它,因?yàn)閷?dǎo)數(shù)指向最陡的上升方向 m -= (m_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m, b
我們以0.0001的學(xué)習(xí)速率分別對(duì) δ 參數(shù)的不同值進(jìn)行500次權(quán)重更新迭代得到下圖:
Huber損失對(duì)于異常值比MSE更強(qiáng)。它用于穩(wěn)健回歸(robust regression),M估計(jì)法(M-estimator)和可加模型(additive model)。Huber損失的變體也可以用于分類。
3. 二分類損失函數(shù)
意義如其名。二分類是指將物品分配到兩個(gè)類中的一個(gè)。該分類基于應(yīng)用于輸入特征向量的規(guī)則。二分類的例子例如,根據(jù)郵件的主題將電子郵件分類為垃圾郵件或非垃圾郵件。
我將在乳腺癌數(shù)據(jù)集^2上說(shuō)明這些二分類損失函數(shù)。
我們希望根據(jù)平均半徑,面積,周長(zhǎng)等特征將腫瘤分類為"惡性(Malignant)"或"良性(Benign)"。為簡(jiǎn)化起見(jiàn),我們將僅使用兩個(gè)輸入特征(X_1和X_2),即"最差區(qū)域(worst area)"和"平均對(duì)稱性(mean symmetry)"用于分類。Y是二值的,為0(惡性)或1(良性)。
這是我們數(shù)據(jù)的散點(diǎn)圖:
cancer
3.1. 二元交叉熵?fù)p失
讓我們從理解術(shù)語(yǔ)"熵"開(kāi)始。 通常,我們使用熵來(lái)表示無(wú)序或不確定性。測(cè)量具有概率分布p(X)的隨機(jī)變量X:
負(fù)號(hào)用于使最后的結(jié)果為正數(shù)。
概率分布的熵值越大,表明分布的不確定性越大。同樣,一個(gè)較小的值代表一個(gè)更確定的分布。
這使得二元交叉熵適合作為損失函數(shù)(你希望最小化其值)。我們對(duì)輸出概率p的分類模型使用二元交叉熵?fù)p失。
元素屬于第1類(或正類)的概率=p 元素屬于第0類(或負(fù)類)的概率=1-p
然后,輸出標(biāo)簽y(可以取值0和1)的交叉熵?fù)p失和和預(yù)測(cè)概率p定義為:
這也稱為L(zhǎng)og-Loss(對(duì)數(shù)損失)。為了計(jì)算概率p,我們可以使用sigmoid函數(shù)。這里,z是我們輸入功能的函數(shù):
sigmoid函數(shù)的范圍是[0,1],這使得它適合于計(jì)算概率。
推薦你引用以下代碼時(shí)先嘗試自己計(jì)算出梯度
def update_weights_BCE(m1, m2, b, X1, X2, Y, learning_rate): m1_deriv = 0 m2_deriv = 0 b_deriv = 0 N = len(X1) for i in range(N): s = 1 / (1 / (1 + math.exp(-m1*X1[i] - m2*X2[i] - b))) # 計(jì)算偏導(dǎo)數(shù) m1_deriv += -X1[i] * (s - Y[i]) m2_deriv += -X2[i] * (s - Y[i]) b_deriv += -(s - Y[i]) # 我們減去它,因?yàn)閷?dǎo)數(shù)指向最陡的上升方向 m1 -= (m1_deriv / float(N)) * learning_rate m2 -= (m2_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m1, m2, b
在不同alpha值里使用權(quán)重更新規(guī)則進(jìn)行1000次迭代得到下圖:
3.2. Hinge損失
Hinge損失主要用于帶有類標(biāo)簽-1和1的支持向量機(jī)(SVM)。因此,請(qǐng)確保將數(shù)據(jù)集中"惡性"類的標(biāo)簽從0更改為-1。
Hinge損失不僅會(huì)懲罰錯(cuò)誤的預(yù)測(cè),還會(huì)懲罰不自信的正確預(yù)測(cè)。
數(shù)據(jù)對(duì)(x,y)的Hinge損失如圖:
def update_weights_Hinge(m1, m2, b, X1, X2, Y, learning_rate): m1_deriv = 0 m2_deriv = 0 b_deriv = 0 N = len(X1) for i in range(N): # 計(jì)算偏導(dǎo)數(shù) if 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] # 否則偏導(dǎo)數(shù)為0 # 我們減去它,因?yàn)閷?dǎo)數(shù)指向最陡的上升方向 m1 -= (m1_deriv / float(N)) * learning_rate m2 -= (m2_deriv / float(N)) * learning_rate b -= (b_deriv / float(N)) * learning_rate return m1, m2, b
在使用三個(gè)不同的alpha值運(yùn)行2000次迭代的更新函數(shù)之后,得到下圖:
Hinge損失簡(jiǎn)化了SVM的數(shù)學(xué)運(yùn)算,同時(shí)最大化了損失(與對(duì)數(shù)損失(Log-Loss)相比)。當(dāng)我們想要做實(shí)時(shí)決策而不是高度關(guān)注準(zhǔn)確性時(shí),就可以使用它。
4. 多分類損失函數(shù)
電子郵件不僅被歸類為垃圾郵件或垃圾郵件(這不再是90年代了!)。它們分為各種其他類別-工作,家庭,社交,促銷等。
我們將使用Iris數(shù)據(jù)集^3來(lái)理解剩余的兩個(gè)損失函數(shù)。我們將使用2個(gè)特征 X_1 萼片長(zhǎng)度(Sepal length)和特征 X_2 花瓣寬度(Petal width)來(lái)預(yù)測(cè)鳶尾花的類別(Y) -Setosa,Versicolor或Virginica
我們的任務(wù)是使用神經(jīng)網(wǎng)絡(luò)模型和Keras內(nèi)置的Adam優(yōu)化器來(lái)實(shí)現(xiàn)分類器。這是因?yàn)殡S著參數(shù)數(shù)量的增加,數(shù)學(xué)以及代碼將變得難以理解。
這是我們數(shù)據(jù)的散點(diǎn)圖:
4.1. 多分類交叉熵?fù)p失
多分類交叉熵?fù)p失是二元交叉熵?fù)p失的推廣。輸入向量 X_i 和相應(yīng)的one-hot編碼目標(biāo)向量 Y_i 的損失是:
我們使用softmax函數(shù)來(lái)找到概率 P_ij:
"Softmax層是接在神經(jīng)網(wǎng)絡(luò)的輸出層前。Softmax層必須與輸出層具有相同數(shù)量的節(jié)點(diǎn)。"google Developer's Blog
最后,我們的輸出是具有給定輸入的最大概率的類別。
我們使用一個(gè)輸入層和一個(gè)輸出層建立一個(gè)模型,并用不同的學(xué)習(xí)速度編譯它。在model.compile()語(yǔ)句中將損失函數(shù)指定為' categorical_crossentropy ':
# 導(dǎo)入包 from keras.layers import Dense from keras.models import Sequential from keras.optimizers import adam #alpha設(shè)置為0.001,如adam優(yōu)化器中的lr參數(shù)所示 # 創(chuàng)建模型 model_alpha1 = Sequential() model_alpha1.add(Dense(50, input_dim=2, activation='relu')) model_alpha1.add(Dense(3, activation='softmax')) # 編譯模型 opt_alpha1 = adam(lr=0.001) model_alpha1.compile(loss='categorical_crossentropy', optimizer=opt_alpha1, metrics=['accuracy']) # 擬合模型 # dummy_Y是one-hot形式編碼的 # history_alpha1用于為繪圖的驗(yàn)證和準(zhǔn)確性評(píng)分 history_alpha1 = model_alpha1.fit(dataX, dummy_Y, validation_data=(dataX, dummy_Y), epochs=200, verbose=0)
在不同的學(xué)習(xí)率經(jīng)過(guò)200輪訓(xùn)練后成本和準(zhǔn)確度的圖如下:
4.2. KL散度
KL散度概率分布與另一個(gè)概率分布區(qū)別的度量。KL散度為零表示分布相同。
請(qǐng)注意,發(fā)散函數(shù)不對(duì)稱。即:
這就是為什么KL散度不能用作距離度量的原因。
我將描述使用KL散度作為損失函數(shù)而不進(jìn)行數(shù)學(xué)計(jì)算的基本方法。在給定一些近似分布Q的情況下,我們希望近似關(guān)于輸入特征的目標(biāo)變量的真實(shí)概率分布P. 由于KL散度不對(duì)稱,我們可以通過(guò)兩種方式實(shí)現(xiàn):
第一種方法用于監(jiān)督學(xué)習(xí),第二種方法用于強(qiáng)化學(xué)習(xí)。KL散度在功能上類似于多分類交叉熵,KL散度也可以稱為P相對(duì)于Q的相對(duì)熵:
我們?cè)赾ompile()函數(shù)中指定'kullback_leibler_divergence'作為損失函數(shù),就像我們之前在處理多分類交叉熵?fù)p失時(shí)所做的那樣。
# 導(dǎo)入包 from keras.layers import Dense from keras.models import Sequential from keras.optimizers import adam # alpha設(shè)置為0.001,如adam優(yōu)化器中的lr參數(shù)所示 # 創(chuàng)建模型 model_alpha1 = Sequential() model_alpha1.add(Dense(50, input_dim=2, activation='relu')) model_alpha1.add(Dense(3, activation='softmax')) # 編譯模型 opt_alpha1 = adam(lr=0.001) model_alpha1.compile(loss='kullback_leibler_divergence', optimizer=opt_alpha1, metrics=['accuracy']) # 擬合模型 # dummy_Y是one-hot形式編碼的 # history_alpha1用于為繪圖的驗(yàn)證和準(zhǔn)確性評(píng)分 history_alpha1 = model_alpha1.fit(dataX, dummy_Y, validation_data=(dataX, dummy_Y), epochs=200, verbose=0)
在不同的學(xué)習(xí)率經(jīng)過(guò)200輪訓(xùn)練后成本和準(zhǔn)確度的圖如下:
與多分類分類相比,KL散度更常用于逼近復(fù)雜函數(shù)。我們?cè)谑褂米兎肿詣?dòng)編碼器(VAE)等深度生成模型時(shí)經(jīng)常使用KL散度。






