系列博客,原文在筆者所維護的github上:https://aka.ms/beginnerAI,
點擊star加星不要吝嗇,星越多筆者越努力。python
這三大概念是:反向傳播,梯度降低,損失函數。git
神經網絡訓練的最基本的思想就是:先「猜」一個結果,咱們叫預測結果a,看看這個預測結果和事先標記好的訓練集中的真實結果y之間的差距,而後調整策略,再試一次,這一次就不是「猜」了,而是有依據地向正確的方向靠近。如此反覆屢次,一直到預測結果和真實結果之間相差無幾,亦即|a-y|->0,就結束訓練。github
在神經網絡訓練中,咱們把「猜」叫作初始化,能夠隨機,也能夠根據之前的經驗給定初始值。即便是「猜」,也是有技術含量的。安全
這三個概念是先後緊密相連的,講到一個,確定會牽涉到另一個。但因爲損失函數篇幅較大,咱們將在下一章中再詳細介紹。網絡
下面咱們舉幾個例子來直觀的說明下這三個概念。機器學習
甲乙兩我的玩兒猜數的遊戲,數字的範圍是[1,50]:函數
甲:我猜5post
乙:過小了學習
甲:50spa
乙:有點兒大
甲:30
乙:小了
......
在這個遊戲裏:
這裏的損失函數是什麼呢?就是「過小了」,「有點兒大」,很不精確!這個「所謂的」損失函數給出了兩個信息:
假設有一個黑盒子如圖2-1。
圖2-1 黑盒子
咱們只能看到輸入和輸出的數值,看不到裏面的樣子,當輸入1時,輸出2.334,而後黑盒子有個信息顯示:我須要輸出值是4。而後咱們試了試輸入2,結果輸出5.332,一會兒比4大了不少。那麼咱們第一次的損失值是\(2.334-4=-1.666\),而二次的損失值是\(5.332-4=1.332\)。
這裏,咱們的損失函數就是一個簡單的減法,用實際值減去目標值,可是它能夠告訴你兩個信息:1)方向,是大了仍是小了;2)差值,是0.1仍是1.1。這樣就給了咱們下一次猜的依據。
小明拿了一支步槍,射擊100米外的靶子。這支步槍沒有準星,或者是準星有問題,或者是小明眼神兒很差看不清靶子,或者是霧很大,或者風很大,或者因爲木星的影響而側向引力場異常......反正就是遇到各類干擾因素。
第一次試槍後,拉回靶子一看,彈着點偏左了,因而在第二次試槍時,小明就會有意識地向右側偏幾毫米,再看靶子上的彈着點,如此反覆幾回,小明就會掌握這支步槍的脾氣了。圖2-2顯示了小明的5次試槍過程。
圖2-2 打靶的彈着點記錄
在有監督的學習中,須要衡量神經網絡輸出和所預期的輸出之間的差別大小。這種偏差函數須要可以反映出當前網絡輸出和實際結果之間一種量化以後的不一致程度,也就是說函數值越大,反映出模型預測的結果越不許確。
這個例子中,小明預期的目標是所有命中靶子的中心,最外圈是1分,以後越向靶子中心分數是2,3,4分,正中靶心能夠得10分。
上圖是每次單發點射,因此每次訓練樣本的個數是1。在實際的神經網絡訓練中,一般須要多個樣本,作批量訓練,以免單個樣本自己採樣時帶來的偏差。在本例中,多個樣本能夠描述爲連發射擊,假設一次能夠連打3發子彈,每次的離散程度都相似,如圖2-3所示。
圖2-3 連發彈着點記錄
那小明每次射擊結果和目標之間的差距是多少呢?在這個例子裏面,用得分來衡量的話,就是說小明獲得的反饋結果從差9分,到差8分,到差2分,到差1分,到差0分,這就是用一種量化的結果來表示小明的射擊結果和目標之間差距的方式。也就是偏差函數的做用。由於是一次只有一個樣本,因此這裏採用的是偏差函數的稱呼。若是一次有多個樣本,就要叫作損失函數了。
其實射擊還不這麼簡單,若是是遠距離狙擊,還要考慮空氣阻力和風速,在神經網絡裏,空氣阻力和風速能夠對應到隱藏層的概念上。
在這個例子中:
損失函數的描述是這樣的:
這裏的損失函數也有兩個信息:
因此,梯度,是個矢量! 它應該即告訴咱們方向,又告訴咱們數值。
以上三個例子比較簡單,容易理解,咱們把黑盒子再請出來:黑盒子這件事真正的意義並非猜想當輸入是多少時輸出會是4。它的實際意義是:咱們要破解這個黑盒子!因而,咱們會有以下破解流程:
表2-1 樣本數據表
樣本ID | 輸入(特徵值) | 輸出(標籤) |
---|---|---|
1 | 1 | 2.21 |
2 | 1.1 | 2.431 |
3 | 1.2 | 2.652 |
4 | 2 | 4.42 |
從上面的過程能夠看出,若是偏差值是正數,咱們就把權重下降一些;若是偏差值爲負數,則升高權重。
簡單總結一下反向傳播與梯度降低的基本工做原理:
系列博客,原文在筆者所維護的github上:https://aka.ms/beginnerAI,
點擊star加星不要吝嗇,星越多筆者越努力。
假設咱們有一個函數:
\[z = x \cdot y \tag{1}\]
其中:
\[x = 2w + 3b \tag{2}\]
\[y = 2b + 1 \tag{3}\]
計算圖如圖2-4。
圖2-4 簡單線性計算的計算圖
注意這裏x, y, z不是變量,只是計算結果。w, b是才變量。由於在後面要學習的神經網絡中,咱們要最終求解的是w和b的值,在這裏先預熱一下。
當w = 3, b = 4時,會獲得圖2-5的結果。
圖2-5 計算結果
最終的z值,受到了前面不少因素的影響:變量w,變量b,計算式x,計算式y。常數是個定值,不考慮。
目前的z=162,若是咱們想讓z變小一些,好比目標是z=150,w應該如何變化呢?爲了簡化問題,咱們先只考慮改變w的值,而令b值固定爲4。
若是想解決這個問題,咱們能夠在輸入端一點一點的試,把w變成4試試,再變成3.5試試......直到滿意爲止。如今咱們將要學習一個更好的解決辦法:反向傳播。
咱們從z開始一層一層向回看,圖中各節點關於變量w的偏導計算結果以下:
\[由於z = x \cdot y,其中x = 2w + 3b,y = 2b + 1\]
因此:
\[\frac{\partial{z}}{\partial{w}}=\frac{\partial{z}}{\partial{x}} \cdot \frac{\partial{x}}{\partial{w}}=y \cdot 2=18 \tag{4}\]
其中:
\[\frac{\partial{z}}{\partial{x}}=\frac{\partial{}}{\partial{x}}(x \cdot y)=y=9\]
\[\frac{\partial{x}}{\partial{w}}=\frac{\partial{}}{\partial{w}}(2w+3b)=2\]
圖2-6 對w的偏導求解過程
圖2-6其實就是鏈式法則的具體表現,z的偏差經過中間的x傳遞到w。若是不是用鏈式法則,而是直接用z的表達式計算對w的偏導數,會是什麼樣呢?咱們來試驗一下。
根據公式一、二、3,咱們有:
\[z=x \cdot y=(2w+3b)(2b+1)=4wb+2w+6b^2+3b \tag{5}\]
對上式求w的偏導:
\[ {\partial z \over \partial w}=4b+2=4 \cdot 4 + 2=18 \tag{6} \]
公式4和公式6的結果徹底一致!因此,請你們相信鏈式法則的科學性。
公式4和公式6的含義是:當w變化一點點時,z會發生w的變化值的18倍的變化。記住咱們的目標是讓z=150,目前在初始狀態時是162,因此,問題轉化爲:當咱們須要z從162變到150時,w須要變化多少?
既然:
\[ \Delta z = 18 \cdot \Delta w \]
則:
\[ \Delta w = {\Delta z \over 18}={162-150 \over 18}= 0.6667 \]
因此:
\[w = w - 0.6667=2.3333\]
\[x=2w+3b=16.6667\]
\[z=x \cdot y=16.6667 \times 9=150.0003\]
咱們一會兒就成功地讓z值變成了150.0003,與150的目標很是地接近,這就是偏導數的威力所在。
此次咱們令w的值固定爲3,變化b的值,目標仍是讓z=150。同上一小節同樣,先求b的偏導數。
注意,在上一小節中,求w的導數只通過了一條路:從z到x到w。可是求b的導數時要通過兩條路,如圖2-7所示:
圖2-7 對b的偏導求解過程
從複合導數公式來看,這二者應該是相加的關係,因此有:
\[\frac{\partial{z}}{\partial{b}}=\frac{\partial{z}}{\partial{x}} \cdot \frac{\partial{x}}{\partial{b}}+\frac{\partial{z}}{\partial{y}}\cdot\frac{\partial{y}}{\partial{b}}=y \cdot 3+x \cdot 2=63 \tag{7}\]
其中:
\[\frac{\partial{z}}{\partial{x}}=\frac{\partial{}}{\partial{x}}(x \cdot y)=y=9\]
\[\frac{\partial{z}}{\partial{y}}=\frac{\partial{}}{\partial{y}}(x \cdot y)=x=18\]
\[\frac{\partial{x}}{\partial{b}}=\frac{\partial{}}{\partial{b}}(2w+3b)=3\]
\[\frac{\partial{y}}{\partial{b}}=\frac{\partial{}}{\partial{b}}(2b+1)=2\]
咱們不妨再驗證一下鏈式求導的正確性。把公式5再拿過來:
\[z=x \cdot y=(2w+3b)(2b+1)=4wb+2w+6b^2+3b \tag{5}\]
對上式求b的偏導:
\[ {\partial z \over \partial b}=4w+12b+3=12+48+3=63 \tag{8} \]
結果和公式7的鏈式法則同樣。
公式7和公式8的含義是:當b變化一點點時,z會發生b的變化值的63倍的變化。記住咱們的目標是讓z=150,目前在初始狀態時是162,因此,問題轉化爲:當咱們須要z從162變到150時,b須要變化多少?
既然:
\[\Delta z = 63 \cdot \Delta b\]
則:
\[ \Delta b = {\Delta z \over 63}={162-150 \over 63}=0.1905 \]
因此:
\[ b=b-0.1905=3.8095 \]
\[x=2w+3b=17.4285\]
\[y=2b+1=8.619\]
\[z=x \cdot y=17.4285 \times 8.619=150.2162\]
這個結果也是與150很接近了,可是精度還不夠。再迭代幾回,應該能夠近似等於150了,直到偏差不大於1e-4時,咱們就能夠結束迭代了,對於計算機來講,這些運算的執行速度很快。
這個問題用數學公式倒推求解一個二次方程,就能直接獲得準確的b值嗎?是的!可是咱們是要說明機器學習的方法,機器並不會解二次方程,並且不少時候不是用二次方程就能解決實際問題的。而上例所示,是用機器所擅長的迭代計算的方法來不斷逼近真實解,這就是機器學習的真諦!並且這種方法是廣泛適用的。
此次咱們要同時改變w和b,到達最終結果爲z=150的目的。
已知\(\Delta z=12\),咱們不妨把這個偏差的一半算在w帳上,另一半算在b的帳上:
\[\Delta b=\frac{\Delta z / 2}{63} = \frac{12/2}{63}=0.095\]
\[\Delta w=\frac{\Delta z / 2}{18} = \frac{12/2}{18}=0.333\]
容易出現的問題:
\[ \frac{\partial{z}}{\partial{b}}=\frac{\partial{z}}{\partial{x}} \cdot \frac{\partial{x}}{\partial{b}}+\frac{\partial{z}}{\partial{y}}\cdot\frac{\partial{y}}{\partial{b}}=y \cdot 3+x \cdot 2=3y+2x \]
\[ \frac{\partial{z}}{\partial{w}}=\frac{\partial{z}}{\partial{x}} \cdot \frac{\partial{x}}{\partial{w}}+\frac{\partial{z}}{\partial{y}}\cdot\frac{\partial{y}}{\partial{w}}=y \cdot 2+x \cdot 0 = 2y \]
因此,在每次迭代中,要從新計算下面兩個值:
\[ \Delta b=\frac{\Delta z}{3y+2x} \]
\[ \Delta w=\frac{\Delta z}{2y} \]
如下是程序的運行結果。
沒有在迭代中從新計算Δb的貢獻值:
single variable: b ----- w=3.000000,b=4.000000,z=162.000000,delta_z=12.000000 delta_b=0.190476 w=3.000000,b=3.809524,z=150.217687,delta_z=0.217687 delta_b=0.003455 w=3.000000,b=3.806068,z=150.007970,delta_z=0.007970 delta_b=0.000127 w=3.000000,b=3.805942,z=150.000294,delta_z=0.000294 delta_b=0.000005 w=3.000000,b=3.805937,z=150.000011,delta_z=0.000011 delta_b=0.000000 w=3.000000,b=3.805937,z=150.000000,delta_z=0.000000 done! final b=3.805937
在每次迭代中都從新計算Δb的貢獻值:
single variable new: b ----- w=3.000000,b=4.000000,z=162.000000,delta_z=12.000000 factor_b=63.000000, delta_b=0.190476 w=3.000000,b=3.809524,z=150.217687,delta_z=0.217687 factor_b=60.714286, delta_b=0.003585 w=3.000000,b=3.805938,z=150.000077,delta_z=0.000077 factor_b=60.671261, delta_b=0.000001 w=3.000000,b=3.805937,z=150.000000,delta_z=0.000000 done! final b=3.805937
從以上兩個結果對比中,能夠看到三點:
對於雙變量的迭代,有一樣的問題:
沒有在迭代中從新計算Δb,Δw的貢獻值(factor_b和factor_w每次都保持63和18):
double variable: w, b ----- w=3.000000,b=4.000000,z=162.000000,delta_z=12.000000 delta_b=0.095238, delta_w=0.333333 w=2.666667,b=3.904762,z=150.181406,delta_z=0.181406 delta_b=0.001440, delta_w=0.005039 w=2.661628,b=3.903322,z=150.005526,delta_z=0.005526 delta_b=0.000044, delta_w=0.000154 w=2.661474,b=3.903278,z=150.000170,delta_z=0.000170 delta_b=0.000001, delta_w=0.000005 w=2.661469,b=3.903277,z=150.000005,delta_z=0.000005 done! final b=3.903277 final w=2.661469
在每次迭代中都從新計算Δb,Δw的貢獻值(factor_b和factor_w每次都變化):
double variable new: w, b ----- w=3.000000,b=4.000000,z=162.000000,delta_z=12.000000 factor_b=63.000000, factor_w=18.000000, delta_b=0.095238, delta_w=0.333333 w=2.666667,b=3.904762,z=150.181406,delta_z=0.181406 factor_b=60.523810, factor_w=17.619048, delta_b=0.001499, delta_w=0.005148 w=2.661519,b=3.903263,z=150.000044,delta_z=0.000044 factor_b=60.485234, factor_w=17.613053, delta_b=0.000000, delta_w=0.000001 w=2.661517,b=3.903263,z=150.000000,delta_z=0.000000 done! final b=3.903263 final w=2.661517
這個與第一個單變量迭代不一樣的地方是:這個問題能夠有多個解,因此兩種方式均可以獲得各自的正確解,可是第二種方式效率高,並且知足梯度降低的概念。
http://colah.github.io/posts/2015-08-Backprop/
ch02, Level1
系列博客,原文在筆者所維護的github上:https://aka.ms/beginnerAI,
點擊star加星不要吝嗇,星越多筆者越努力。
在上面的線性例子中,咱們能夠發現,偏差一次性地傳遞給了初始值w和b,即,只通過一步,直接修改w和b的值,就能作到偏差校訂。由於從它的計算圖看,不管中間計算過程有多麼複雜,它都是線性的,因此能夠一次傳到底。缺點是這種線性的組合最多隻能解決線性問題,不能解決更復雜的問題。這個咱們在神經網絡基本原理中已經闡述過了,須要有激活函數鏈接兩個線性單元。
下面咱們看一個非線性的例子,如圖2-8所示。
圖2-8 非線性的反向傳播
其中\(1<x<=10,0<y<2.15\)。假設有5我的分別表明x、a、b、c、y:
提出問題:假設咱們想最後獲得c=2.13的值,x應該是多少?(偏差小於0.001便可)
\[c=\sqrt{b}=\sqrt{\ln(a)}=\sqrt{\ln(x^2)}=2.13\]
\[x = 9.6653\]
\[ \frac{da}{dx}=\frac{d(x^2)}{dx}=2x=\frac{\Delta a}{\Delta x} \tag{1} \]
\[ \frac{db}{da} =\frac{d(\ln{a})}{da} =\frac{1}{a} = \frac{\Delta b}{\Delta a} \tag{2} \]
\[ \frac{dc}{db}=\frac{d(\sqrt{b})}{db}=\frac{1}{2\sqrt{b}}=\frac{\Delta c}{\Delta b} \tag{3} \]
所以獲得以下一組公式,能夠把最後一層\(\Delta c\)的偏差一直反向傳播給最前面的\(\Delta x\),從而更新x值:
\[ \Delta c = c - y \tag{4} \]
\[ \Delta b = \Delta c \cdot 2\sqrt{b} \tag{根據式3} \]
\[ \Delta a = \Delta b \cdot a \tag{根據式2} \]
\[ \Delta x = \Delta a / 2x \tag{根據式1} \]
咱們給定初始值\(x=2,\Delta x=0\),依次計算結果如表2-2。
表2-2 正向與反向的迭代計算
方向 | 公式 | 迭代1 | 迭代2 | 迭代3 | 迭代4 | 迭代5 |
---|---|---|---|---|---|---|
正向 | \(x=x-\Delta x\) | 2 | 4.243 | 7.344 | 9.295 | 9.665 |
正向 | \(a=x^2\) | 4 | 18.005 | 53.934 | 86.404 | 93.233 |
正向 | \(b=\ln(a)\) | 1.386 | 2.891 | 3.988 | 4.459 | 4.535 |
正向 | \(c=\sqrt{b}\) | 1.177 | 1.700 | 1.997 | 2.112 | 2.129 |
標籤值y | 2.13 | 2.13 | 2.13 | 2.13 | 2.13 | |
反向 | \(\Delta c = c - y\) | -0.953 | -0.430 | -0.133 | -0.018 | |
反向 | \(\Delta b = \Delta c \cdot 2\sqrt{b}\) | -2.243 | -1.462 | -0.531 | -0.078 | |
反向 | \(\Delta a = \Delta b \cdot a\) | -8.973 | -26.317 | -28.662 | -6.698 | |
反向 | \(\Delta x = \Delta a / 2x\) | -2.243 | -3.101 | -1.951 | -0.360 |
表2-2,先看「迭代-1」列,從上到下是一個完整的正向+反向的過程,最後一行是-2.243,回到「迭代-2」列的第一行,2-(-2.243)=4.243,而後繼續向下。到第5輪時,正向計算獲得的c=2.129,很是接近2.13了,迭代結束。
運行示例代碼的話,能夠獲得以下結果:
how to play: 1) input x, 2) calculate c, 3) input target number but not faraway from c input x as initial number(1.2,10), you can try 1.3: 2 c=1.177410 input y as target number(0.5,2), you can try 1.8: 2.13 forward... x=2.000000,a=4.000000,b=1.386294,c=1.177410 backward... delta_c=-0.952590, delta_b=-2.243178, delta_a=-8.972712, delta_x=-2.243178 ...... forward... x=9.655706,a=93.232666,b=4.535098,c=2.129577 backward... done!
爲節省篇幅只列出了第一步和最後一步(第5步)的結果,第一步時c=1.177410,最後一步時c=2.129577,中止迭代。
ch02, Level2
系列博客,原文在筆者所維護的github上:https://aka.ms/beginnerAI,
點擊star加星不要吝嗇,星越多筆者越努力。
在大多數文章中,都以「一我的被困在山上,須要迅速下到谷底」來舉例,這我的會「尋找當前所處位置最陡峭的地方向下走」。這個例子中忽略了安全因素,這我的不可能沿着最陡峭的方向走,要考慮坡度。
在天然界中,梯度降低的最好例子,就是泉水下山的過程:
梯度降低的數學公式:
\[\theta_{n+1} = \theta_{n} - \eta \cdot \nabla J(\theta) \tag{1}\]
其中:
「梯度降低」包含了兩層含義:
亦即與上升相反的方向運動,就是降低。
圖2-9 梯度降低的步驟
圖2-9解釋了在函數極值點的兩側作梯度降低的計算過程,梯度降低的目的就是使得x值向極值點逼近。
假設一個單變量函數:
\[J(x) = x ^2\]
咱們的目的是找到該函數的最小值,因而計算其微分:
\[J'(x) = 2x\]
假設初始位置爲:
\[x_0=1.2\]
假設學習率:
\[\eta = 0.3\]
根據公式(1),迭代公式:
\[x_{n+1} = x_{n} - \eta \cdot \nabla J(x)= x_{n} - \eta \cdot 2x\tag{1}\]
假設終止條件爲J(x)<1e-2,迭代過程是:
x=0.480000, y=0.230400 x=0.192000, y=0.036864 x=0.076800, y=0.005898 x=0.030720, y=0.000944
上面的過程如圖2-10所示。
圖2-10 使用梯度降低法迭代的過程
假設一個雙變量函數:
\[J(x,y) = x^2 + \sin^2(y)\]
咱們的目的是找到該函數的最小值,因而計算其微分:
\[{\partial{J(x,y)} \over \partial{x}} = 2x\]
\[{\partial{J(x,y)} \over \partial{y}} = 2 \sin y \cos y\]
假設初始位置爲:
\[(x_0,y_0)=(3,1)\]
假設學習率:
\[\eta = 0.1\]
根據公式(1),迭代過程是的計算公式:
\[(x_{n+1},y_{n+1}) = (x_n,y_n) - \eta \cdot \nabla J(x,y)\]
\[ = (x_n,y_n) - \eta \cdot (2x,2 \cdot \sin y \cdot \cos y) \tag{1}\]
根據公式(1),假設終止條件爲\(J(x,y)<1e-2\),迭代過程如表2-3所示。
表2-3 雙變量梯度降低的迭代過程
迭代次數 | x | y | J(x,y) |
---|---|---|---|
1 | 3 | 1 | 9.708073 |
2 | 2.4 | 0.909070 | 6.382415 |
... | ... | ... | ... |
15 | 0.105553 | 0.063481 | 0.015166 |
16 | 0.084442 | 0.050819 | 0.009711 |
迭代16次後,J(x,y)的值爲0.009711,知足小於1e-2的條件,中止迭代。
上面的過程如表2-4所示,因爲是雙變量,因此須要用三維圖來解釋。請注意看兩張圖中間那條隱隱的黑色線,表示梯度降低的過程,從紅色的高地一直沿着坡度向下走,直到藍色的窪地。
表2-4 在三維空間內的梯度降低過程
觀察角度1 | 觀察角度2 |
---|---|
在公式表達時,學習率被表示爲\(\eta\)。在代碼裏,咱們把學習率定義爲learning_rate,或者eta。針對上面的例子,試驗不一樣的學習率對迭代狀況的影響,如表2-5所示。
表2-5 不一樣學習率對迭代狀況的影響
學習率 | 迭代路線圖 | 說明 |
---|---|---|
1.0 | 學習率太大,迭代的狀況很糟糕,在一條水平線上跳來跳去,永遠也不能降低。 | |
0.8 | 學習率大,會有這種左右跳躍的狀況發生,這不利於神經網絡的訓練。 | |
0.4 | 學習率合適,損失值會從單側降低,4步之後基本接近了理想值。 | |
0.1 | 學習率較小,損失值會從單側降低,但降低速度很是慢,10步了尚未到達理想狀態。 |
ch02, Level3, Level4, Level5