【Python機器學習】108:資料標準化與進階梯度遞減的實用技巧

Data Standardization and Advanced Gradient Descent

--

Photo by Cindy Chan on Unsplash

在先前的文章中已經教了比正規方程更好用的梯度遞減。但是,在什麼樣的情況下,原本的梯度遞減公式還是會不適用呢?

給定Kaggle資料集艾姆斯房價資料為例,若以其中的 GrLivArea 作為特徵矩陣來預測目標向量 Saleprice。

使用 Scikit-Learn 的 Linear Regression 預測器找出 𝑤:

使用 Gradient Descent 找出 𝑤:

我們發現透過梯度遞減演算法找的w,w0的值(194)與正確解答(30774)還差了十萬八千里。我們試著作圖了解一下原因:

由於在一開始迭代時,MSE就已經是最小了,所以w0才會每次只動一點點,造成w0無法抵達最佳解的值。

究竟發生什麼事情,為什麼離最佳解這麼遠?

這是因為最佳解 𝑤0 與 𝑤1 的係數量級(scale)差距太大的緣故

藍色的加號是用梯度遞減在找的w組合,從上圖中可以發現w1在不斷的更新,但是w1卻沒什麼移動。由於我們每次移動都是學習速率乘上斜率,說明w0每一點的謝率都太小了,再乘上一個很小的學習速率,那就等於幾乎沒在動。

該如何解決這樣的問題?

標準化(Standardization):

把特徵矩陣(X)標準化後,每個w係數之間的級距差距會比較接近

使用進階的梯度遞減演算法:

  • 動量梯度遞減
  • 調適梯度遞減
  • RMSprop 梯度遞減
  • Adam 梯度遞減

常見的標準化方法有兩個:

  1. MinMax scaler :

2. Standard scaler :

自己手寫Standard scaler:

原本的特徵矩陣 X 的值
經過手動標準化後的特徵矩陣 X 的值

有標準化的 X 與沒有標準化的 X 的直方圖經比較後發現:X 的分佈並沒有改變,但是整個圖形卻向左平移,使整個圖形的平均值為0,標準差為1。

直接使用 Scikit-Learn 中的套件,以sklearn.preprocessing.StandardScalar( )函數做標準化:

和手動的標準化 X 值一樣

把最後得到的w印出來後,回去跟標準答案比(30774, 98)似乎還是不太對。為什麼?

那是因為我們是拿標準化後的資料去訓練模型,所以訓練完後的係數要再逆標準化得到最後的答案。

w0和w1在有標準化的情況下,兩者在迭代的過程中都有在往最佳解移動

逆「標準化」

經過逆標準化後得到的 w0 和 w1 係數離標準答案就很近了。

除了將特徵矩陣 𝑋 標準化,亦可以採用進階梯度遞減演算法,常見的包含:

動量梯度遞減(Gradient Descent with Momentum):

具有動量的梯度下降在每次迭代更新係數時會將前一次更新的動量(Momentum, 𝑉 )以 𝛾 與當下的梯度加權;這會使得如果當下梯度的正負號與之前相同,更新的幅度會增強(說明方向是對的,就會加快速度抵達最佳解);若當下梯度的正負號與之前不一致,更新的幅度則會衰退。

每次迭代更新係數時會將前一次更新的動量(Momentum, 𝑉 )以 𝛾 與當下的梯度加權:

直接看公式可能會很抽象,但如果直接寫成程式碼就會清楚許多。在原本梯度遞減的程式碼中加入初始化𝑉(Intiate velocities),範例中由於w有w0和w1兩個值,因此初始值給(0,0)。每次更新w,除了需要知道這次的梯度值,我還需要知道前一次更新的梯度值為何。

一開始當迭代次數為0時,因為沒有參考的 𝑉,所以只需寫公式後一項((1 - 𝛾)*梯度)即可。
從第0次的迭代到第200000的迭代中,w0崇德非常快,但是之後又漸漸的放慢速度,就是因為動量的關係

調適梯度遞減(AdaGrad)

在梯度遞減迭代的過程動態地調整學習速率(Learning rate)的值,在梯度高的時候增加學習速率、在梯度低的時候減緩學習速率。

在梯度遞減迭代的過程動態地調整學習速率(Learning rate)的值:

ssg = Sum of Squared Gradient, 分母放epsilon的目的是避免分母值為0

一開始迭代時,由於梯度平方值和(ssg)很小,導致分母項沒有很大,所以一開始在跑的速度就會快;但是一旦累加的值越來越大,分母項就會越來越大,跑的速度就會變慢,如此一來,學習速率就不會只是單一的值了。

在上一篇文章中有提到如果學習速率調大一點點,w的值可能一下就飄出去無法收斂;或是w0和w1的值差別很大,但是學習速率卻都是給一樣的值。但是AdaGrad是如果是大的斜率,我就給予比較大的學習速率,如果是小的梯度,我就給小的學習速率,這樣w的值就比較不會飄掉。

先前範例中所設的學習速率都是0.001或0.00001這種很小的值,但是AdaGrad的例子中,學習速率就可以調成100,迭代的次數也比較少一點。

RMSProp 梯度遞減(Gradient Descent with Root Mean Square Propagation)

和調適梯度遞減同樣是在迭代的過程動態地調整學習速率(Learning rate)的值,但 AdaGrad 所採用的梯度平方和是單調遞增的數值(monotonic increasing),有可能造成學習速率下降過快;RMSProp 利用 1−𝛾 去降低梯度平方和的影響力。

利用 1−𝛾 去降低梯度平方和的影響力:

Adam 梯度遞減(Gradient Descent with Adaptive Moment Estimation)

結合動量梯度遞減與 RMSProp 梯度遞減的特性,是目前最被廣泛使用的梯度遞減演算法。

結合動量梯度遞減與 RMSProp 梯度遞減的特性:

從上圖中發現,使用Adam這麼強的梯度遞減,迭代20000次都有點多了,大概在10000次左右就已經收斂了。

感謝你閱讀完這篇文章,如果你覺得這些文章對你有幫助請在底下幫我拍個手(長按最多可以拍50下手)。

上一章:【Python機器學習】107:機器學習模型的計算複雜性

下一章:【Python機器學習】109:當數據集含有遺漏值的處理方法與未經過訓練的分類預測器

--

--

張育晟 Eason Chang
展開數據人生

在不斷變動中努力思索自己的定位,想做的事情很多,但最希望的是不要變成無趣的人。 Linkedin: https://www.linkedin.com/in/stareason1997