系列文章目錄
機器學習掃盲系列(1)- 序
機器學習掃盲系列(2)- 深入淺出“反向傳播”-1
文章目錄
- 前言
- 一、神經網絡的本質
- 二、線性問題
- 解析解的不可行性
- 梯度下降與隨機梯度下降
- 鏈式法則
- 三、非線性問題
- 激活函數
前言
反向傳播(Backpropagation) 是神經網絡中重要且難以理解的概念之一,甚至可以說如果理解了反向傳播的工作機制,你就基本理解了神經網絡的工作原理。所以我們從“反向傳播”切入,由此揭開神經網絡的神秘面紗。學習完之后你會發現,反向傳播只是一個非常簡單的過程,它告訴我們在神經網絡中需要怎么改變參數。
一、神經網絡的本質
神經網絡的本質其實就是根據數據集(點)擬合預測/推理函數(曲線),所以簡單來說神經網絡其實是一個“極為復雜的曲線擬合機器”。 如下圖所示,左圖的點作為訓練數據,神經網絡經過訓練之后會擬合處右圖的曲線,這樣對新數據x,可以預測/推理出y的值。
二、線性問題
為了簡單起見,我們使用一個線性回歸模型作為示例來演示。顯然,我們在對訓練數據擬合成函數(曲線)之前,需要先假設一個預測的函數,如 y = weight * x + bias。有了預測函數之后,我們就可以對每個數據計算損失(實際值和預測值的偏差)。這里我們使用 MSE(mean squared error loss 均方誤差) 作為損失函數, 針對預測函數中參數的不同值,我們都可以計算出這批訓練數據的總的損失。
如下圖,直線是我們假設的預測函數,圖上的點是訓練數據。我們試著調整weight 和 bias 的值,看看損失如何變化。
上面提到,我們要讓損失函數的值最小才能得到最完美的預測函數, 那我們先看看損失函數的圖形,如下圖。x、y軸分別表示 weight 和 bias, z 軸的值就是對應的損失值。大家想想,怎樣才能找到損失值最小的位置(weight 和 bias)?
由此引出梯度(導數,在某個位置的瞬時變化率)的定義。下面的公式給的是只有一個變量x 的情況。因此我們還是先從簡單的圖形入手。
假設損失函數 loss = x^2 - 1, 我們得到下面的圖形:
雖然肉眼很容易能看出來最小值在哪個位置,但是對于計算機來說卻很難,尤其是函數非常復雜的時候。那怎么才能找到讓 loss 最(極)小的位置呢? 首先,我們觀察這個圖形,在什么情況下 loss 值最小?是不是當梯度為0或者梯度接近于0的時候 loss 最(極)小。這個時候,有人可能會說,那直接令 梯度=0,解析出這個函數的變量x值就行了吧(求解析解)?
其實不然,為什么?
解析解的不可行性
1. 解析解的不可行性,數學復雜度:
對于絕大多數模型(如神經網絡、支持向量機等),損失函數是高維非線性的,其梯度方程(?L(θ)=0)常無法分解為閉式解(closed-form solution)。例如:
- 線性回歸可以求得解析解(θ=(X?X)?1X?y),但僅因模型是凸且線性。
- 對復雜模型(如深度學習),損失函數的高度非線性導致方程求解需要多項式時間之外的計算量。
2. 計算資源限制, 維數災難,高維參數空間的矩陣運算代價極高。例如:
- 當參數維度為n時,求解線性方程組的計算復雜度為O(n3),而n=1e?時需1e1?次運算。
- 實際深度學習模型的參數規模可達1e?量級(如GPT-3),直接求解完全不現實。
3. 非凸優化問題,局部極小值與鞍點:
- 非凸損失函數(如神經網絡的損失函數)的梯度為零點可能是局部極小值或鞍點,而全局極小值難以定位。
- 鞍點尤其在高維空間中普遍存在(概率隨維度指數級增長),直接求解梯度為零可能落入低質量解。
4. 數據驅動動態優化,在線學習與大數據場景:
- 當數據集過大時,直接求解需一次性加載全體數據(內存不足問題)。
梯度下降與隨機梯度下降
ok,那我們想想如果不用解析解,你會怎么找到最小值?顯然,聰明的你肯定會想到這樣做:
Prepare階段:使用訓練數據求出損失函數(正向傳播)
- 隨機初始化一個位置值 x1
- 計算x1處的梯度d1
- 計算 步長=d1 * 學習率(通過調參設置)(這里你會發現一個很巧妙的地方,離最優點越遠,步長越長)
- 更新位置 x2 = x1 - 步長 = x1 - d1 * 學習率
- 循環執行,直到梯度接近0 或者 步數達到最大值
恭喜,你發明了梯度下降算法。
在繼續之前,大家想想這個算法有沒有什么問題?如果訓練數據量非常大,我們的損失函數就會異常復雜,因為計算損失函數時需要將參數加載到內存/顯存中,過大的訓練數據顯然無法運行。怎么辦?
把全量數據(epoch)按固定大小隨機分組,每次只拿這一組的數據(batch)計算損失函數。
恭喜,你發明了隨機梯度下降算法。
以上只是一個參數的情況,如果涉及兩個參數比如 weight 和 bias,該怎么處理?
還是讓我們先回到一開始的預測函數 y = weight * x + bias。 這里的兩個參數weight 和 bias 都會影響 loss值 ,那我們需要計算每個參數對loss的影響程度,即偏導數(梯度),然后根據偏導數不斷迭代更新相應參數的值,從而找到最優解(loss 最小)。我們看看有兩個參數時,loss的變化情況,為簡單起見,我們用二維等高線來畫。
用loss的顏色深淺表示loss值。從圖上能很明顯看出當 weight = -1, bias = 5時loss為0,也就是我們的目標優化位置。
舉個例子,順便復習一下剛剛梯度下降的步驟,讓我們試著從圖上隨機取點來優化我們的參數(初始化)。
第二步 需要分別計算兩個參數在這個位置的偏導數(梯度)
第三步:分別計算兩個參數的步長,第四步: 更新w 和 b
回顧以上步驟,大家再想想哪一步是比較難的?
對,第3步,怎么計算損失函數的梯度值?
鏈式法則
先看下這張圖:
如果你想知道藍色值(loss)如何被粉色值(參數)影響,你會怎么觀察?
先從藍色值開始:
- 觀察藍色值被橘色值影響的程度
- 觀察橘色值被綠色值影響的程度
- 觀察綠色值被粉色值影響的程度
恭喜,你發明了鏈式法則! 看公式:
注意,這里的neuron就是預測函數y。當你想知道loss被w的影響程度(loss 關于 w的梯度), 你可以先計算loss被neuron(預測值)的影響程度,再計算neuron(預測值)被w的影響程度,兩個相乘,你就得到了loss 關于 w的梯度。 再觀察下,我們是從后往前計算梯度(loss -> 預測值 -> 參數),這也是反向傳播這一名詞的由來,這樣做的好處是可以利用前向傳播過程中的計算結果,而不需要重復計算,節約資源和時間。
ok,來看一個具體的示例。
對于 y=wx + b, 我們假設有一條訓練數據(x=2.1, y=4),w=1,b=0
正向傳播:
反向傳播:
分別更新參數,這里我們設置學習率為 0.1 (lr = 0.1),學習率的更新也是人工/自動調參的一部分:
看看更新參數后loss值:
3.61 -> 2.87, loss 下降了!
三、非線性問題
還是回到一開始的圖,如果是這些點,你會怎么選擇函數來擬合呢?
聰明的你可能會想到用一個相對復雜的嵌套函數來擬合這個曲線:
y= log(1 + e^(w11 * x + b11)) * w21 + log(1 + e^(w12 * x + b12)) * w22 + b2
恭喜,你發明了神經網絡!
也就是說,上面的公式其實可以用一個簡單的神經網絡結構來表示:
那么它的正向傳播過程就可以表示為:
而反向傳播計算梯度的過程就可以這樣表示,這里就以w21和w11為例:
注意: 如果在計算某個參數w11的梯度時用到了另一個參數w21的值,w21的值應該取當前值,而不是優化后的值。等計算完梯度,再統一對所有參數進行迭代更新。
到這里,我們應該能發現,為了擬合更加復雜的曲線,我們可以在每層添加更多神經元、更多層以及在輸出中添加非線性(激活函數)來實現。如果我們把整個神經網絡視為一個函數,那么通過添加更多神經元和更多層,我們就可以創建一個嵌套更多的函數。這樣做有幾大好處:
- 創建了更多可以調整的參數來擬合輸出結果
- 保證可微: 可以計算梯度,也就是沒有尖銳拐角或斷層
- 通過添加具有失活點的非線性激活函數,某些神經元可能對輸出沒有影響,而其他神經元可能變得更加活躍,從而導致輸出不必遵循線性約束。
激活函數
我們這里使用的是softplus作為激活函數:
還有比較常見的激活函數:
常見激活函數:
- Relu:
- sigmoid:
未完待續。。。