續上
緊接著上面一篇文章 ML01 - Regression 案例學習 (上) 講到的 Gradient Descent
,我們現在有了 Model
、Training Data
、Loss Function
,我們的 Model
:
$$ y = b + w \cdot x_{cp} $$
經過訓練呢,我們得出以下結果:
$$ b=-188.4 \\\ w=2.7 $$
將 $w$ 和 $b$ 代入到原 Model
中,我們就能得到一個一次方程,我們將其畫在座標軸上就是這樣(橫軸代表進化前的 CP 值,縱軸代表進化後的 CP 值):
計算下來的 $L(w,b)=31.9$。
當然,以上資料僅僅是我們用已知的 10 只寶可夢訓練出來的 Model
,如果現在新拿給我們一隻寶可夢,代入這個 Model
進行計算,得到的預測資料與實際資料會相差多少呢?
所以我們又捉了 10 只與之前完全不同的寶可夢,代入計算了一下,如下:
可以看到,我們 Model
計算出來的資料與新的 10 只寶可夢實際的資料還是挺契合的。實際計算下來,這 10 只寶可夢的 $L_{w,b}=35.0$。在座標軸的左下方和右上方,誤差會更大一些。
那我們如何才能將左下方和右上方的那些資料也都包含到我們的 Model
中呢?當前我們的 Model
是 Linear Model
也就是線性的,在圖中我們能夠很明顯的看出,用一條紅色的直線,再怎麼都不可能將所有藍色點都包含進去。所以,我們現在需要一個更強的 Model
。
第五步:Selecting Another Model
我們更進一步,由於圖中的藍色點並不可能在一條直線上,我們就嘗試一下,選用二次方程的曲線來擬合它們:
$$ y = b+w_1\cdot x_{cp}+w_2\cdot x_{cp}^2 $$
然後我們通過之前的辦法訓練這個 Model
,找出來最好的結果對應的是:
$$ b=-10.3 \\\ w_1=1.0 \\\ w_2=2.7*10^{-3} \\\ L(w_1,w_2,b)=15.4 $$
對應的圖形是這樣的:
如果我們將其用在 Testing Set
上呢,對應的 $L(w_1,w_2,b)=18.4$,對應的圖形是:
如果我們現在將剛才的二次 Model
改成三次方程呢:
$$ y = b+w_1\cdot x_{cp}+w_2\cdot x_{cp}^2+w_3\cdot x_{cp}^3 $$
同樣訓練過後,得出:
$$ b=6.4 \\\ w\_1=0.66 \\\ w_2=4.3\*10^{-3} \\\ w_3=-1.8\*10^{-6} \\\ L(w_1,w_2,w_3,b)=15.3 $$
圖形長這樣,看上去和二次的 Model
沒有太大的區別:
在 Testing Set
上得到的 $L(w_1,w_2,w_3,b)=18.1$,有好一點點:
那如果我們換用四次方程的 Model
的話,訓練結果會不會更好一些呢:
$$ y = b+w_1\cdot x_{cp}+w_2\cdot x_{cp}^2+w_3\cdot x_{cp}^3+w_4\cdot x_{cp}^4 $$
在 Training Data
下,擬合曲線如下圖,很明顯的擬合更準確了一些,$L=14.9$:
我們再看看它在 Testing Set
上的表現如何呢:
實際結果竟然是 $L=28.8$,反而比三次方程更糟糕了!!如果我們換做 5 次、6 次或者更高次方程的 Model
情況會不會變好呢?
下面我們再用五次方程的 Model
來訓練一下,看看效果如何:
$$ y = b+w_1\cdot x_{cp}+w_2\cdot x_{cp}^2+w_3\cdot x_{cp}^3+w_4\cdot x_{cp}^4+w_5\cdot x_{cp}^5 $$
在五次方程的 Model
下,Training Data
的 $L=12.8$,確實變好了,而 Testing Set
的 $L=232.1$,糟糕透頂。
現在,我們將上面五個 Model
(分別為一次方程、二次方程、三次方程、四次方程、五次方程),以及他們的 Loss Funciton
$L$ 的值都畫在一張圖中,我們可以發現,隨著引數的增多、方程次數的增大,我們擬合的效果是越來越好,誤差是越來越小的:
這很好解釋,因為,二次方程中其實就已經包含了一次方程的情況(使二次方程中$w_2=0$,它就變為了一次方程),所以二次方程除了擬合一次方程已經擬合到的點,還能夠擬合更多一次方程沒有擬合到的點。所以,它的誤差就會比一次方程更小。同理三次方程會比二次方程擬合更好、誤差更小...五次方程會比四次方程擬合得更好、誤差更小。
但是,在 Testing Data
上則不相同了,我們將不同 Model
在 Training Data
和 Testing Data
上 $L$ 的變化畫在同一張圖中(藍色線代表 Training Data
的結果,橙色線代表 Testing Data
的結果):
我們發現,越複雜的 Model
在 Training Data
下表現會越來越好,而在 Testing Data
下則不一定。
這種現象我們就把它叫做 Overfitting(過度擬合)
。舉個例子來說,如果我們想訓練機器人識別人類,我們就把小明拿給它學習。在只讓機器人記住一項
特徵的時候,他就記住:有兩隻眼睛的是人類;只讓它記住兩項
特徵的時候,他會發現:噢,有兩隻眼睛,一個嘴巴的是人類;當我們讓它能記住三項
特徵的時候,他就可能會記作:有兩隻眼睛,一個嘴巴,戴著帽子的是人類,這種情況下,機器人對小明
這個人類的個體
描述得就很明確了,但是對於人類
這個整體來說,就過度擬合
了(並不是所有人都戴帽子,就會導致這個機器人識別不出來很多人類)。
所以我們應當合理地選取 Model
,在減少擬合不夠
情況的同時避免過度擬合
。
前面我們的訓練都是在 10 只寶可夢的資料上做的,那如果我們選取更多的寶可夢,情況會是怎麼樣的呢?下面我們就選取了 60 只寶可夢,繪製在圖上:
能看出來,這個分佈並不是簡單的屬於一次、二次、三次...式,它其中,應該還有另一個因素在很大程度上影響進化後的結果,很明顯,應該就是不同寶可夢對應的物種:
下圖中,我們將這些寶可夢,按照不同的物種,將其用不同顏色繪製:
嗯,大概是這麼一個畫風:
那看來我們可能犯了一個嚴重的錯誤,忽略了物種的影響。
重回第一步:Redesign the Model
根據不同的物種,我們需要有不同的 Model
,物種這個屬性,就對應的是每個 $x$ 的 $x_s$:
$$ \mbox{輸入 }x \\\ \downarrow \\\ y = \begin{cases} b_1+w_1\cdot x_{cp}, & \mbox{if }x_s=\mbox{ Pidgey} \\\ b_2+w_2\cdot x_{cp}, & \mbox{if }x_s=\mbox{ Weedle} \\\ b_3+w_3\cdot x_{cp}, & \mbox{if }x_s=\mbox{ Caterpie} \\\ b_4+w_4\cdot x_{cp}, & \mbox{if }x_s=\mbox{ Eevee} \end{cases} \\\ \downarrow \\\ \mbox{輸出 }y $$
那難道我們需要為每個不同的物種設定單獨的 Linear Model(線性模型)
嗎?這似乎太麻煩了,寶可夢的物種至少有十多類並且還在持續增加。我們能不能用某個特殊的函式將不同的物種都包含進一個 Linear Model
呢?答案是:有的!
我們需要引進一個函式 $\delta()$,它的作用就是,給一個輸入,他要麼輸出 1 要麼輸出 0 (訊號與系統的知識)
$$ \delta(x_s=\mbox{ Pidgey}) \\\ \downarrow \\\ \begin{cases} =1 & \mbox{if }x_s=\mbox{ Pidgey} \\ =0 & \mbox{ 其他情況} \end{cases} $$
那我們的 Model
就可以改寫為:
$$ \begin{align} y = & \ b_1\cdot \delta(x_s=\mbox{ Pidgey}) \\\ & +w_1\cdot \delta(x_s=Pidgey)x_{cp} \\\ & +b_2\cdot \delta(x_s=\mbox{ Weedle}) \\\ & +w_2\cdot \delta(x_s=Weedle)x_{cp} \\\ & +b_3\cdot \delta(x_s=\mbox{ Caterpie}) \\\ & +w_3\cdot \delta(x_s=Caterpie)x_{cp} \\\ & +b_4\cdot \delta(x_s=\mbox{ Eevee}) \\\ & +w_4\cdot \delta(x_s=Eevee)x_{cp} \\\ \end{align} $$
比如,我們現在輸入一個 Pidgey
,那 $x_s=\mbox{ Pidgey}$,上面的式子就會變成:
$$ \begin{align} y = & \ b_1\cdot 1 \\\ & +w_1\cdot 1 \cdot x_{cp}\\\ & +b_2\cdot 0 \\\ & +w_2\cdot 0 \cdot x_{cp} \\\ & +b_3\cdot 0 \\\ & +w_3\cdot 0 \cdot x_{cp} \\\ & +b_4\cdot 0 \\\ & +w_4\cdot 0 \cdot x_{cp} \\\ \end{align} \\\ \downarrow \\\ y = b_1 +w\_1 \cdot x\_{cp} \\\ $$
所以,現在我們這個 Model
依然是一個 Linear Model
!
做出來的效果怎麼樣呢?
$L=3.8$,效果和圖中看到的一樣,非常好的擬合了 Training Data
。但我們真正在意的是它在 Testing Data
上的表現,這幾乎決定了這個 Model
的好壞。
結果是 $L=14.3$,比我們以往的所有結果都要好,說明這個思考方式我們是做對了的!
但是仔細看,我們發現,還是有一些點擬合得不夠。回想一下,我們剛才只代入了寶可夢的種類 $x_s$ 進行運算,並沒有考慮它的其他屬性對進化後 CP 值的影響,比如:進化前的體重、高度、生命值等等,這些因素都有可能會影響到一隻寶可夢進化後 CP 值的變化情況:
我們該如何將這些因素都考慮進去呢?最簡單也是最直接的一個方式就是:把所有屬性都傳進 Model
中進行運算,那我們就需要設計一個略微複雜的 Model
:
$$ \mbox{輸入 }x \\\ \downarrow \\\ y' = \begin{cases} b\_1+w_1\cdot x_{cp}+w_5\cdot(x_{cp})^2, & \mbox{if }x_s=\mbox{ Pidgey} \\\ b\_2+w_2\cdot x_{cp}+w_6\cdot(x_{cp})^2, & \mbox{if }x_s=\mbox{ Weedle} \\\ b\_3+w_3\cdot x_{cp}+w_7\cdot(x_{cp})^2, & \mbox{if }x_s=\mbox{ Caterpie} \\\ b\_4+w_4\cdot x_{cp}+w_8\cdot(x_{cp})^2, & \mbox{if }x_s=\mbox{ Eevee} \end{cases} \\\ \downarrow \\\ y = y'+w_9\cdot x_{hp}+w_{10}\cdot(x_{hp})^2+w_{11}\cdot x_{h}+w_{12}\cdot(x_{h})^2+w_{13}\cdot x_{w}+w_{14}\cdot(x_{w})^2 \\\ \downarrow \\\ \mbox{輸出 }y $$
這樣,我們既顧及了每隻寶可夢物種的特殊性,又增加了 HP 、height 和 weight 三個額外的屬性進行分析,總共 18 個引數。
果然,我們得到了一個非常低的 Loss
$L=1.9$,但是,根據以往的經驗,這麼多引數,我們很有可能會造成 Overfitting
的結果。經過 Testing Data
的運算,$L=102.3$,算是比較糟糕的一個結果了。接下來又怎麼處理呢?
重回第二步:Regularization
之前我們的輸出 $y$ 定義為:
$$ y=b+ \sum w_i x_i $$
我們需要在 Loss Function
$L$ 的基礎上,增加另一個因子,也就是下面公式中,$\color{Red}+$ 號後面的部分:
$$ L= {\sum_n (\widehat{y}^n - (b+\sum w_i x_i))^2} {\color{Red}+\lambda\sum(w_i)^2} $$
這裡的 $\lambda$ 是一個引數,需要我們事先給出並手動調節的(它的值越大
,我們的 Loss Function
就越平滑
)。加入 $w_i$ 的意思就是說,在滿足 $L$ 儘可能小的前提下,讓 $w_i$ 也儘可能地小。因為如果 $w_i$ 越小,輸入中 $x$ 值的變化,所帶來的 $w_i\cdot x$ 的變化就越小,也就是 $\Delta y$ 越小。這樣的話,不同的輸入之間,微小的差異就可以控制在一定的範圍內,不會對系統產生過大的影響,也就在最大可能上避免了 Overfitting
的發生。當然,它並不需要包含 $b$,因為 $b$ 只是一個常數,並不會隨著 $x$ 的變化而變化,所以加上與否,對系統幾乎沒有影響。
那最終結果怎麼樣呢?
上圖中,我們將 $\lambda$ 的值從 0
調整到 100000
,可以明顯看出,其在值為 100 左右的時候,效果是最好的(我們希望 Loss Function
適當地平滑,這可以去除一些噪聲對結果的干擾,但過於平滑的話,訓練資料對結果的影響又會變得過小,從而減弱了有益特徵值對系統的影響)。
最終,我們得到了一個基本可用的寶可夢進化 CP 值預測系統
。當然,由於我們所用的訓練資料種類還是偏少,可能在實際的使用中會出現很多系統從來沒遇到過的物種,這個時候基本上系統會給出錯誤率很高的預測值。
本文總結
- 我們最開始通過確定一個
Linear Model
來訓練寶可夢的資料,結果發現,有很多的資料都是沒辦法擬合的(線性模型在圖上看來就是一條直線); - 然後我們就想到了用
二次方程
來擬合,結果是:在Training Data
上,Loss Function
的輸出的卻變小了,並且在Testing Data
上,也得到了同樣的結果; - 我們就開始思考,是否通過增加模型的複雜度,就能訓練出更好的模型?然後我們就嘗試了
三次方程
、四次方程
、五次方程
,結果發現,雖然隨著方程複雜度的增大,在Training Data
上的 $L$ 輸出越來越小,但是在Testing Data
上,$L$ 變得非常不穩定,並且有快速增大的趨勢。我們就意識到,現在的模型Overfitting
了; - 然後我們發現,選取的寶可夢可能有點少了,才導致了個別的特性在訓練中變得比較突出加重了
Overfitting
發生的可能性。所以我們又選取了 50 只,一共 60 只寶可夢來進行分析; - 在將 60 只寶可夢繪製在座標軸上時,我們又發現了一個新的問題,這些點在某些範圍內,分佈是比較有規律的。所以我們將各個寶可夢根據它們所屬的物種進行了分類,然後重新設計了
Model
,用到了 $\delta()$ 函式,這個函式針對不同的輸入,只會返回 0 或者 1; - 我們將重新設計的模型通過訓練後發現,效果顯著,但是還有提升空間,因為有的點並沒有被擬合到,所以我們猜想,會不會 CP 的變化不僅和物種 $x_s$ 有關,還和它的生命值 $x_{hp}$、高度$x_h$、重量$x_w$有關呢?所以我們將這些因素都代入了
Model
進行計算,總共用到了 18 個引數。 - 由於之前我們有過經驗,
Model
過於複雜就有很大可能發生Overfitting
的現象。果不其然,這次又過度擬合了,為了解決這個問題,我們在Loss Function
中,加入了一個額外的式子 $\lambda\sum(w_i)^2$,由於我們訓練的依據就是儘量的讓Loss Function
變小,所以我們就需要讓剛才這個式子也儘量的小,也就是讓 $w_i$ 儘量小,這樣的話整個Loss Function
就會變得比較平滑,減少噪聲的影響,這也就Regularization(正則化)
的作用; - 最終,我們通過調節 $\lambda$ 的值,得到了比較滿意的一個訓練結果,在
Training Data
和Testing Data
上的Loss
$L$ 都比較小,不過考慮到我們所使用的寶可夢種類還是太少,如果要將這個系統做到上線實用的話,還需要更豐富的訓練資料來訓練。
今天更新到這裡,期待下一課...