1. 程式人生 > >《deep learning》學習筆記(6)——深度前饋網路

《deep learning》學習筆記(6)——深度前饋網路

6.1 例項:學習 XOR


通過學習一個表示來解決 XOR 問題。圖上的粗體數字標明瞭學得的函式必須在每個點輸出的值。(左) 直接應用於原始輸入的線性模型不能實現 XOR 函式。當 x 1 = 0 時,模型的輸出必須隨著 x 2 的增大而增大。當 x 1 = 1 時,模型的輸出必須隨著 x 2 的增大而減小。線性模型必須對x 2 使用固定的係數 w 2 。因此,線性模型不能使用 x 1 的值來改變 x 2 的係數,從而不能解決這個問題。(右) 在由神經網路提取的特徵表示的變換空間中,線性模型現在可以解決這個問題了。在我們的示例解決方案中,輸出必須為 1 的兩個點摺疊到了特徵空間中的單個點。換句話說,非線性特徵將 x = [1,0] ⊤ 和 x = [0,1] ⊤ 都對映到了特徵空間中的單個點 h = [1,0] ⊤ 。線性模型現在可以將函式描述為 h 1 增大和 h 2 減小。在該示例中,學習特徵空間的動機僅僅是使得模型的能力更大,使得它可以擬合訓練集。在更現實的應用中,學習的表示也可以幫助模型泛化。

程式碼實現:

import tensorflow as tf
import numpy as np

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
Y = np.array([[0], [1], [1], [0]])

x = tf.placeholder(tf.float32, [None, 2])
y = tf.placeholder(tf.float32, [None, 1])

w1_1 = tf.Variable(tf.random_normal([2, 1]))
w1_2 = tf.Variable(tf.random_normal([2
, 1])) w2 = tf.Variable(tf.random_normal([2, 1])) b1_1 = tf.constant(0.1, shape=[1]) b1_2 = tf.constant(0.1, shape=[1]) b2 = tf.constant(0.1, shape=[1]) h1 = tf.nn.relu(tf.matmul(x, w1_1) + b1_1) h2 = tf.nn.relu(tf.matmul(x, w1_2) + b1_2) # 將兩陣列按列合併 hidden = tf.concat([h1, h2], 1) out = tf.matmul(hidden, w2) + b2 loss = tf.reduce_mean(tf.square(out - y)) train = tf.train.AdamOptimizer(0.01
).minimize(loss) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for i in range(1000): for j in range(4): sess.run(train, feed_dict={x: np.expand_dims(X[j], 0), y: np.expand_dims(Y[j], 0)}) loss_ = sess.run(loss, feed_dict={x: X, y: Y}) print("step: %d, loss: %.3f"%(i, loss_)) print("X: %r"%X) print("pred: %r"%sess.run(out, feed_dict={x: X}))

6.2 基於梯度的學習

神經網路中的非線性導致它的大部分代價函式變得非凸,對於非凸的損失函式,梯度下降演算法不能保證收斂到全域性最優,因此神經網路模型中的引數初始化是非常重要的,通常會將所有的權重初始化為一個較小的隨機數,並且將偏置初始化為0或者較小的正值。同其他機器學習演算法一樣,基於梯度的學習方法,需要設計代價函式,選擇模型輸出的表示方法。這裡介紹神經網路中關於它們的一些設計方法。

6.2.1 代價函式

同其他機器學習模型一樣,大多數情況下,神經網路的引數模型定義一個分佈 ,並且使用最大似然原理,用訓練資料和模型預測間的交叉熵作為損失函式。有時候我們不需要預測 y 的完整概率分佈,而是僅僅預測在給定 x 的條件下 y 的統計量。這個時候我們會使用一些專門的損失函式來進行模型的評估。

6.2.1.1 使用最大似然學習條件分佈

大多數現代神經網路使用極大似然原理,也就是說模型的損失函式和訓練資料和模型分佈間的交叉熵等價。它表示為:

由於神經網路的特殊結構,導致神經網路必須注意的是損失函式的梯度必須有足夠大的預測性,這樣才能很好的指導演算法的學習。很多輸出單元都會包含一個指數函式,當變數取絕對值非常大的負值時函式會變得飽和(函式變得很“平”),函式梯度變得很小,而負的對數似然能夠抵消輸出單元中的指數效果。

6.2.1.2 學習條件統計量

我們有時只需要學習給定 x 的某個條件統計量,不需要學習一個完整的概率分佈 。這是需要使用變分法(calculus of variations),通過學習到一個函式,這個函式能夠計算給定 x 時 y 的均值和中位數。目前我們給出學習給定 x 時的 y 均值和中位數的優化問題:
預測y的均值 通過優化問題

從而得到

只要這個函式屬於我們所要優化的函式族,那麼我們可以得到一個對於每個 x 預測 y 均值的函式。
不同的損失函式可以給出不同的統計量,為了預測y的中位數,我們通過優化問題

得到一個函式,如果這個函式屬於我們所需優化的函式族,那麼這個函式可以對每個 x 的中位數。這個損失函式其實就是平均絕對誤差(mean absolute error)。
需要提出的是,均方誤差和平均絕對誤差在使用基於梯度的優化方法時,會因為飽和的問題導致效果不好。因此即使我們不需要預測整個 ,也傾向於使用交叉熵損失函式。

6.2.2 輸出單元

從前文可知,通過極大似然的交叉熵損失函式,與我們選擇的輸出模型相關。本節討論輸出單元的選擇,我們假定本節輸出單元對前饋網路提供的一組定義為 的隱藏特徵進行變換來完成整個網路的任務。

6.2.2.1 用於高斯輸出分佈的線性單元

線性輸出層基於仿射變換,仿射變換的單元被稱為線性單元。給定特徵 h ,線性輸出層產生輸出向量

,線性輸出層常被用來產生條件高斯分佈均值:

最大化其最大似然等價於最小化均方誤差。線性模型不會飽和,因此適合採用基於梯度的優化演算法,也可以使用其他多種優化演算法。

6.2.2.2 用於 Bernoulli 輸出分佈的 sigmoid 單元

對於二分類問題,極大似然方法是定義 y 下的Bernoulli分佈。Bernoulli分佈僅需要預測單個引數 ,並且這個引數處於區間 [0, 1] 中。
如果我們使用線性單元,則需要限定它是一個有效的概率值:

這滿足概率要求,但是使用梯度下降演算法無法高效訓練這個模型,因為當

處於單位區間外,模型梯度都將為0,梯度為0則使得演算法不能再繼續學習引數。我們需要使用一種方法使得無論模型合適給出錯誤答案,都能有一個比較大的梯度。這就是使用sigmoid單元的原因,sigmoid單元定義如下:

我們分析使用sigmoid單元的極大似然交叉熵損失函式,首先忽略對於 x 的依賴性,只討論如何用z 的概率分佈。sigmoid可以構造一個非歸一化(和不為1)的概率分佈 。通過除以一個合適的常數,可以得到一個有效的概率分佈。假定非歸一化的對數概率對 y 和 z 是線性的,可以對它取指數來得到非歸一化的概率。然後進行歸一化,可以發現它服從Bernoulli分佈,該分佈收到 z 的sigmoid變換控制。步驟如下:


歸一化:


定義這種二值分佈的變數z被稱為分對數(logit)。
由上文可知,基於最大似然交叉熵的損失函式為 ,上文中說明了損失函式中的對數抵消了sigmoid中的指數,使得梯度不會飽和。基於極大似然交叉熵的損失函式如下所示:

6.2.2.3 用於 Multinoulli 輸出分佈的 softmax 單元

當我們進行n分類時,我們可以使用softmax函式,softmax函式用於表示 n 個不同分類上的概率分佈,用向量 表示,其中,每個元素 ,要求每個 在0到1之間,並且所有 之和為1。類似於上文講的二分類,多分類首先用線性層預測了未歸一化的概率:

其中 。softmax函式對其指數化並且歸一化來獲得滿足條件的 。softmax函式形式為:

使用最大化對數似然來訓練softmax輸出目標 y,得到如下損失函式:

這個損失函式不會出現飽和的情況,對於錯誤的引數總能得到比較大的梯度,需要注意的是,如果不適用對數似然的損失函式,那麼由於指數項的存在將導致飽和問題而不能達到好的訓練效果。

6.3 隱藏單元

6.3.1 整流線性單元及其擴充套件

整流線性單元的啟用函式如下:

整流線性單元的特點是當它處於啟用狀態時,它們的梯度大於0並且是一致的,一階導數處處為1,這對於學習演算法來說是很有用的。整流線性單元通常作用於仿射變換之上:

初始化的仿射變換引數的建議是將 b 的所有元素設定成一個較小的正值,這樣整流線性單元在初始時就對訓練集中的大多數輸入處於啟用狀態,並且允許導數通過。
整流線性單元的一個缺陷是未啟用狀態不能帶來基於梯度學習的效果。因此許多整流線性單元的擴充套件設計了不同的方法避免這種情況。當 z_i=0*時使用一個非零的斜率* alpha_i ,表示為

下面是三種基於這種設計方法的啟用函式:
絕對值整流(absolute value rectification):通過固定 來得到
滲漏整流線性單元(Leaky ReLU):固定 alpha_i 為一個類似0.01的小值
引數化整流線性單元(parametric ReLU)或者PReLU:將 alpha_i 也作為一個要學習的引數

maxout單元(maxout unit)進一步擴充套件了整流線性單元,maxout單元將z劃分為每組具有 k 個值的組,表示如下:

其中 是組 i 的輸入索引集合

,maxout可以學習 k 段的分段線性凸函式。當 k 足夠大時,maxout可以以任意精度來近似任何凸函式。由於maxout相比普通整流線性單元增加了 k 組,因此引數增加了 k 倍,所以訓練maxout需要更多的正則化或者更多訓練樣本來提高模型的泛化能力。

6.3.2 logistic sigmoid與雙曲正切函式

對於隱藏單元,logistic sigmoid函式只有在輸入接近0的時候它們的梯度才比較大,因此不鼓勵將它們作為前饋網路中的隱藏層,對於上文提到的輸出層,對數似然損失函式抵消了sigmoid的飽和性,因此可以用在基於梯度學習的輸出單元中。
雙曲正切啟用函式 通常比sigmoid函式表現要好,它和sigmoid啟用函式關係密切: 。因此需要用sigmoid函式作為隱藏層啟用函式時,可以考慮使用雙曲正切函式代替。雙曲正切函式在0附近與單位函式類似,因此使用雙曲正切函式作為啟用函式類似於學習一個線性模型,因此在輸入處於0附近時,使用tanh網路更加容易進行學習。
相比前饋網路的隱藏層,sigmoid啟用函式在迴圈網路等一些額外要求不能使用分段啟用函式的場景中更實用。

6.4 架構設計

神經網路的架構(architecture)指網路的整體架構:神經網路需要多少單元以及單元之間的連線方式。大多數神經網路被組織成層的單元組,然後將這些層佈置成鏈式結構,其中每一層是前一層的函式。在這種結構中,第一層表示如下:

那麼第二層為:

在這個鏈式結構中,主要考慮的是網路的深度和每一層的寬度。通常來說更深的網路對每一層能夠使用更少的單元數以及引數,並且泛化效果更好,但是它也更能難以訓練

6.4.1 萬能近似性質和深度

萬能近似定理(universal approximation theorem)表明一個前饋神經網路如果具有線性輸出層和至少一層具有任何一種“擠壓”性質的啟用函式(如logistic sigmoid啟用函式)的隱藏層,只要給與網路足夠數量的隱藏單元,它可以以任意精度來近似任何從一個有限維空間到另一有限維空間的Borel可測函式,前饋網路的導數也可以任意精度來近似函式的導數。簡單的說,定義在 R^n 的有界閉集上的任意連續函式是Borel可測的,因此可以用神經網路來近似。神經網路也可以近似從任何有限維離散空間對映到另一個的函式。萬能近似性質被證明對於比較廣泛類別的啟用函式都是適用的,其中包括整流線性單元。
萬能近似定理說明了存在達到任意精度的這麼一個神經網路,但是沒有指出這個網路有多大。Barron提供了單層網路近似一大類函式所需大小的一些界,在最壞的情況下,隱藏單元的數量是指數數量。具有單層的前饋網路足以表達任何函式,但是單元數會多到無法實現,因此無法正確學習和泛化,在很多情況下,使用更深的模型能夠減少表示期望函式所需的單元數量,並且可以減少泛化誤差。增加網路的深度往往能夠得到比增加寬度更加好的泛化能力。增加深度能夠更好的泛化的原因可以理解為神經網路將學習分解成了多個步驟(例如先認識點,再認識線,再認識形狀等),每一層在上一層的基礎上進行了學習。

6.5 反向傳播和其他的微分演算法