训练softmax分类器实例_第四章.模型训练
迄今為止,我們只是把機(jī)器學(xué)習(xí)模型及其大多數(shù)訓(xùn)練算法視為黑盒。但是如果你做了前面幾章的一些練習(xí),你可能會(huì)驚訝于你可以在不知道任何關(guān)于背后原理的情況下完成很多工作:優(yōu)化一個(gè)回歸系統(tǒng),改進(jìn)一個(gè)數(shù)字圖像分類器,甚至從頭開(kāi)始建立一個(gè)垃圾郵件分類器,所有這些都不知道它們的實(shí)際工作原理。事實(shí)上,在很多情況下,你其實(shí)并不需要知道這些實(shí)現(xiàn)細(xì)節(jié)。
然而,深刻理解事物的工作原理,可以幫助你快速找到合適的模型、正確的訓(xùn)練算法,以及一組適合目標(biāo)任務(wù)的超參數(shù)。除此之外,也會(huì)幫助你更有效地調(diào)試問(wèn)題和進(jìn)行錯(cuò)誤分析。最后,本章所討論的大部分主題將對(duì)理解、構(gòu)建和訓(xùn)練神經(jīng)網(wǎng)絡(luò)(將在本書(shū)第二部分中討論)至關(guān)重要。
在本章中,我們將從線性回歸模型開(kāi)始,因?yàn)樗亲詈?jiǎn)單的模型之一。我們將討論兩種非常不同的訓(xùn)練方法。
- 使用 "閉式 "方程,直接計(jì)算出最適合模型與訓(xùn)練集的模型參數(shù)(即在訓(xùn)練集上最小化成本函數(shù)的模型參數(shù))。
- 使用一種梯度下降(GD)的迭代優(yōu)化方法,通過(guò)逐步調(diào)整模型參數(shù),使訓(xùn)練集上的成本函數(shù)最小化,并最終收斂到與第一種方法相同的參數(shù)。我們來(lái)看一下梯度下降的幾個(gè)變體,在第二部分學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)時(shí)將會(huì)反復(fù)使用這些變體:Batch GD、Mini-batch GD和Stochastic GD。
然后,我們將討論一下多項(xiàng)式回歸,這是一個(gè)比較復(fù)雜的模型,可以擬合非線性的數(shù)據(jù)集。由于這個(gè)模型的參數(shù)比線性回歸更多,所以容易對(duì)訓(xùn)練數(shù)據(jù)過(guò)擬合,我們將討論如何使用學(xué)習(xí)曲線來(lái)檢測(cè)是否存在這種情況,以及幾種可以降低過(guò)擬合風(fēng)險(xiǎn)的正則化方法。
最后,我們?cè)僦赜懻搩蓚€(gè)常用于分類任務(wù)的模型:Logistic回歸和Softmax回歸。
線性回歸
在第一章中,我們研究了一個(gè)簡(jiǎn)單的生活滿意度回歸模型:
life_satisfaction
GDP_per_capita.該模型為單個(gè)輸入特征GDP_per_capita的線性函數(shù),其中
和 為模型的參數(shù)。更一般地,線性模型是通過(guò)簡(jiǎn)單地計(jì)算輸入特征的加權(quán)平均,并加上一個(gè)偏置項(xiàng)(也稱為截距項(xiàng))來(lái)進(jìn)行預(yù)測(cè),如公式4-1所示:
其中:- 是模型的預(yù)測(cè)值
- 是模型輸入的特征數(shù)量
- 是第 個(gè)特征的取值
- 是第 個(gè)模型參數(shù)
上述公式用矢量化的形式可以寫(xiě)得更簡(jiǎn)潔,如公式4-2所示:
其中:- 是模型的參數(shù)向量,包含了偏置項(xiàng) 和權(quán)重項(xiàng) 到
- 是實(shí)例的特征向量,包含了特征 到 ,其中 始終為常數(shù)
但我們應(yīng)該如何訓(xùn)練呢?回顧一下,訓(xùn)練模型意味著找出在訓(xùn)練集上最適合模型的參數(shù)。為此,我們首先需要一個(gè)目標(biāo)函數(shù),正如我們?cè)诘诙轮兴吹?#xff0c;回歸模型最常用的度量標(biāo)準(zhǔn)是均方根誤差(RMSE)。為了訓(xùn)練線性回歸模型,我們需要尋找最小化RMSE的
值,而在實(shí)踐中,更簡(jiǎn)單的方法是最小化均方誤差(MSE),因?yàn)樗鼈兙哂幸恢碌慕Y(jié)果。在線性假設(shè)
下,模型在訓(xùn)練集 上 的計(jì)算如公式4-3所示:正規(guī)方程
為了找到最小化成本函數(shù)的
值,可以通過(guò)閉式解,這就是所謂的正規(guī)方程(方程4-4)。其中:- 為最小化代價(jià)函數(shù)的模型參數(shù)的取值
- 為標(biāo)簽取值的向量,包含 到
現(xiàn)在我們來(lái)生成一些類似線性關(guān)系的數(shù)據(jù)
import numpy as npX = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1)我們可以使用正規(guī)方程進(jìn)行求解,只需使用NumPy的線性代數(shù)模塊(np.linalg)中的inv()函數(shù)來(lái)計(jì)算矩陣的逆,并使用dot()方法進(jìn)行矩陣乘法。
X_b = np.c_[np.ones((100, 1)), X] # add x0 = 1 to each instance theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)我們用來(lái)生成數(shù)據(jù)的函數(shù)是
。讓我們看看求解得出的方程是什么。theta_best # array([[4.21509616], # [2.77011339]])我們本來(lái)希望
和 ,但是已經(jīng)足夠接近了,因?yàn)樵肼暤挠绊?#xff0c;無(wú)法恢復(fù)原始函數(shù)的精確參數(shù)。我們來(lái)做些預(yù)測(cè):
X_new = np.array([[0], [2]]) X_new_b = np.c_[np.ones((2, 1)), X_new] # add x0 = 1 to each instance y_predict = X_new_b.dot(theta_best) y_predict # array([[4.21509616], # [9.75532293]])plt.plot(X_new, y_predict, "r-") plt.plot(X, y, "b.") plt.axis([0, 2, 0, 15]) plt.show()使用Scikit-Learn進(jìn)行線性回歸非常簡(jiǎn)單。
from sklearn.linear_model import LinearRegressionlin_reg = LinearRegression() lin_reg.fit(X, y) lin_reg.intercept_, lin_reg.coef_ # (array([4.21509616]), array([[2.77011339]])) lin_reg.predict(X_new) # array([[4.21509616], # [9.75532293]])LinearRegression類是基于scipy.linalg.lstsq()函數(shù)( "最小二乘法"),你可以直接調(diào)用它。
theta_best_svd, residuals, rank, s = np.linalg.lstsq(X_b, y, rcond=1e-6) theta_best_svd # array([[4.21509616], # [2.77011339]])這個(gè)函數(shù)計(jì)算
,其中 是 的偽逆,你可以使用np.linalg.pinv()直接計(jì)算。np.linalg.pinv(X_b).dot(y) # array([[4.21509616], # [2.77011339]])偽逆本身的計(jì)算是通過(guò)奇異值分解(SVD)的方法進(jìn)行的,該方法將訓(xùn)練集矩陣
分解成三個(gè)矩陣相乘 (見(jiàn) numpy.linalg.svd())。偽逆的計(jì)算公式為 ,為了計(jì)算矩陣 ,首先將矩陣 中所有小于預(yù)先設(shè)定閾值的值都設(shè)置為 ,并將非零值替換為其倒數(shù),最后將矩陣進(jìn)行轉(zhuǎn)置。這種方法比計(jì)算正規(guī)方程更有效率,事實(shí)上,如果矩陣 不可逆(即奇異),如 或一些特征是多余的,正規(guī)方程可能就不起作用了,但偽逆總是存在的。現(xiàn)在我們來(lái)看看一種非常不同的訓(xùn)練線性回歸模型的方法,這種方法更適合于有大量特征或訓(xùn)練實(shí)例太多,無(wú)法放入內(nèi)存的情況。
梯度下降
梯度下降是一種通用的優(yōu)化算法,能夠?yàn)楦鞣N問(wèn)題找到最優(yōu)解,梯度下降的一般思想是反復(fù)調(diào)整參數(shù)來(lái)最小化成本函數(shù)。
假設(shè)你由于濃霧而在山中迷失,你只能感覺(jué)到腳下地面的坡度,要想快速到達(dá)谷底,一個(gè)好的策略就是沿著坡度最陡的方向下山。這正是 "梯度下降 "的思想:通過(guò)計(jì)算誤差函數(shù)關(guān)于參數(shù)向量
的局部梯度,并沿著梯度下降的方向前進(jìn),一旦梯度為零,你就達(dá)到了最低點(diǎn)!具體來(lái)說(shuō),你先隨機(jī)初始化參數(shù)
的取值,然后逐步調(diào)整,每次一小步,每一步都試圖減少成本函數(shù)(如MSE),直到算法收斂到最小值(見(jiàn)圖4-3)。梯度下降法的一個(gè)重要參數(shù)是步長(zhǎng)的大小,由超參數(shù)學(xué)習(xí)率所決定。如果學(xué)習(xí)率太小,那么算法就必須經(jīng)過(guò)多次迭代才能收斂,也就意味著需要很長(zhǎng)的時(shí)間進(jìn)行訓(xùn)練(見(jiàn)圖4-4)。
另一方面,如果學(xué)習(xí)率太高,你可能會(huì)跳過(guò)山谷,最后到了另一邊,甚至可能比之前更高了,這可能會(huì)導(dǎo)致算法發(fā)散(見(jiàn)圖4-5)。
最后需要注意的是,并不是所有的代價(jià)函數(shù)都是規(guī)則的碗狀結(jié)構(gòu)。代價(jià)函數(shù)的曲面可能會(huì)有洞、山脊、鞍部和各種不規(guī)則的地形,這使得收斂到最小值變得困難。圖4-6顯示了梯度下降的兩個(gè)主要挑戰(zhàn)。如果隨機(jī)初始化從左邊開(kāi)始,那么它將收斂到局部最小值,這顯然不如全局最小值。而如果從右邊開(kāi)始,那么它將需要很長(zhǎng)的時(shí)間來(lái)跨越鞍部,并且如果你過(guò)早地停止訓(xùn)練,將永遠(yuǎn)無(wú)法到達(dá)全局最小值。
幸運(yùn)的是,線性回歸模型的MSE代價(jià)函數(shù)恰好是一個(gè)凸函數(shù),這意味著如果你在曲線上選取任意兩點(diǎn),則連接它們的線段永遠(yuǎn)不會(huì)與曲線交叉,也就是說(shuō)沒(méi)有局部最小值,只有一個(gè)全局最小值。此外,它也是一個(gè)連續(xù)可導(dǎo)的函數(shù),這兩個(gè)特點(diǎn)可以保證梯度下降法會(huì)無(wú)限接近全局最小值。
事實(shí)上,即使代價(jià)函數(shù)具有碗的形狀,如果特征具有非常不同的尺度大小,它可以是一個(gè)拉長(zhǎng)的碗。圖4-7顯示了在特征1和2具有相同尺度的情況下,以及在特征1的取值比特征2小得多的情況下,梯度下降法在訓(xùn)練集上的迭代過(guò)程。
正如你所看到的,在左圖中,梯度下降法直接向最小值運(yùn)動(dòng),從而快速到達(dá)最小值,而在右圖中,先是向著與全局最小值方向幾乎正交的方向運(yùn)動(dòng),最后沿著一個(gè)幾乎平坦的山谷移動(dòng),雖然最終依然會(huì)到達(dá)最小值,但這需要很長(zhǎng)的時(shí)間。
當(dāng)使用梯度下降法時(shí),你應(yīng)該確保所有的特征都具有相似的尺度(例如,使用Scikit-Learn的StandardScaler類),否則會(huì)花費(fèi)很長(zhǎng)的時(shí)間來(lái)收斂。這張圖也說(shuō)明了訓(xùn)練一個(gè)模型意味著尋找一個(gè)模型參數(shù)的組合來(lái)最小化訓(xùn)練集上的代價(jià)函數(shù)。而這個(gè)過(guò)程是在模型的參數(shù)空間中進(jìn)行的:一個(gè)模型的參數(shù)越多,意味著這個(gè)空間的維度就越多,搜索的難度也就越大(大海撈針)。幸運(yùn)的是,由于在線性回歸的情況下,成本函數(shù)是凸的,搜索就變得容易多了。
批量梯度下降
為了實(shí)現(xiàn)梯度下降,你需要計(jì)算代價(jià)函數(shù)關(guān)于每個(gè)模型參數(shù)
的梯度。換句話說(shuō),你需要計(jì)算如果改變 一點(diǎn)點(diǎn),代價(jià)函數(shù)會(huì)有多大變化。這就是所謂的偏導(dǎo)數(shù)。代價(jià)函數(shù)關(guān)于參數(shù) 的偏導(dǎo)數(shù) 的計(jì)算如公式4-5所示:與其單獨(dú)計(jì)算這些偏導(dǎo)數(shù),不如使用公式4-6一次性計(jì)算完梯度向量,記為 n
abla_{theta} MSE(theta) ,其包含了代價(jià)函數(shù)的所有偏導(dǎo)數(shù)。請(qǐng)注意,上述公式在梯度下降的每一步中都涉及整個(gè)訓(xùn)練集 的計(jì)算!這就是為什么該算法被稱為 "批量梯度下降"(Batch Gradient Descent):它在每一步都使用所有訓(xùn)練數(shù)據(jù)(實(shí)際上,完全梯度下降可能是一個(gè)更好的名字)。因此,在非常大的訓(xùn)練集上,它的速度會(huì)變得非常慢,但是,梯度下降法隨著特征數(shù)量的增加具有良好的可擴(kuò)展性:當(dāng)面對(duì)幾十萬(wàn)個(gè)特征的時(shí)侯,使用梯度下降法訓(xùn)練線性回歸模型要比使用正規(guī)方程或SVD分解法快得多。一旦有了梯度向量,其指向?yàn)樯掀?#xff0c;我們所需要做的就是反方向下坡。這意味著從
中減去 。 這就是學(xué)習(xí)率 的作用所在:將梯度向量乘以 來(lái)確定下坡的步長(zhǎng)(公式4-7)。我們來(lái)看看該算法的快速實(shí)現(xiàn):
eta = 0.1 # learning rate n_iterations = 1000 m = 100theta = np.random.randn(2,1) # random initializationfor iteration in range(n_iterations):gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)theta = theta - eta * gradientstheta # array([[4.21509616], # [2.77011339]])這正是正規(guī)方程所求的! 梯度下降法的效果非常好,但如果你使用了不同的學(xué)習(xí)率
呢?圖4-8展示了使用三種不同學(xué)習(xí)率的梯度下降的前10步(虛線代表起始)。Figure 4-8. Gradient Descent with various learning rates為了找到一個(gè)好的學(xué)習(xí)率,你可以使用網(wǎng)格搜索(見(jiàn)第2章)。但是,您可能希望限制迭代次數(shù),以便網(wǎng)格搜索可以淘汰那些需要太長(zhǎng)時(shí)間才能收斂的模型。
你可能想知道如何設(shè)置迭代次數(shù)。如果它太低,當(dāng)算法停止時(shí),你仍然會(huì)離最優(yōu)解很遠(yuǎn);但如果它太高,你會(huì)浪費(fèi)時(shí)間,而模型參數(shù)卻不再改變。一個(gè)簡(jiǎn)單的解決方案是設(shè)置一個(gè)非常大的迭代次數(shù),但當(dāng)梯度向量變得很小,也就是說(shuō),當(dāng)它的范數(shù)變得小于一個(gè)很小的數(shù)值
(稱為容忍度)時(shí),中斷算法,因?yàn)榇藭r(shí)梯度下降已經(jīng)(幾乎)達(dá)到最小值了。隨機(jī)梯度下降
批量梯度下降的主要問(wèn)題是其每一步都使用整個(gè)訓(xùn)練集來(lái)計(jì)算梯度,所有當(dāng)訓(xùn)練集很大時(shí),迭代的速度就會(huì)非常慢。相反地,隨機(jī)梯度下降法在每一步都會(huì)在訓(xùn)練集中隨機(jī)挑選一個(gè)實(shí)例,并僅基于該實(shí)例來(lái)計(jì)算梯度,顯然,每次只處理一個(gè)實(shí)例會(huì)使算法的速度快得多。
另一方面,由于其隨機(jī)性的特點(diǎn),該算法比Batch Gradient Descent的規(guī)律性要差得多:代價(jià)函數(shù)不是緩緩下降到達(dá)最小值,而是上下跳動(dòng),總體上下降。隨著時(shí)間的推移,它最終會(huì)非常接近最小值,但是就算到了最小值,也會(huì)繼續(xù)跳動(dòng),永遠(yuǎn)不會(huì)穩(wěn)定下來(lái)(見(jiàn)圖4-9)。所以當(dāng)算法停止時(shí),最終得到的參數(shù)值是好的,但并不是最優(yōu)的。
當(dāng)代價(jià)函數(shù)非常不規(guī)則時(shí)(如圖4-6),這實(shí)際上可以幫助算法跳出局部最小值,所以隨機(jī)梯度下降比批量梯度下降有更好的機(jī)會(huì)找到全局最小值。
因此,隨機(jī)性對(duì)于跳出局部最優(yōu)值是有利的,但也意味著算法永遠(yuǎn)無(wú)法在最小值處安頓下來(lái)。解決該難題的一個(gè)辦法是學(xué)習(xí)率衰減。步數(shù)一開(kāi)始很大(有助于加速并跳出局部最小值),然后逐漸減小,讓算法在全局最小值處穩(wěn)定下來(lái)。這個(gè)過(guò)程類似于模擬退火,這種算法的靈感來(lái)自于冶金學(xué)中的退火過(guò)程,即熔融的金屬被緩慢冷卻。決定每次迭代時(shí)學(xué)習(xí)率的函數(shù)稱為學(xué)習(xí)調(diào)度。如果學(xué)習(xí)率降低得太快,可能會(huì)卡在局部最小值,甚至中途停止,但如果學(xué)習(xí)率降低得太慢,可能會(huì)在最小值附近跳動(dòng)很長(zhǎng)時(shí)間,如果此時(shí)過(guò)早地停止訓(xùn)練,最終得到的將是一個(gè)次優(yōu)的解。
下面這段代碼使用了一個(gè)簡(jiǎn)單的學(xué)習(xí)調(diào)度實(shí)現(xiàn)了隨機(jī)梯度下降。
n_epochs = 50 m = len(X_b) t0, t1 = 5, 50 # learning schedule hyperparametersdef learning_schedule(t):return t0 / (t + t1)theta = np.random.randn(2,1) # random initializationfor epoch in range(n_epochs):for i in range(m):random_index = np.random.randint(m)xi = X_b[random_index:random_index+1]yi = y[random_index:random_index+1]gradients = 2 * xi.T.dot(xi.dot(theta) - yi)eta = learning_schedule(epoch * m + i)theta = theta - eta * gradientstheta # array([[4.21076011], # [2.74856079]])根據(jù)傳統(tǒng)慣例,我們以
次迭代為一輪,每一輪稱為一個(gè)輪次(epoch)。上述的批量梯度下降對(duì)整個(gè)訓(xùn)練集進(jìn)行了 次迭代,而隨機(jī)梯度下降只對(duì)整個(gè)訓(xùn)練集進(jìn)行了50個(gè)輪次,就達(dá)到了一個(gè)相當(dāng)不錯(cuò)的解。圖4-10展示了訓(xùn)練的前20步:
Figure 4-10. The first 20 steps of Stochastic Gradient Descent注意到,由于實(shí)例是隨機(jī)選取的,所以在每個(gè)epoch中, 有些實(shí)例可能會(huì)被選取幾次,而有些實(shí)例可能根本不會(huì)被選取。如果你想確保訓(xùn)練過(guò)程使用到每一個(gè)實(shí)例,一種方法是對(duì)訓(xùn)練集進(jìn)行洗牌(確保將輸入特征和標(biāo)簽一起洗牌),然后逐個(gè)實(shí)例進(jìn)行迭代。不過(guò),這種方法一般收斂比較慢。
基于Scikit-Learn的隨機(jī)梯度下降進(jìn)行線性回歸,可以使用 SGDRegressor 類,該類默認(rèn)為優(yōu)化平方誤差代價(jià)函數(shù)。
下面的代碼運(yùn)行最大epoch數(shù)為1,000,或者直到損失下降小于0.001為止(max_iter=1000, tol=1e-3),初始學(xué)習(xí)率為0.1(eta0=0.1),使用默認(rèn)的學(xué)習(xí)調(diào)度(與前面的不同),不使用任何正則化(penalty=None)。
from sklearn.linear_model import SGDRegressorsgd_reg = SGDRegressor(max_iter=1000, tol=1e-3, penalty=None, eta0=0.1, random_state=42) sgd_reg.fit(X, y.ravel())sgd_reg.intercept_, sgd_reg.coef_ # (array([4.24365286]), array([2.8250878]))小批量梯度下降
最后我們要講的梯度下降算法叫做小批量梯度下降。如果你知道了批量梯度下降和隨機(jī)梯度下降,應(yīng)該就容易理解了:在每一步,小批量梯度下降并不是基于完整的訓(xùn)練集或僅僅基于單個(gè)實(shí)例來(lái)計(jì)算梯度,而是在小批量的隨機(jī)實(shí)例集上計(jì)算梯度。與隨機(jī)梯度下降相比,小批量梯度下降的主要優(yōu)勢(shì)在于,你可以從矩陣運(yùn)算的硬件優(yōu)化中獲得性能提升,尤其是在使用GPU時(shí)。
此外,與隨機(jī)梯度下降相比,小批量梯度下降在參數(shù)空間的進(jìn)展并沒(méi)有那么不穩(wěn)定,尤其是在相當(dāng)大的小批量下。因此,小批量梯度下降最終會(huì)比隨機(jī)梯度下降更接近最小值,但同時(shí)它可能會(huì)更難脫離局部最小值。圖4-11展示了三種梯度下降算法在訓(xùn)練過(guò)程中的路徑,它們最終都在集中最小值附近,但批量梯度下降的路徑實(shí)際上停在了最小值處,而隨機(jī)梯度下降和小批量梯度下降都繼續(xù)在最小值附近擺動(dòng)。但是,別忘了,批量梯度下降每走一步都需要大量的時(shí)間,并且如果你使用一個(gè)合適的學(xué)習(xí)調(diào)度,隨機(jī)梯度下降和小批量梯度下降也會(huì)達(dá)到最小值。
讓我們比較一下到目前為止我們討論過(guò)的線性回歸的算法(回憶一下,
是訓(xùn)練實(shí)例的數(shù)量, 是特征的數(shù)量)。多項(xiàng)式回歸
如果你的數(shù)據(jù)比直線更復(fù)雜怎么辦?你可以使用線性模型來(lái)擬合非線性數(shù)據(jù),一個(gè)簡(jiǎn)單的方法是將每個(gè)特征的冪級(jí)添加為新特征,然后在這個(gè)擴(kuò)展的特征集上訓(xùn)練一個(gè)線性模型,這就是所謂的多項(xiàng)式回歸。
我們來(lái)看一個(gè)例子,首先,我們根據(jù)一個(gè)簡(jiǎn)單的二次方程(加上一些噪聲,見(jiàn)圖4-12),生成一些非線性數(shù)據(jù)。
m = 100 X = 6 * np.random.rand(m, 1) - 3 y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1)顯然,直線永遠(yuǎn)無(wú)法正確擬合這些數(shù)據(jù),因此,我們使用 Scikit- Learn 的 PolynomialFeatures類來(lái)轉(zhuǎn)換我們的訓(xùn)練數(shù)據(jù),并將訓(xùn)練集中每個(gè)特征的平方作為新的特征添加進(jìn)來(lái)(本例中只有一個(gè)特征)。
from sklearn.preprocessing import PolynomialFeatures poly_features = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly_features.fit_transform(X) X[0] # array([-0.75275929]) X_poly[0] # array([-0.75275929, 0.56664654])現(xiàn)在你可以對(duì)這個(gè)擴(kuò)展的訓(xùn)練數(shù)據(jù)擬合一個(gè)LinearRegression模型(圖4-13)。
lin_reg = LinearRegression() lin_reg.fit(X_poly, y) lin_reg.intercept_, lin_reg.coef_ # (array([1.78134581]), array([[0.93366893, 0.56456263]]))還不錯(cuò),預(yù)測(cè)模型為:
,實(shí)際模型為: .需要注意的是,當(dāng)數(shù)據(jù)具有多個(gè)特征時(shí),多項(xiàng)式回歸能夠找到特征之間的交互關(guān)系(這是普通線性回歸模型無(wú)法做到的)。這是因?yàn)镻olynomialFeatures還可以將所有特征的組合到給定的次數(shù)。例如,如果有兩個(gè)特征
和 ,PolynomialFeatures中的degree=3,則除了添加特征 外,還會(huì)添加組合特征 。PolynomialFeatures(degree=d)將包含 個(gè)特征的數(shù)組轉(zhuǎn)換成包含 個(gè)特征的數(shù)組。學(xué)習(xí)曲線
如果你嘗試高次的多項(xiàng)式回歸,你可能會(huì)比普通線性回歸更好地?cái)M合訓(xùn)練數(shù)據(jù)。圖4-14將300次的多項(xiàng)式模型應(yīng)用于前面的訓(xùn)練數(shù)據(jù),并將結(jié)果與單純的線性模型和四元模型(二次多項(xiàng)式)進(jìn)行比較。注意到300次的多項(xiàng)式模型是搖擺不定的,并盡可能接近訓(xùn)練實(shí)例。
高次多項(xiàng)式回歸模型對(duì)訓(xùn)練數(shù)據(jù)嚴(yán)重過(guò)擬合,而線性模型則欠擬合。在這種情況下,最具泛化能力的模型是二次模型,這是合理的的,因?yàn)閿?shù)據(jù)是用二次模型生成的。但是在一般情況下,你不會(huì)知道數(shù)據(jù)是由什么函數(shù)生成的,所以你該如何決定你的模型應(yīng)該有多復(fù)雜?如何判斷你的模型對(duì)數(shù)據(jù)是過(guò)擬合還是欠擬合?
在第2章中,我們使用交叉驗(yàn)證來(lái)獲得模型泛化性能的估計(jì)。如果一個(gè)模型在訓(xùn)練數(shù)據(jù)上表現(xiàn)良好,但根據(jù)交叉驗(yàn)證的指標(biāo),它的泛化性能很差,那么你的模型就是過(guò)擬合。如果在這兩方面都表現(xiàn)不佳,那么就是欠擬合,這是判斷一個(gè)模型太簡(jiǎn)單或太復(fù)雜的一種方法。
另一種方法是觀察學(xué)習(xí)曲線:這些曲線是模型在訓(xùn)練集和驗(yàn)證集上的性能相對(duì)于訓(xùn)練集大小(或迭代次數(shù))的函數(shù)。下面的代碼定義了一個(gè)函數(shù),給定一些訓(xùn)練數(shù)據(jù),繪制模型的學(xué)習(xí)曲線。
from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_splitdef plot_learning_curves(model, X, y):X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=10)train_errors, val_errors = [], []for m in range(1, len(X_train)):model.fit(X_train[:m], y_train[:m])y_train_predict = model.predict(X_train[:m])y_val_predict = model.predict(X_val)train_errors.append(mean_squared_error(y_train[:m], y_train_predict))val_errors.append(mean_squared_error(y_val, y_val_predict))plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="train")plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="val")plt.legend(loc="upper right", fontsize=14) # not shown in the bookplt.xlabel("Training set size", fontsize=14) # not shownplt.ylabel("RMSE", fontsize=14) # not shownlin_reg = LinearRegression() plot_learning_curves(lin_reg, X, y) plt.axis([0, 80, 0, 3]) # not shown in the book plt.show() # not shown這是個(gè)欠擬合的模型,值得解釋一下。首先,我們來(lái)看看在訓(xùn)練數(shù)據(jù)上的表現(xiàn):當(dāng)訓(xùn)練集中只有一兩個(gè)實(shí)例時(shí),模型可以完美地?cái)M合它們,這就是為什么曲線從零開(kāi)始。但是隨著新的實(shí)例加入到訓(xùn)練集中,模型就不可能完美地?cái)M合訓(xùn)練數(shù)據(jù)了,這既是因?yàn)閿?shù)據(jù)是有噪聲的,也是因?yàn)閿?shù)據(jù)根本不是線性的。所以訓(xùn)練數(shù)據(jù)上的誤差會(huì)一直上升,直到達(dá)到一個(gè)平穩(wěn)的狀態(tài),這時(shí)向訓(xùn)練集添加新的實(shí)例并不會(huì)使平均誤差有多大的變化。現(xiàn)在我們來(lái)看看模型在驗(yàn)證數(shù)據(jù)上的表現(xiàn),當(dāng)模型在極少的訓(xùn)練實(shí)例上進(jìn)行訓(xùn)練時(shí),它無(wú)法進(jìn)行正確的泛化,這就是為什么最初的驗(yàn)證誤差相當(dāng)大。然后,當(dāng)模型被展示更多的訓(xùn)練實(shí)例時(shí),它就會(huì)學(xué)習(xí),因此驗(yàn)證誤差會(huì)慢慢下降。然而,直線又不能很好地對(duì)數(shù)據(jù)進(jìn)行建模,所以誤差也最終會(huì)達(dá)到一個(gè)平穩(wěn)狀態(tài),非常接近另一條曲線。
這些學(xué)習(xí)曲線是典型的模型欠擬合,兩條曲線都達(dá)到了一平緩,很接近,而且相當(dāng)高。
如果你的模型對(duì)訓(xùn)練數(shù)據(jù)欠擬合,添加更多的訓(xùn)練實(shí)例也無(wú)濟(jì)于事,你需要使用更復(fù)雜的模型或添加更好的特征。我們來(lái)看看10次多項(xiàng)式模型在相同數(shù)據(jù)上的學(xué)習(xí)曲線(圖4-16)。
from sklearn.pipeline import Pipelinepolynomial_regression = Pipeline([("poly_features", PolynomialFeatures(degree=10, include_bias=False)),("lin_reg", LinearRegression()),])plot_learning_curves(polynomial_regression, X, y) plt.axis([0, 80, 0, 3]) # not shown plt.show()這些學(xué)習(xí)曲線看起來(lái)有點(diǎn)像之前的曲線,但有兩個(gè)非常重要的區(qū)別。
- 訓(xùn)練數(shù)據(jù)的誤差比線性回歸模型低得多
- 曲線之間存在差距。這意味著模型在訓(xùn)練數(shù)據(jù)上的表現(xiàn)明顯好于驗(yàn)證數(shù)據(jù),這是過(guò)擬合的標(biāo)志,然而,如果你使用更大的訓(xùn)練集,兩條曲線會(huì)繼續(xù)變得更接近。
改進(jìn)過(guò)擬合模型的一種方法是給它輸入更多的訓(xùn)練數(shù)據(jù),直到驗(yàn)證誤差逼近訓(xùn)練誤差。
統(tǒng)計(jì)學(xué)和機(jī)器學(xué)習(xí)的一個(gè)重要理論成果是,一個(gè)模型的泛化誤差可以用三個(gè)不同的誤差之和來(lái)表示。偏差:這部分泛化誤差是由于錯(cuò)誤的假設(shè)造成的,比如假設(shè)數(shù)據(jù)是線性的,而實(shí)際上是二次元的。高偏差的模型很有可能是對(duì)訓(xùn)練數(shù)據(jù)欠擬合。方差:這部分是由于模型對(duì)訓(xùn)練數(shù)據(jù)的微小變化過(guò)于敏感。一個(gè)具有高自由度的模型(如高次多項(xiàng)式模型)很可能具有較高的方差,從而對(duì)訓(xùn)練數(shù)據(jù)過(guò)擬合。
隨機(jī)誤差:這部分是由于數(shù)據(jù)本身的噪聲。減少這部分誤差的唯一方法是清理數(shù)據(jù)(如修復(fù)數(shù)據(jù)源,如破損的傳感器,或檢測(cè)并去除異常值)。
增加一個(gè)模型的復(fù)雜性通常會(huì)增加其方差,減少其偏差。相反,降低一個(gè)模型的復(fù)雜性會(huì)增加它的偏差,減少它的方差。這就是為什么它被稱為權(quán)衡。
正則化線性回歸
正如我們?cè)诘?章和第2章中所看到的,減少過(guò)擬合的一個(gè)方法是對(duì)模型進(jìn)行正則化(即約束模型):模型的自由度越少,它就越難對(duì)數(shù)據(jù)過(guò)擬合。正則化多項(xiàng)式模型的一個(gè)簡(jiǎn)單方法是減少多項(xiàng)式的次數(shù)。
對(duì)于線性模型來(lái)說(shuō),正則化通常是通過(guò)約束模型的權(quán)重來(lái)實(shí)現(xiàn)的。我們現(xiàn)在來(lái)看一下嶺回歸、拉索回歸和彈性網(wǎng)絡(luò)三種不同的權(quán)重約束方式。
嶺回歸
嶺回歸(也叫Tikhonov正則化)是線性回歸的正則化版本:在代價(jià)函數(shù)中加入
的正則化項(xiàng),迫使學(xué)習(xí)算法不僅要擬合數(shù)據(jù),而且要使模型權(quán)重盡可能小。需要注意的是,正則化項(xiàng)只在訓(xùn)練期間添加到代價(jià)函數(shù)中,當(dāng)模型訓(xùn)練完成后,你要使用非正則化的性能度量來(lái)評(píng)估模型的性能。訓(xùn)練時(shí)使用的代價(jià)函數(shù)與測(cè)試時(shí)使用的性能度量標(biāo)準(zhǔn)往往是不同的。除了正則化之外,另一個(gè)原因是,一個(gè)好的代價(jià)函數(shù)應(yīng)該具有良好優(yōu)化的導(dǎo)數(shù),而用于測(cè)試的性能度量應(yīng)該盡可能地接近最終目標(biāo)。例如,分類模型通常使用對(duì)數(shù)損失等代價(jià)函數(shù)進(jìn)行訓(xùn)練,但是使用精度/召回率進(jìn)行評(píng)估。超參數(shù)
控制了對(duì)模型的正則化程度,如果 ,則嶺回歸就是線性回歸,如果 非常大,則所有的權(quán)重最終都會(huì)非常接近于零,結(jié)果就是一條平坦的線穿過(guò)數(shù)據(jù)的平均值。公式4-8給出了嶺回歸的代價(jià)函數(shù):注意到偏置項(xiàng)
是不需要正則化的。在進(jìn)行嶺回歸之前,對(duì)數(shù)據(jù)進(jìn)行縮放(例如,使用StandardScaler)是很重要的,因?yàn)樗鼘?duì)輸入特征的尺度很敏感,實(shí)際上大多數(shù)正則化模型都是如此。圖4-17展示了使用不同的懲罰系數(shù)
對(duì)一些線性數(shù)據(jù)進(jìn)行訓(xùn)練的嶺回歸模型。在左圖中,使用簡(jiǎn)單的Ridge模型,進(jìn)行線性擬合;在右圖中,首先使用PolynomialFeatures(degree=10)對(duì)數(shù)據(jù)進(jìn)行擴(kuò)展,然后使用StandardScaler對(duì)數(shù)據(jù)進(jìn)行縮放,最后對(duì)得到的特征應(yīng)用嶺回歸模型。注意到,增加 會(huì)導(dǎo)致曲線更平坦,從而減少模型的方差,但相應(yīng)地會(huì)增加其偏差。與線性回歸一樣,我們也可以通過(guò)計(jì)算閉式解或梯度下降來(lái)訓(xùn)練嶺回歸模型。方程4-9為對(duì)應(yīng)的閉式解,其中
為 的單位矩陣,只是左上角取值為0,因?yàn)槠鋵?duì)應(yīng)偏置項(xiàng)。下面使用閉式解來(lái)訓(xùn)練Scikit-Learn的嶺回歸:
from sklearn.linear_model import Ridge ridge_reg = Ridge(alpha=1, solver="cholesky", random_state=42) ridge_reg.fit(X, y) ridge_reg.predict([[1.5]]) # array([[1.55071465]])也可以使用隨機(jī)梯度下降法:
ridge_reg = Ridge(alpha=1, solver="sag", random_state=42) ridge_reg.fit(X, y) ridge_reg.predict([[1.5]]) # array([[1.5507201]])# SGD sgd_reg = SGDRegressor(penalty="l2", max_iter=1000, tol=1e-3, random_state=42) sgd_reg.fit(X, y.ravel()) sgd_reg.predict([[1.5]]) # array([1.47012588])其中超參數(shù)penalty設(shè)置要使用的正則化項(xiàng)的類型,指定 "l2 "表示希望SGD在代價(jià)函數(shù)中添加一個(gè)正則化項(xiàng),取值為權(quán)重向量的
范數(shù)的一半。拉索回歸
拉索回歸是線性回歸的另一個(gè)正則化版本:就像嶺回歸一樣,它在代價(jià)函數(shù)中增加了一個(gè)正則化項(xiàng),但它使用的是權(quán)重向量的
范數(shù)(見(jiàn)公式4-10)。與圖4-17類似,將嶺模型替換為拉索模型,并使用較小的
值,結(jié)果如圖4-18所示:拉索回歸的一個(gè)重要特點(diǎn)是它傾向于淘汰不重要的特征的權(quán)重(即將其設(shè)置為零)。例如,圖4-18中右圖中的虛線(
)看起來(lái)是二次的,而且?guī)缀跏蔷€性的,即所有高次的特征的權(quán)重都等于零。換句話說(shuō),拉索回歸會(huì)自動(dòng)進(jìn)行特征選擇,并輸出一個(gè)稀疏模型。你可以通過(guò)看圖4-19來(lái)了解為什么會(huì)這樣:軸代表模型的兩個(gè)參數(shù),背景輪廓代表不同的損失函數(shù)。在左上角的圖中,等高線代表了
損失( ),當(dāng)接近任何一個(gè)軸時(shí),其取值都會(huì)線性下降。例如,如果你初始化模型參數(shù)為 和 ,使用 "梯度下降 法"將使兩個(gè)參數(shù)均等地遞減(用黃色虛線表示),因此, 將首先達(dá)到 (因?yàn)樗婚_(kāi)始就接近 ),之后,梯度下降會(huì)順著軸滾下去,直到達(dá)到 (會(huì)有一點(diǎn)跳動(dòng),因?yàn)? 范數(shù)的梯度永遠(yuǎn)不會(huì)接近0:每個(gè)參數(shù)的梯度不是 就是 )。在右上角的圖中,等高線代表了拉索回歸的代價(jià)函數(shù)(即MSE代價(jià)函數(shù)加上 損失),白色的小圓圈顯示了梯度下降法優(yōu)化模型參數(shù)的路徑,這些參數(shù)初始化在 和 附近。我們?cè)僖淮巫⒁獾铰窂娇焖俚竭_(dá) ,然后沿著軸滾動(dòng),并圍繞全局最優(yōu)值(紅色方塊)跳動(dòng)。如果我們?cè)龃? ,全局最優(yōu)值將沿黃色虛線向左移動(dòng),而如果我們減小 ,全局最優(yōu)值將向右移動(dòng)(本例中,無(wú)正則化MSE的最優(yōu)參數(shù)為 和 )。底部的兩張圖顯示的是同樣的情況,只是懲罰項(xiàng)換成了
損失。在左下角的圖中,可以看到 損失會(huì)隨著距離原點(diǎn)的距離而減少,所以梯度下降走了一條直達(dá)原點(diǎn)的路徑。在右下角的圖中,等高線代表了嶺回歸的代價(jià)函數(shù)(即MSE代價(jià)函數(shù)加上 損失)。這與拉索回歸有兩個(gè)主要區(qū)別:首先,當(dāng)參數(shù)接近全局最優(yōu)時(shí),梯度會(huì)變小,所以梯度下降自然會(huì)變慢,這有助于收斂(因?yàn)闆](méi)有反彈);其次,當(dāng)你增大 時(shí),最佳參數(shù)(紅色方塊)會(huì)越來(lái)越接近原點(diǎn),但它們永遠(yuǎn)不會(huì)被完全消除(即其中一個(gè)取值為 )。在使用拉索回歸時(shí),為了避免梯度下降在最后繞著最優(yōu)值跳動(dòng),你需要在訓(xùn)練中逐漸降低學(xué)習(xí)率(它仍然會(huì)繞著最優(yōu)值跳動(dòng),但步子會(huì)越來(lái)越小,所以會(huì)收斂)。拉索回歸的代價(jià)函數(shù)在
時(shí)不可導(dǎo),但是如果我們?cè)? 時(shí)使用次梯度向量 代替的話,梯度下降仍然可以正常工作。公式4-11給出了一個(gè)次梯度的計(jì)算:from sklearn.linear_model import Lasso lasso_reg = Lasso(alpha=0.1) lasso_reg.fit(X, y) lasso_reg.predict([[1.5]]) # array([1.53788174])彈性網(wǎng)絡(luò)
彈性網(wǎng)絡(luò)是介于嶺回歸和拉索回歸之間,正則化項(xiàng)是它們正則化項(xiàng)的簡(jiǎn)單混合,并通過(guò)混合比
進(jìn)行控制,當(dāng) 時(shí),彈性網(wǎng)絡(luò)相當(dāng)于嶺回歸,當(dāng) 時(shí),相當(dāng)于拉索回歸(見(jiàn)公式4-12)。那么,什么時(shí)候應(yīng)該使用普通的線性回歸(即不進(jìn)行任何正則化)、Ridge、Lasso和Elastic Net?事實(shí)上最好還是要有一點(diǎn)正則化,即盡量避免使用純線性回歸。Ridge是一個(gè)很好的初始模型,但如果你懷疑只有幾個(gè)特征是有用的,你應(yīng)該更偏向于Lasso或Elastic Net,因?yàn)樗鼈儍A向于將無(wú)用特征的權(quán)重降到零。一般來(lái)說(shuō),Elastic Net比Lasso更適用,因?yàn)楫?dāng)特征的數(shù)量大于訓(xùn)練實(shí)例的數(shù)量,或者有幾個(gè)特征具有很強(qiáng)的相關(guān)性時(shí),Lasso可能會(huì)表現(xiàn)得很不穩(wěn)定。
from sklearn.linear_model import ElasticNet elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5, random_state=42) elastic_net.fit(X, y) elastic_net.predict([[1.5]]) # array([1.54333232])早停
對(duì)迭代學(xué)習(xí)算法(如梯度下降)進(jìn)行正則化的另一個(gè)方法是:當(dāng)驗(yàn)證誤差達(dá)到最小值時(shí),立即停止訓(xùn)練,這就是所謂的早停。圖4-20展示了一個(gè)復(fù)雜的模型(在本例中,是一個(gè)高階多項(xiàng)式回歸模型)使用批量梯度下降法進(jìn)行訓(xùn)練,隨著時(shí)間的推移,模型在訓(xùn)練集和驗(yàn)證集的預(yù)測(cè)誤差(RMSE)都在下降。然而過(guò)了一段時(shí)間,驗(yàn)證誤差不再減少,開(kāi)始回升,這說(shuō)明模型已經(jīng)開(kāi)始對(duì)訓(xùn)練數(shù)據(jù)過(guò)擬合,你只要在驗(yàn)證誤差達(dá)到最小值時(shí)就停止訓(xùn)練即可。就是這樣一種簡(jiǎn)單高效的正則化技術(shù),Geoffrey Hinton稱其為 "美妙的免費(fèi)午餐"。
對(duì)于隨機(jī)和小批量的梯度下降,曲線并不是那么平滑,可能很難知道你是否已經(jīng)達(dá)到了最小值。一個(gè)解決方案是,只有在驗(yàn)證誤差超過(guò)最小值一段時(shí)間后(即當(dāng)你確信模型不會(huì)有更好的表現(xiàn)時(shí))才停止,然后返回驗(yàn)證誤差最小的模型參數(shù)。from sklearn.base import clonepoly_scaler = Pipeline([("poly_features", PolynomialFeatures(degree=90, include_bias=False)),("std_scaler", StandardScaler())])X_train_poly_scaled = poly_scaler.fit_transform(X_train) X_val_poly_scaled = poly_scaler.transform(X_val)sgd_reg = SGDRegressor(max_iter=1, tol=-np.infty, warm_start=True,penalty=None, learning_rate="constant", eta0=0.0005, random_state=42)minimum_val_error = float("inf") best_epoch = None best_model = None for epoch in range(1000):sgd_reg.fit(X_train_poly_scaled, y_train) # continues where it left offy_val_predict = sgd_reg.predict(X_val_poly_scaled)val_error = mean_squared_error(y_val, y_val_predict)if val_error < minimum_val_error:minimum_val_error = val_errorbest_epoch = epochbest_model = clone(sgd_reg)注意到熱重啟參數(shù)warm_start=True,當(dāng)調(diào)用fit() 函數(shù)時(shí),會(huì)接著上次訓(xùn)練的結(jié)果繼續(xù)訓(xùn)練,而不是重新訓(xùn)練。
邏輯回歸
正如我們?cè)诘谝徽轮兴懻摰哪菢?#xff0c;一些回歸算法可以用于分類(反之亦然)。邏輯回歸通常用于估計(jì)一個(gè)實(shí)例屬于特定類別的概率(例如,這封郵件是垃圾郵件的概率是多少?)如果估計(jì)的概率大于50%,那么該模型就預(yù)測(cè)該實(shí)例屬于該類(稱為正類,標(biāo)簽為 "1"),否則就預(yù)測(cè)它不屬于該類(即屬于負(fù)類,標(biāo)簽為 "0")。
概率估計(jì)
那么,邏輯回歸是如何工作的呢?如線性回歸模型一樣,邏輯回歸模型計(jì)算的是輸入特征的加權(quán)和(加上一個(gè)偏置項(xiàng)),但它并不像線性回歸模型那樣直接輸出結(jié)果,而是輸出這個(gè)結(jié)果的logistic(見(jiàn)公式4-13)。
是輸出在 和 之間的 函數(shù)(即S形)。 它的定義如公式4-14和圖4-21所示:只要邏輯回歸模型估計(jì)出一個(gè)實(shí)例
屬于正類的概率 ,就可以很容易地進(jìn)行預(yù)測(cè)(見(jiàn)公式4-15):代價(jià)函數(shù)及其訓(xùn)練
我們知道了邏輯回歸模型如何估計(jì)概率并進(jìn)行預(yù)測(cè)了,但是如何訓(xùn)練呢?訓(xùn)練的目的是尋找參數(shù)向量
,使得模型對(duì)正的實(shí)例( )估計(jì)出較高的概率取值,而對(duì)負(fù)的實(shí)例( )估計(jì)出較低的概率取值。公式4-16給出了單個(gè)訓(xùn)練實(shí)例 的代價(jià)函數(shù):這個(gè)代價(jià)函數(shù)是合理的,因?yàn)楫?dāng)
接近 時(shí), 會(huì)急劇增大,所以對(duì)于一個(gè)正例,如果模型估計(jì)的概率接近 ,代價(jià)會(huì)很大;類似地,對(duì)于一個(gè)負(fù)例,如果模型估計(jì)的概率接近 ,代價(jià)也會(huì)很大。另一方面,當(dāng) 接近于 時(shí), 會(huì)接近于 ,所以對(duì)于估計(jì)概率接近于 的負(fù)例或估計(jì)概率接近于 的正例,其代價(jià)將接近于 ,這正是我們想要的。整個(gè)訓(xùn)練集的代價(jià)函數(shù)是所有訓(xùn)練實(shí)例的代價(jià)的平均。它可以寫(xiě)成一個(gè)單一的表達(dá)式,即對(duì)數(shù)損失,如式4-17所示:
壞消息是,并沒(méi)有已知的閉式方程來(lái)求解最小化這個(gè)代價(jià)函數(shù)的
值。好消息是,這個(gè)代價(jià)函數(shù)是凸的,所以梯度下降法(或其他任何優(yōu)化算法)能夠保證找到全局最小值。代價(jià)函數(shù)關(guān)于模型參數(shù) 的偏導(dǎo)數(shù)由式4-18給出:這個(gè)式子看起來(lái)很像式4-5:對(duì)于每個(gè)實(shí)例,計(jì)算其預(yù)測(cè)誤差,并將其乘以
個(gè)特征的取值,最后計(jì)算所有訓(xùn)練實(shí)例的平均值。只要有了包含所有偏導(dǎo)數(shù)的梯度向量,就可以在批量梯度下降算法中使用它。決策邊界
我們用鳶尾花數(shù)據(jù)集來(lái)了解Logistic回歸,該數(shù)據(jù)集包含了150朵三種不同品種(Iris setosa, Iris versicolor, Iris virginica)的鳶尾花的萼片和花瓣的長(zhǎng)度與寬度(見(jiàn)圖4-22)。
我們先嘗試建立一個(gè)僅根據(jù)花瓣寬度來(lái)檢測(cè)花朵是否為Iris virginica的二分類器,首先我們來(lái)加載數(shù)據(jù):
from sklearn import datasets iris = datasets.load_iris() list(iris.keys()) # ['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'] X = iris["data"][:, 3:] # petal width y = (iris["target"] == 2).astype(np.int) # 1 if Iris virginica, else 0然后我們訓(xùn)練一個(gè)邏輯回歸模型:
from sklearn.linear_model import LogisticRegression log_reg = LogisticRegression(solver="lbfgs", random_state=42) log_reg.fit(X, y)我們來(lái)看看模型對(duì)于花瓣寬度從0到3厘米不等的花朵的預(yù)測(cè)概率分布(圖4-23)。
X_new = np.linspace(0, 3, 1000).reshape(-1, 1) y_proba = log_reg.predict_proba(X_new) decision_boundary = X_new[y_proba[:, 1] >= 0.5][0]plt.figure(figsize=(8, 3)) plt.plot(X[y==0], y[y==0], "bs") plt.plot(X[y==1], y[y==1], "g^") plt.plot([decision_boundary, decision_boundary], [-1, 2], "k:", linewidth=2) plt.plot(X_new, y_proba[:, 1], "g-", linewidth=2, label="Iris virginica") plt.plot(X_new, y_proba[:, 0], "b--", linewidth=2, label="Not Iris virginica") plt.text(decision_boundary+0.02, 0.15, "Decision boundary", fontsize=14, color="k", ha="center") plt.arrow(decision_boundary, 0.08, -0.3, 0, head_width=0.05, head_length=0.1, fc='b', ec='b') plt.arrow(decision_boundary, 0.92, 0.3, 0, head_width=0.05, head_length=0.1, fc='g', ec='g') plt.xlabel("Petal width (cm)", fontsize=14) plt.ylabel("Probability", fontsize=14) plt.legend(loc="center left", fontsize=14) plt.axis([0, 3, -0.02, 1.02]) plt.show()Iris virginica(三角形)的花瓣寬度從
到 厘米不等,而其他鳶尾花(正方形)的花瓣寬度一般較小,從 到 厘米不等。對(duì)于花瓣寬度,如果在 厘米以上,則分類器高度確信該花是Iris virginica,而如果在 厘米以下,則它高度確信該花不是Iris virginica。對(duì)于兩者之間的情況,分類器是不確定的,但是,如果你讓它預(yù)測(cè)類別(使用predict()方法而不是predict_proba()方法),它將返回最有可能的類。因此,在 厘米左右有一個(gè)決策邊界,該處兩個(gè)概率都等于50%:如果花瓣寬度高于 厘米,分類器就會(huì)預(yù)測(cè)這朵花是Iris virginica,否則就會(huì)預(yù)測(cè)它不是。log_reg.predict([[1.7], [1.5]]) # array([1, 0])圖4-24展示了相同的數(shù)據(jù)集,但這次展示的是兩個(gè)特征:花瓣寬度和長(zhǎng)度。訓(xùn)練完成后,邏輯回歸分類器就可以根據(jù)這兩個(gè)特征來(lái)估計(jì)新樣本是Iris virginica的概率。虛線代表模型估計(jì)概率為50%的點(diǎn):這是模型的決策邊界,并注意到,這是一個(gè)線性邊界。每條平行線代表模型輸出特定概率的點(diǎn),從15%(左下)到90%(右上),根據(jù)模型,右上角線以外的所有花都有90%以上的概率是Iris virginica。
如同其他線性模型一樣,邏輯回歸模型可以使用
或 懲罰來(lái)進(jìn)行正則化,事實(shí)上,Scikit-Learn默認(rèn)會(huì)增加一個(gè) 的懲罰項(xiàng)。控制Scikit-Learn中LogisticRegression模型正則化強(qiáng)度的超參數(shù)不是 ,而是其倒數(shù): , 的值越大,模型的正則化強(qiáng)度越低。Softmax
邏輯回歸模型可以推廣為支持多分類的情形,這就是所謂的Softmax回歸。
其思想很簡(jiǎn)單:當(dāng)給定一個(gè)實(shí)例
時(shí),Softmax回歸模型首先計(jì)算出每個(gè)類 的分?jǐn)?shù) ,然后通過(guò)對(duì)分?jǐn)?shù)應(yīng)用softmax函數(shù)來(lái)得到每個(gè)類的概率。計(jì)算 的方程應(yīng)該很熟悉,因?yàn)樗途€性回歸的方程一樣(見(jiàn)方程4-19):注意到,每個(gè)類都有自己的專用參數(shù)向量
,所有這些向量通常以行的形式存儲(chǔ)在一個(gè)參數(shù)矩陣 中。只要計(jì)算出實(shí)例
的每一類對(duì)應(yīng)的分?jǐn)?shù),就可以通過(guò)softmax函數(shù)來(lái)計(jì)算實(shí)例屬于類 的概率(公式4-20)。該函數(shù)計(jì)算每個(gè)分?jǐn)?shù)的指數(shù),然后將其標(biāo)準(zhǔn)化(除以所有指數(shù)的總和)。其中:
- 為類別數(shù)
- 為實(shí)例 的所有類別的得分向量
- 為實(shí)例 屬于類別 的概率
與邏輯回歸一樣,Softmax回歸也是預(yù)測(cè)估計(jì)概率最高的類(簡(jiǎn)單來(lái)說(shuō)就是得分最高的類),如公式4-21所示:
我們的目標(biāo)是訓(xùn)練一個(gè)對(duì)目標(biāo)類具有高概率取值的模型。最小化式4-22所示的代價(jià)函數(shù),即交叉熵,是可以達(dá)到目標(biāo)的,因?yàn)楫?dāng)模型對(duì)目標(biāo)類的估計(jì)概率較低時(shí),它會(huì)對(duì)模型進(jìn)行懲罰。交叉熵經(jīng)常用來(lái)衡量預(yù)測(cè)類概率與目標(biāo)類的匹配程度。
其中:- 表示第 個(gè)實(shí)例是否屬于類別 ,其取值為 或
該代價(jià)函數(shù)關(guān)于
的梯度向量由式4-23給出:現(xiàn)在,你可以計(jì)算每個(gè)類的梯度向量,然后使用梯度下降(或任何其他優(yōu)化算法)找到最小化代價(jià)函數(shù)的參數(shù)矩陣
。X = iris["data"][:, (2, 3)] # petal length, petal width y = iris["target"]softmax_reg = LogisticRegression(multi_class="multinomial",solver="lbfgs", C=10, random_state=42) softmax_reg.fit(X, y)圖4-25展示了由此產(chǎn)生的決策邊界,用背景顏色表示。注意,任何兩個(gè)類之間的決策邊界都是線性的。圖中還顯示了Iris versicolor的概率,用曲線表示(例如,標(biāo)有0.450的線代表45%的概率邊界)。
與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的训练softmax分类器实例_第四章.模型训练的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python数据分析_上海交大学姐带你1
- 下一篇: bgl 词典_深大版成语词典发布!不学不