第六章 深度前饋網路 (開篇引言)
重點摘要:
深度前饋網路 (deep feedforward network),也叫作前饋神經網路 (feedforward neural network) 或者多層感知機 (multilayer perceptron, MLP),是典型的深度學習模型。前饋網路的目標是近似某個函數 f*
。例如,對於分類器,y = f*(x)
將輸入 x
映射到一個類別 y
。前饋網路定義了一個映射 y = f(x; θ)
,並且學習參數 θ
的值,使它能夠得到最佳的函數近似。
這種模型被稱為前向 (feedforward) 的,是因為信息流過 x
的函數,流經用於定義 f
的中間計算過程,最終到達輸出 y
。在模型的輸出和模型本身之間沒有反饋 (feedback) 連接。當前饋神經網路被擴展成包含反饋連接時,它們被稱為循環神經網路 (recurrent neural network),在第十章介紹。
前饋網路對於機器學習的從業者是極其重要的。它們是許多重要商業應用的基礎。例如,用於對照片中的對象進行識別的卷積神經網路就是一種專門的前饋網路。
前饋神經網路被稱為網路 (network) 是因為它們通常用許多不同函數複合在一起來表示。該模型與一個有向無環圖相關聯,而圖描述了函數是如何複合在一起的。例如,我們有三個函數 f^(1)
, f^(2)
和 f^(3)
連接在一個鏈上以形成 f(x) = f^(3)(f^(2)(f^(1)(x)))
。這些鏈式結構是神經網路中最常用的結構。在這種情況下,f^(1)
被稱為網路的第一層 (first layer),f^(2)
被稱為第二層 (second layer),以此類推。鏈的全長稱為模型的深度 (depth)。正是因為這個術語才出現了「深度學習」這個名字。前饋網路的最後一層被稱為輸出層 (output layer)。
Q: 什麼是前饋神經網路 (feedforward neural network)?它與循環神經網路 (RNN) 的主要區別是什麼?
A: 前饋神經網路,也稱為深度前饋網路或多層感知機 (MLP),是一種其信息流是單向的、從輸入層經過一個或多個隱藏層最終到達輸出層的神經網路。 與循環神經網路 (RNN) 的主要區別在於連接方式: * 前饋網路: 信息只向前流動,不存在從後續層到先前層的反饋連接,也不存在層內的循環連接。 * 循環網路: 包含反饋連接,使得網路的輸出可以影響其後續的輸入(或內部狀態),從而具有記憶和處理序列數據的能力。
Q: 「深度學習」這個術語中的「深度」指的是什麼?
A: 「深度」指的是模型中函數鏈的長度,也就是從輸入到輸出的過程中,信息所經過的層的數量。一個具有多個隱藏層的網路被認為是「深」的。
Q: 在前饋神經網路中,第一層和最後一層通常被稱為什麼?
A:
- 第一層: 通常指最接近輸入數據的隱藏層(或有時指輸入層本身,但更常見的是指第一個進行計算的層)。
- 最後一層: 被稱為輸出層 (output layer),它產生模型的最終輸出。
Q: 前饋神經網路的目標是什麼?
A: 前饋神經網路的目標是近似某個目標函數 f*
。它通過學習一組參數 θ
來定義一個映射 y = f(x; θ)
,使得這個映射 f
能夠很好地逼近 f*
。例如,在分類任務中,f*
是將輸入 x
映射到正確類別 y
的函數。
6.1 示例:學習 XOR
重點摘要:
XOR 函數(異或邏輯)是一個經典的例子,說明了為什麼需要多層神經網路來解決非線性可分問題。單層感知機(沒有隱藏層)無法解決 XOR 問題,因為 XOR 不是線性可分的。
一個包含單個隱藏層(例如,包含兩個隱藏單元,使用 ReLU 激活函數)和一個輸出層的前饋神經網路可以完美地學習 XOR 函數。隱藏層將原始輸入空間映射到一個新的表示空間,在這個新的空間中,XOR 問題變成了線性可分的。
例如,對於 XOR 問題的四個輸入點 X = {[0,0], [0,1], [1,0], [1,1]}
,目標輸出分別是 [0,1,1,0]
。一個帶有隱藏層 h = max{0, XW + c}
和輸出層 y = hw + b
的網路,通過適當選擇權重 W, c, w, b
(如公式 6.4-6.6 所示),可以實現 XOR 函數。
這個例子展示了隱藏層學習到的非線性變換(特徵提取)的重要性。
Q: 為什麼 XOR (異或) 函數不能被單層感知機(沒有隱藏層的線性分類器)解決?
A: 因為 XOR 函數是非線性可分的 (non-linearly separable)。單層感知機只能學習線性的決策邊界(在二維情況下是一條直線,在高維情況下是一個超平面)。XOR 函數的四個輸入點 (0,0)→0
, (0,1)→1
, (1,0)→1
, (1,1)→0
無法用一條直線(或一個線性決策邊界)完美地分開其對應的兩類輸出。
Q: 如何使用一個帶有隱藏層的前饋神經網路來解決 XOR 問題?隱藏層在這個過程中扮演了什麼角色?
A: 可以使用一個帶有至少一個隱藏層(例如,包含兩個使用非線性激活函數如 ReLU 或 sigmoid 的隱藏單元)和一個輸出層的前饋神經網路來解決 XOR 問題。 隱藏層的角色: 隱藏層對原始輸入數據進行非線性變換,將其映射到一個新的特徵空間(隱藏表示空間)。在這個新的特徵空間中,原本在輸入空間中非線性可分的問題(如 XOR)可以變成線性可分的。然後,輸出層就可以在這個新的表示空間上學習一個線性的決策邊界來解決問題。 例如,教材中展示了一個使用 ReLU 激活的隱藏層,通過精心選擇的權重,將 XOR 的四個輸入點映射到一個新的二維空間,在這個空間中,兩類輸出可以被一條直線分開。
Q: 教材中解決 XOR 問題的神經網路架構是什麼樣的?
A: 教材中描述的解決 XOR 問題的神經網路包含:
- 輸入層: 接收兩個二進制輸入
x_1, x_2
。 - 隱藏層: 包含兩個隱藏單元
h_1, h_2
,使用 ReLU 激活函數。其計算為h = max{0, XW + c}
,其中X
是輸入,W
是輸入到隱藏層的權重矩陣,c
是隱藏層的偏置向量。 - 輸出層: 一個單獨的輸出單元,對隱藏層的激活進行線性組合並加上偏置,然後(通常)通過一個 sigmoid 函數(如果輸出是機率)或直接輸出(如果目標是0/1)。教材中的例子是
y = hw + b
,然後再通過某種方式得到最終的二進制輸出。
6.2 基於梯度的學習
重點摘要: 設計和訓練神經網路與使用梯度下降訓練其他任何機器學習模型並沒有太大不同。在 5.10 節中,我們描述了如何通過梯度下降法來最小化一個代價函數。神經網路訓練中使用的絕大多數算法都是基於梯度下降的。
6.2.1 代價函數
重點摘要:
深度神經網路設計中的一個重要方面是代價函數的選擇。幸運的是,神經網路的代價函數或多或少是與其他參數模型(如線性模型)的代價函數相同的。
在大多數情況下,我們的參數模型定義了一個分布 p(y|x; θ)
,並且我們簡單地使用最大概似原理。這意味著我們使用訓練數據和模型預測間的交叉熵作為代價函數。
有時,我們使用一個更簡單的方法,不是預測 y
的完整機率分布,而是僅僅學習在給定 x
時 y
的某個統計量。某些專門的損失函數允許我們來訓練這些估計量。
用於訓練神經網路的完整的代價函數,通常在我們這裡描述的基本代價函數的基礎上結合一個正則化項。
6.2.1.1 使用最大概似學習條件分布
重點摘要:
大多數現代神經網路使用最大概似來訓練。這意味著代價函數就是負對數概似 (negative log-likelihood, NLL),它與訓練數據和模型分布間的交叉熵等價。
J(θ) = -E_{(x,y)∼p̂_data} log p_model(y|x; θ)
(公式 6.12)
代價函數的具體形式取決於 log p_model
的具體形式。如果模型輸出是高斯分布,則最大概似等價于最小化均方誤差 (MSE) (公式 6.13)。如果模型輸出是伯努利分布(用於二元分類),則最大概似等價于最小化二元交叉熵損失。
Q: 在訓練神經網路時,最常用的代價函數是什麼?它與哪個統計原理相關?
A: 在訓練神經網路時,最常用的代價函數是負對數概似 (Negative Log-Likelihood, NLL)。 它與最大概似原理 (Maximum Likelihood Principle) 密切相關。最大化數據的(條件)對數概似等價于最小化其負對數概似。 負對數概似也等價于訓練數據的經驗分布與模型預測分布之間的交叉熵 (cross-entropy)。
Q: 代價函數的具體形式取決於什麼?請舉例說明兩種常見的輸出分布及其對應的代價函數。
A: 代價函數的具體形式取決於模型對輸出 y
的條件機率分布 p_model(y|x; θ)
的假設。
- 輸出服從高斯分布 (用於回歸任務):
- 假設
p_model(y|x; θ) = N(y; f(x;θ), σ^2I)
,其中f(x;θ)
是網路的預測均值,σ^2
是方差(通常假設為常數或可學習)。 - 最大化其對數概似等價于最小化均方誤差 (Mean Squared Error, MSE) 代價函數:
J(θ) = (1/2m) Σ_i ||y^(i) - f(x^(i);θ)||^2
(忽略常數項和與σ^2
相關的項)
- 假設
- 輸出服從伯努利分布 (用於二元分類任務):
- 假設網路輸出一個單一的機率值
p = f(x;θ)
,表示y=1
的機率。 - 最大化其對數概似等價于最小化二元交叉熵 (Binary Cross-Entropy) 或對數損失 (Log Loss) 代價函數:
J(θ) = - (1/m) Σ_i [ y^(i) log f(x^(i);θ) + (1-y^(i)) log(1 - f(x^(i);θ)) ]
其中y^(i)
是真實標籤 (0 或 1)。
- 假設網路輸出一個單一的機率值
6.2.1.2 學習條件統計量
重點摘要:
有時我們並不希望學習完整的機率分布 p(y|x;θ)
,而是僅僅學習在給定 x
時 y
的某個條件統計量,例如條件均值 E[y|x]
。
如果我們使用一個足夠強大的神經網路來表示函數 f(x;θ)
,並使用均方誤差作為代價函數來訓練它,那麼最小化代價函數會得到一個函數 f*(x)
,該函數近似於 E_{y∼p_data(y|x)}[y]
,即條件均值 (公式 6.15)。
如果使用平均絕對誤差 (Mean Absolute Error, MAE) 作為代價函數,即 L(y, f(x;θ)) = ||y - f(x;θ)||_1
,那麼最小化代價函數會得到一個近似於條件中位數的函數。
然而,MSE 和 MAE 在使用基於梯度的優化算法時,如果輸出單元的激活函數飽和(例如 sigmoid 或 tanh 的輸出接近其邊界),可能會導致梯度非常小,學習停滯。因此,通常更可取的是使用交叉熵損失,即使我們不關心預測完整的機率分布。
Q: 除了學習完整的條件機率分布 p(y|x;θ)
,神經網路還可以被訓練來學習輸入 x
條件下 y
的哪些統計量?這通常通過選擇什麼樣的代價函數來實現?
A:
- 學習條件均值
E[y|x]
:- 代價函數: 均方誤差 (Mean Squared Error, MSE),即
L(y, f(x;θ)) = ||y - f(x;θ)||^2
。 - 當使用 MSE 作為損失函數並訓練一個足夠表達能力的模型時,模型學習到的函數
f(x;θ)
會趨向於逼近y
在給定x
時的條件均值。
- 代價函數: 均方誤差 (Mean Squared Error, MSE),即
- 學習條件中位數 (Conditional Median):
- 代價函數: 平均絕對誤差 (Mean Absolute Error, MAE),即
L(y, f(x;θ)) = ||y - f(x;θ)||_1
。 - 當使用 MAE 作為損失函數時,模型學習到的函數會趨向於逼近
y
在給定x
時的條件中位數。
- 代價函數: 平均絕對誤差 (Mean Absolute Error, MAE),即
Q: 為什麼說即使我們只關心預測一個條件統計量(如均值),使用交叉熵損失(它預測完整的機率分布)有時仍然比直接使用 MSE 或 MAE 更好?
A: 主要原因是梯度特性和優化難度:
- MSE/MAE 與飽和激活函數的問題: 如果模型的輸出單元使用了飽和激活函數(如 sigmoid 或 tanh),那麼當預測值非常錯誤(導致激活值處於飽和區)時,MSE 或 MAE 損失函數關於模型參數的梯度可能會變得非常小(梯度消失)。這會使得學習過程非常緩慢,模型難以從錯誤的預測中恢復。
- 交叉熵損失的優勢: 當與合適的輸出激活函數(如 sigmoid 對應二元交叉熵,softmax 對應多元交叉熵)配合使用時,交叉熵損失通常具有更好的梯度特性。即使模型的預測非常錯誤(例如,機率預測接近 0 而真實值是 1),梯度通常仍然比較大,能夠提供有效的學習信號。這使得基於交叉熵的訓練通常更穩定且收斂更快。 因此,即使最終目標可能只是預測一個類別或一個均值,通過預測完整的機率分布並使用交叉熵損失進行訓練,往往在優化上更為有利。
6.2.2 輸出單元
重點摘要: 代價函數的選擇與輸出單元的選擇緊密相關。大多數情況下,我們簡單地使用數據分布和模型分布間的交叉熵。選擇如何表示輸出決定了交叉熵函數的形式。
- 用於高斯輸出分布的線性單元: 對於基於高斯輸出的模型,輸出層通常是線性的(沒有非線性激活),直接輸出預測的均值。最大概似等價于最小化均方誤差。
- 用於伯努利輸出分布的 Sigmoid 單元: (公式 6.19) 對於二元分類問題,輸出層通常使用一個 sigmoid 單元,其輸出
ŷ = σ(w^Th + b)
表示y=1
的機率。最大概似對應於最小化二元交叉熵損失。一個技巧是,如果直接計算log σ(z)
,當σ(z)
飽和時梯度會消失;但如果損失函數是ζ((1-2y)z)
(公式 6.26,其中ζ(x) = log(1+exp(x))
是 softplus 函數,z
是 sigmoid 的輸入),則梯度不會飽和。 - 用於 Multinoulli 輸出分布的 Softmax 單元: (公式 6.29) 對於多元互斥分類問題(
n
個類別),輸出層使用 softmax 函數將n
個線性輸出z_i
轉換為機率分布softmax(z)_i = exp(z_i) / Σ_j exp(z_j)
。最大概似對應於最小化多元交叉熵損失。一個數值穩定的技巧是計算log softmax(z)_i = z_i - log Σ_j exp(z_j)
(公式 6.30),並且在計算log Σ_j exp(z_j)
時使用log Σ_j exp(z_j - max_k z_k) + max_k z_k
來避免上溢或下溢。
Q: 在神經網路中,輸出單元(或輸出層的激活函數)的選擇主要取決於什麼?
A: 輸出單元的選擇主要取決於我們希望模型輸出的數據類型和我們對該輸出的機率分布的假設。它與所使用的代價函數緊密相關,通常是為了與最大概似原理下的某種條件機率分布相匹配。
Q: 針對以下三種常見的輸出數據類型,通常會選擇什麼樣的輸出單元和相應的代價函數?
1. 連續值輸出 (回歸任務,假設高斯噪聲):
* 輸出單元: 線性單元 (Linear Unit),即輸出層不使用任何非線性激活函數(或者說使用恆等激活函數)。網路直接輸出預測的均值。
* 代價函數: 均方誤差 (Mean Squared Error, MSE)。
2. 二元輸出 (0/1 分類任務):
* 輸出單元: Sigmoid 單元 (Sigmoid Unit)。其輸出值在 (0,1) 之間,可以解釋為預測 y=1
的機率。
* 代價函數: 二元交叉熵 (Binary Cross-Entropy) 或對數損失 (Log Loss)。
3. 多元互斥類別輸出 (K 個類別中選擇一個):
* 輸出單元: Softmax 單元 (Softmax Unit)。輸出層有 K
個單元,softmax 函數將它們的線性輸出轉換為一個 K
維的機率分布(所有元素非負且和為 1),每個元素表示對應類別的預測機率。
* 代價函數: 多元交叉熵 (Categorical Cross-Entropy) 或負對數概似。
Q: 在使用 sigmoid 輸出單元時,為了避免梯度飽和問題,損失函數的計算有什麼技巧?
A: 當 sigmoid 單元的輸入 z
的絕對值很大時,sigmoid 函數 σ(z)
會飽和(接近 0 或 1),其導數會非常小,導致梯度消失。
為了避免這個問題,在計算與 sigmoid 相關的損失(如二元交叉熵)時,一個技巧是直接使用 sigmoid 的輸入 z
(即線性層的輸出,logit)來計算損失,而不是先計算 σ(z)
然後再計算 log σ(z)
。
例如,二元交叉熵損失可以表示為 ζ((1-2y)z)
,其中 y
是真實標籤 (0 或 1),z
是 sigmoid 的輸入,ζ(x) = log(1+exp(x))
是 softplus 函數。這種形式的損失函數關於 z
的梯度通常不會飽和。許多深度學習庫在實現交叉熵損失時會自動使用這種數值穩定的計算方式。
Q: 在使用 softmax 輸出單元時,為了保證數值穩定性(避免上溢或下溢),計算 log softmax(z)
有什麼技巧?
A: Softmax 函數的計算涉及到指數運算 exp(z_j)
。如果某些 z_j
非常大,exp(z_j)
可能會導致上溢 (overflow);如果所有 z_j
都非常負,exp(z_j)
可能會導致下溢 (underflow),使得分母接近於零。
為了保證數值穩定性,計算 log softmax(z)_i = z_i - log Σ_j exp(z_j)
時,可以利用 log Σ_j exp(z_j)
的一個重要性質:
log Σ_j exp(z_j) = log (exp(max_k z_k) Σ_j exp(z_j - max_k z_k)) = max_k z_k + log Σ_j exp(z_j - max_k z_k)
通過從所有的 z_j
中減去它們的最大值 max_k z_k
,可以使得 exp(...)
的參數最大為 0,從而避免了上溢。即使所有 z_j - max_k z_k
都非常負,導致 exp(z_j - max_k z_k)
下溢為零,log Σ_j ...
仍然可以計算(因為至少有一個 exp(0)=1
項),或者可以通過其他技巧處理分母為零的情況。
這個技巧被稱為 “log-sum-exp” 技巧。
後續章節將討論隱藏單元、網路架構設計以及反向傳播算法。
6.3 隱藏單元
重點摘要: 選擇隱藏單元的類型(即激活函數)是一個重要的設計決策。
- 修正線性單元 (Rectified Linear Unit, ReLU): (公式 6.3)
g(z) = max{0, z}
。是最常用的默認選擇。優點是計算高效,且在正區間梯度為常數(不飽和),有助於緩解梯度消失。缺點是「死亡 ReLU」問題(如果一個 ReLU 單元的輸入總是負的,它將永遠輸出零且梯度為零)。 - ReLU 的變體: 為了解決死亡 ReLU 問題,出現了一些變體:
- Leaky ReLU:
g(z) = max{0,z} + α min{0,z}
(其中α
是一個小的正常數,如 0.01)。 - Parametric ReLU (PReLU):
α
作為可學習參數。 - Maxout 單元: (公式 6.37)
g(z)_i = max_{j∈G^(i)} z_j
。一個 Maxout 單元是k
個線性變換的最大值。它可以學習近似任意凸激活函數。
- Leaky ReLU:
- Logistic Sigmoid 和 Hyperbolic Tangent (tanh): (公式 6.38, 6.39) 傳統的選擇,但容易出現梯度飽和問題,導致學習緩慢,因此在深度網路的隱藏層中已較少作為首選。Tanh 通常比 sigmoid 表現略好,因為其輸出以零為中心。
- 其他激活函數: 如 softplus
ζ(a) = log(1+e^a)
(ReLU 的平滑版本),硬 tanh 等。 選擇哪種激活函數通常取決於經驗和具體任務。
Q: 為什麼說修正線性單元 (ReLU) 及其變體是目前深度神經網路中隱藏單元最常用的默認選擇?它有哪些主要的優點?
A: ReLU 及其變體成為最常用的默認選擇,主要因為以下優點:
- 計算高效: ReLU 的計算非常簡單(
max{0,z}
),相比 sigmoid 或 tanh 涉及到指數運算,ReLU 的計算成本低得多。 - 緩解梯度消失問題 (在正區間): 當輸入
z > 0
時,ReLU 的梯度是常數 1。這意味著在正激活區域,梯度可以無衰減地反向傳播,有助於訓練更深的網路。而 sigmoid 和 tanh 在其輸入絕對值較大時會飽和,梯度接近於零,導致梯度消失。 - 誘導稀疏性 (對於 ReLU): ReLU 會將所有負輸入置為零,這導致網路的激活具有一定的稀疏性,即對於任何給定的輸入,可能只有一部分隱藏單元是激活的。這種稀疏性有時被認為是有益的(類似於稀疏表示)。
Q: ReLU 激活函數存在什麼潛在的問題?有哪些常見的 ReLU 變體試圖解決這個問題?
A: ReLU 的一個主要潛在問題是「死亡 ReLU (Dying ReLU)」問題:
- 如果在訓練過程中,一個 ReLU 單元的輸入由於某次大的梯度更新或其他原因持續為負,那麼該單元將持續輸出零。由於當輸入為負時 ReLU 的梯度也為零,所以這個單元的權重將永遠不會再得到更新,該單元就「死亡」了,不再對網路的學習做出貢獻。
常見的 ReLU 變體試圖解決這個問題:
- Leaky ReLU (LReLU):
g(z) = max{αz, z}
(通常α
是一個小的正常數,如 0.01) 或寫成g(z) = z
ifz>0
elseαz
。它允許在輸入為負時仍然有一個小的、非零的梯度 (α
),從而防止單元完全死亡。 - Parametric ReLU (PReLU): (He et al., 2015) 與 Leaky ReLU 類似,但負區間的斜率
α
不是預設的超參數,而是作為模型的一個可學習參數,通過反向傳播進行學習。 - Exponential Linear Unit (ELU): (Clevert et al., 2015)
g(z) = z
ifz>0
elseα(exp(z)-1)
。在負區間具有飽和到-α
的特性,據稱可以使平均激活更接近零,並提高對噪聲的魯棒性。 - (Maxout 也可以被看作是 ReLU 的一種推廣)
- Leaky ReLU (LReLU):
Q: Maxout 單元是如何工作的?它有什麼特點?
A: Maxout 單元 (Goodfellow et al., 2013a) 的輸出是其多個線性輸入的最大值。
具體來說,一個 Maxout 單元接收 k
組不同的線性變換的輸入(每組都是 W_j^T x + b_j
),然後輸出這 k
個線性值的最大值:
g(x)_i = max_{j∈G^(i)} (W_j^T x + b_j)
(類似公式 6.37,其中 z_j
是線性輸入)
其中 G^(i)
是一個索引集合,定義了哪些線性輸入參與到第 i
個 Maxout 單元的計算中。
特點:
1. 分段線性凸函數: Maxout 單元本身是一個分段線性的凸激活函數。
2. 學習激活函數: 它可以被看作是在學習激活函數本身。通過適當選擇 k
和線性變換的參數,一個 Maxout 網路(包含多個 Maxout 層)理論上可以近似任意凸函數。
3. 對 Dropout 友好: Maxout 激活函數與 Dropout 正則化配合使用時通常表現良好。
4. 繼承 ReLU 的優點: 例如,不容易飽和,梯度在激活的線性段是存在的。
5. 參數較多: 相對於 ReLU,Maxout 單元通常需要更多的參數(因為它有多組權重和偏置)。
6.4 架構設計
重點摘要:
神經網路設計的另一個關鍵點是確定它的架構 (architecture),這指的是網路的整體結構,它應該具有多少單元,以及這些單元應該如何連接。
大多數神經網路被組織成層 (layers) 的單元組,每一層都是前一層的函數。在這種結構中,第一層由下式給出:
h^(1) = g^(1)(W^(1)T x + b^(1))
(公式 6.40)
後續層由下式給出:
h^(l) = g^(l)(W^(l)T h^(l-1) + b^(l))
(公式 6.41)
- 通用近似性質 (Universal Approximation Theorem): (Hornik et al., 1989; Cybenko, 1989) 表明,一個具有線性輸出層和至少一個具有「擠壓」性質的激活函數(如 sigmoid)的隱藏層的前饋神經網路,只要隱藏單元數量足夠,就可以以任意精度近似任何 Borel 可測函數(即幾乎所有我們感興趣的連續函數)。這意味著淺層(單隱藏層)網路理論上具有很強的表達能力。
- 深度 vs. 寬度: 儘管通用近似定理表明淺層網路就足夠,但在實踐中,更深的網路(具有多個隱藏層)通常比同樣參數數量的淺而寬的網路更容易學習和泛化得更好。深度架構能夠學習到數據的層次化特征,並且在表示某些複雜函數時可能更有效率(即用更少的參數)。
- 架構選擇的經驗性: 儘管有一些理論指導,但神經網路架構的選擇(如層數、每層的單元數、連接方式等)在很大程度上仍然是一個經驗性的過程,需要通過實驗和驗證來確定。
6.4.1 通用近似性質和深度
Q: 什麼是通用近似定理 (Universal Approximation Theorem)?它對單隱藏層前饋神經網路的表達能力說明了什麼?
A: 通用近似定理指出,一個具有線性輸出層和至少一個隱藏層(該隱藏層使用任何「擠壓」性質的非線性激活函數,如 sigmoid 或 tanh,或者更一般地,任何非多項式的連續激活函數)的前饋神經網路,只要其隱藏層包含足夠數量的隱藏單元,就可以以任意所需的精度近似任何定義在輸入空間有界閉集上的連續函數。 對於單隱藏層網路,這意味著理論上,只要我們允許隱藏層的寬度(單元數量)足夠大,它就能夠表示(或近似)非常廣泛的函數類別。
Q: 既然通用近似定理表明淺層(單隱藏層)網路就具有很強的表達能力,為什麼在實踐中我們通常更傾向于使用深度(多隱藏層)網路?
A: 儘管理論上淺層網路具有通用近似能力,但在實踐中使用深度網路通常更為有利,原因如下:
- 表示效率 (Representation Efficiency): 對於某些類型的複雜函數(特別是那些具有層次化結構的函數),深度網路可能可以用比淺層網路少得多的參數(和計算單元)來有效地表示它們。換句話說,要達到相同的近似精度,一個深度網路可能比一個淺層網路更「緊湊」。
- 學習層次化特征 (Learning Hierarchical Features): 深度架構天然地適合學習數據的層次化表示。每一層可以在前一層特征的基礎上學習更抽象、更複雜的特征,這對於理解複雜的現實世界數據(如圖像、語音、文本)非常重要。淺層網路則難以有效地學習這種層次結構。
- 更好的泛化能力 (Generalization): 實驗和理論都表明,在許多情況下,深度網路比同樣參數數量(或更少參數)的淺層網路更容易學習並且具有更好的泛化性能。這可能與深度網路能夠學習到更魯棒、更具有不變性的特征有關。
- 更容易優化 (在某些方面): 雖然訓練非常深的網路有其自身的挑戰(如梯度消失/爆炸),但在某些情況下,將一個非常複雜的映射分解為多個較簡單的層次化映射(如深度網路所做的)可能比直接學習一個單一的、非常複雜的淺層映射更容易優化。 通用近似定理只說明了表達能力的存在性,並沒有說明這種表示是否容易學習,或者是否需要不切實際數量的隱藏單元。
Q: 教材中提到的 Montufar et al. (2014) 的研究結果如何支持使用深度網路的優勢?
A: Montufar et al. (2014) 的研究表明,深度網路(特別是那些使用 ReLU 或 Maxout 等分段線性激活函數的網路)能夠表示的線性區域 (linear regions) 的數量可以隨網路深度呈指數級增長。 一個函數的線性區域數量可以被看作是其表達能力的某種度量。如果一個深度網路能夠比一個具有相同參數數量的淺層網路表示多得多的線性區域,這就意味著深度網路在表示複雜的分段線性函數時具有顯著的優勢。 他們的理論結果(如圖 6.5 和公式 6.42, 6.43)為「深度比寬度更有效」這一經驗觀察提供了一些理論支持。
6.5 反向傳播和其他的微分算法
重點摘要:
當我們使用前饋神經網路去接受輸入 x
並產生輸出 ŷ
時,信息正向流過網路。這被稱為前向傳播 (forward propagation)。在訓練過程中,前向傳播可以持續向前直到它產生一個標量代價 J(θ)
。反向傳播 (backpropagation) 算法 (Rumelhart et al., 1986c) 允許信息從代價函數反向流過網路,以便計算梯度。
反向傳播算法,通常簡稱為 backprop,並不僅僅適用於多層感知機,它可以精確計算任何由基本可微運算(如加法、乘法、指數、對數、三角函數等)組成的函數的梯度。它本質上是應用微積分中的鏈式法則 (chain rule) 來高效計算複雜函數的梯度。
- 計算圖 (Computational Graph): 反向傳播的概念可以通過計算圖來清晰地理解。計算圖將複雜的計算分解為一系列基本操作,每個操作對應圖中的一個節點。
- 鏈式法則: 如果
z = f(y)
且y = g(x)
,那麼dz/dx = (dz/dy) * (dy/dx)
。反向傳播系統地、從後向前地應用鏈式法則來計算損失函數關於網路中所有參數和中間變數的梯度。 - 符號到符號的導數 (Symbol-to-symbol derivatives) vs. 符號到數值的導數 (Symbol-to-number derivatives): 現代深度學習框架(如 Theano, TensorFlow, PyTorch)通常使用自動微分 (automatic differentiation) 來實現反向傳播。它們可以處理更廣泛的計算圖,並且能夠高效地計算梯度。 算法 6.1 到 6.6 詳細描述了反向傳播的數學原理和實現細節。
6.5.1 計算圖
Q: 什麼是計算圖 (computational graph)?它在理解和實現反向傳播中有什麼作用?
A: 計算圖是一種將數學表達式或計算過程表示為有向圖的方法。
- 節點 (Nodes): 代表計算中的變數(如輸入、參數、中間結果、最終輸出/損失)或操作(如加法、乘法、激活函數)。
- 有向邊 (Directed Edges): 表示數據(變數)在操作之間的流動方向。
在理解和實現反向傳播中的作用:
- 清晰化計算依賴: 計算圖清晰地展示了模型中所有變數之間的計算依賴關係,即哪些變數的計算依賴於哪些其他變數。
- 系統化應用鏈式法則: 反向傳播算法可以被看作是在計算圖上從輸出節點(損失函數)向輸入節點(參數)反向傳播梯度的過程。計算圖的結構直接指導了如何系統地、高效地應用鏈式法則來計算每個節點的梯度。
- 模塊化和自動化: 現代深度學習框架使用計算圖來自動構建反向傳播的路徑並計算梯度,用戶只需要定義前向傳播的計算過程。
6.5.2 微積分中的鏈式法則
Q: 微積分中的鏈式法則是什麼?它與反向傳播算法有何根本聯繫?
A: 微積分中的鏈式法則是計算複合函數導數的一個基本規則。
- 單變數情況: 如果
y = f(u)
且u = g(x)
,那麼y
關於x
的導數是dy/dx = (dy/du) * (du/dx)
。 - 多變數情況 (向量/矩陣形式): 如果
z = f(y)
且y = g(x)
(其中x, y, z
可能是向量或矩陣),那麼z
關於x
的 Jacobian 矩陣是∂z/∂x = (∂z/∂y) * (∂y/∂x)
(這裡的乘法是矩陣乘法)。 與反向傳播算法的根本聯繫: 反向傳播算法本質上就是對一個(通常非常複雜的)複合函數(即神經網路的損失函數)系統地、從輸出端向輸入端(即從後向前)遞歸地應用鏈式法則,以計算損失函數關於網路中所有參數和中間激活值的梯度。計算圖為這種鏈式法則的應用提供了一個清晰的結構化框架。
6.5.3 遞歸地使用鏈式法則來實現反向傳播
Q: 反向傳播算法是如何遞歸地應用鏈式法則來計算梯度的?請簡述其基本步驟。
A: 反向傳播算法的基本步驟(以計算損失 L
關於某個參數 W
的梯度為例):
- 前向傳播: 首先,執行一次完整的前向傳播,計算網路中所有中間激活值和最終的損失
L
。在這個過程中,保存所有中間變數的值,因為它們在反向傳播時會被用到。 - 初始化輸出梯度: 損失
L
關於其自身的梯度是 1,即∂L/∂L = 1
。 - 反向傳播梯度: 從輸出層開始,逐層向輸入層反向計算梯度:
- 對於網路中的任何一個節點(或一層)
u^(l)
,如果我們已經知道了損失L
關於其後續節點(或層)u^(l+1)
的梯度∂L/∂u^(l+1)
,並且我們知道u^(l+1)
是如何通過一個函數f^(l)
從u^(l)
計算得到的(即u^(l+1) = f^(l)(u^(l))
),那麼根據鏈式法則,損失L
關於u^(l)
的梯度可以計算為:∂L/∂u^(l) = (∂L/∂u^(l+1)) * (∂u^(l+1)/∂u^(l))
其中∂u^(l+1)/∂u^(l)
是函數f^(l)
的 Jacobian 矩陣。 - 如果一個節點
u^(l)
同時是多個後續節點的輸入(即在計算圖中有多個出邊),那麼∂L/∂u^(l)
是從所有這些後續節點傳回的梯度的總和。 - 如果
u^(l)
是一個參數(例如,權重W
或偏置b
),那麼計算得到的∂L/∂u^(l)
就是損失關於該參數的梯度。 這個過程遞歸地進行,直到計算出損失關於所有我們感興趣的參數(以及可能的輸入)的梯度。
- 對於網路中的任何一個節點(或一層)
6.5.4 全連接 MLP 中的反向傳播計算
Q: 對於一個典型的全連接多層感知機 (MLP),反向傳播算法在計算權重和偏置的梯度時,涉及到哪些主要的矩陣/向量運算?
A: 假設一個 MLP 的某一層計算如下:
a^(l) = W^(l) h^(l-1) + b^(l)
(線性組合)
h^(l) = g^(l)(a^(l))
(激活函數)
其中 h^(l-1)
是前一層的激活,W^(l)
和 b^(l)
是當前層的權重和偏置,g^(l)
是激活函數。
在反向傳播時,假設我們已經計算得到了損失 L
關於當前層激活 h^(l)
的梯度 δ^(l) = ∂L/∂h^(l)
。
- 計算損失關於預激活值
a^(l)
的梯度:∂L/∂a^(l) = δ^(l) ⊙ g'^(l)(a^(l))
(其中⊙
表示逐元素乘積,g'^(l)
是激活函數的導數) - 計算損失關於權重
W^(l)
的梯度:∂L/∂W^(l) = (∂L/∂a^(l))^T h^(l-1)
(這裡假設∂L/∂a^(l)
是行向量,或者需要進行適當的轉置和求和操作以得到正確的矩陣維度) 更常見的寫法是∂L/∂W^(l) = h^(l-1) (∂L/∂a^(l))^T
(如果h^(l-1)
和∂L/∂a^(l)
都視為列向量,則這是外積然後可能需要對批量求平均)。 或者,如果δ_a^(l) = ∂L/∂a^(l)
,那麼∇_{W^(l)} L = δ_a^(l) (h^(l-1))^T
。 - 計算損失關於偏置
b^(l)
的梯度:∂L/∂b^(l) = ∂L/∂a^(l)
(通常需要對批量維度求和或取平均) - 將梯度傳播到前一層
h^(l-1)
:δ^(l-1) = ∂L/∂h^(l-1) = (W^(l))^T (∂L/∂a^(l))
6.5.5 符號到符號的導數
Q: 什麼是「符號到符號的導數 (symbol-to-symbol differentiation)」?它與「符號到數值的導數 (symbol-to-number differentiation)」有何不同?現代深度學習框架通常使用哪種方式?
A:
- 符號到數值的導數: 這種方法接收一個函數(或計算圖)和一組具體的輸入數值,然後計算出該函數在這些具體數值點的梯度(也是數值)。傳統的數值微分(如有限差分)就是這種方式。
- 符號到符號的導數: 這種方法接收一個描述函數的符號表達式(或計算圖的結構),然後輸出一個描述該函數導數的新的符號表達式(或新的計算圖結構)。這個導數表達式本身也是一個函數,可以後續再代入具體數值進行計算。
現代深度學習框架(如 TensorFlow, PyTorch, JAX)通常使用符號到符號的導數(或更準確地說是其變種,如基於計算圖的自動微分)。
它們首先構建一個表示前向計算過程的計算圖(符號表示)。然後,它們可以自動地從這個前向計算圖推導出一個計算梯度的反向計算圖(也是符號表示)。最後,當需要實際計算梯度時,再將具體的輸入數據和參數值代入這個反向計算圖進行數值計算。
這種方式的優點是:
- 高效: 推導出梯度計算圖後,可以對其進行優化(例如,公共子表達式消除、內存優化等),然後再執行數值計算。
- 靈活: 可以計算高階導數。
- 易於使用: 用戶只需要定義前向計算,框架自動處理梯度計算。
6.5.10 高階微分
Q: 深度學習框架是否支持計算高階導數?高階導數在優化中有什麼潛在應用?
A: 是的,許多現代深度學習框架(特別是那些基於符號微分或更高級的自動微分技術的框架,如 TensorFlow, PyTorch, JAX)支持計算高階導數(即導數的導數)。 高階導數在優化中的潛在應用包括: 1. 二階優化方法: * 牛頓法: 需要計算 Hessian 矩陣(二階導數矩陣)及其逆。 * 擬牛頓法 (如 BFGS, L-BFGS): 雖然不直接計算 Hessian,但其更新依賴於梯度的一階變化,間接利用了二階信息。 * Hessian-free 優化: 試圖在不顯式形成 Hessian 矩陣的情況下,利用 Hessian 與向量的乘積(可以通過兩次反向傳播計算)來進行優化。 2. 曲率分析和正則化: * 分析損失函數的局部曲率,以理解優化景觀的特性(例如,檢測鞍點、平坦區域)。 * 某些正則化方法可能涉及到對 Hessian 矩陣的跡或特征值的懲罰(例如,鼓勵損失函數更平滑)。 3. 敏感性分析和不確定性量化: 高階導數可以用於分析模型輸出對輸入或參數微小變化的敏感性,以及估計模型預測的不確定性。 4. 元學習 (Meta-Learning): 在某些元學習算法中,可能需要對內部優化過程的結果(本身涉及到梯度)再求梯度。 儘管高階導數(特別是完整的 Hessian 矩陣)的計算成本對於大型神經網路來說通常很高,但利用其近似或特定乘積形式的技術仍在不斷發展。