Tensorflow過擬合與欠擬合

由於真實數據的分佈往往是未知而且複雜的,無法推斷出其分佈函數的類型和相關參 數,因此人們在選擇學習模型的容量時,往往會根據經驗值選擇稍大的模型容量。但模型 的容量過大時,有可能出現在訓練集上表現較好,但是測試集上表現較差的現象。

當模型的容量過大時,網絡模型除了學習到訓練集數據的模態之外,還把額外的觀測 誤差也學習進來,導致學習的模型在訓練集上面表現較好,但是在未見的樣本上表現不 佳,也就是模型泛化能力偏弱,我們把這種現象叫作過擬合(Overfitting)。當模型的容量過 小時,模型不能夠很好地學習到訓練集數據的模態,導致訓練集上表現不佳,同時在未見 的樣本上表現也不佳,我們把這種現象叫作欠擬合(Underfitting)。

儘管統計學習理論很難給出神經網絡所需要的最小容量,但是卻可以根據奧卡姆剃刀 原理(Occam’s razor)來指導神經網絡的設計和訓練。奧卡姆剃刀原理是由 14 世紀邏輯學 家、聖方濟各會修士奧卡姆的威廉(William of Occam)提出的一個解決問題的法則,他在 《箴言書注》2 卷 15 題說“切勿浪費較多東西,去做‘用較少的東西,同樣可以做好的事 情’。”1。也就是說,如果兩層的神經網絡結構能夠很好的表達真實模型,那麼三層的神經 網絡也能夠很好的表達,但是我們應該優先選擇使用更簡單的兩層神經網絡,因爲它的參 數量更少,更容易訓練,也更容易通過較少的訓練樣本獲得不錯的泛化誤差。

測試集中的樣本不能參與模型的訓練,防止模型“記憶” 住數據的特徵,損害模型的泛化能力。

劃分過的 訓練集與原來的訓練集的功能一致,用於訓練模型的參數,而驗證集則用於選擇模型的超 參數(模型選擇,Model selection).

❑ 根據驗證集的性能表現來調整學習率、權值衰減係數、訓練次數等。 

❑ 根據驗證集的性能表現來重新調整網絡拓撲結構。
❑ 根據驗證集的性能表現判斷是否過擬合和欠擬合。

驗證集與測試集的區別在於,算法設計人員可以根據驗證集的表現來調整模型的各種 超參數的設置,提升模型的泛化能力,但是測試集的表現卻不能用來反饋模型的調整,否 則測試集將和驗證集的功能重合,因此在測試集上的性能表現將無法代表模型的泛化能 力。

如何選擇合適的 Epoch 就提前停止訓練(Early Stopping),避免出現過擬合現象 呢?我們可以通過觀察驗證指標的變化,來預測最適合的 Epoch 可能的位置。具體地,對 於分類問題,我們可以記錄模型的驗證準確率,並監控驗證準確率的變化,當發現驗證準 確率連續𝑛個 Epoch 沒有下降時,可以預測可能已經達到了最適合的 Epoch 附近,從而提 前終止訓練。

通過限制網絡參數的稀疏性, 可以來約束網絡的實際容量。引入範數

優化目標除了要最小化原來的損失函數L( ,𝑦)之外,還需要約束網絡參數的稀疏 性𝛺(𝜃),優化算法會在降低L( ,𝑦)的同時,儘可能地迫使網絡參數𝜃𝑖變得稀疏,它們之間 的權重關係通過超參數𝜆來平衡。較大的𝜆意味着網絡的稀疏性更重要;較小的𝜆則意味着 網絡的訓練誤差更重要。通過選擇合適的𝜆超參數,可以獲得較好的訓練性能,同時保證網 絡的稀疏性,從而獲得不錯的泛化能力。

數據增強(Data Augmentation)是指在維持樣本標籤不變的條件下,根據先驗知識改變樣本的特徵,使得新 產生的樣本也符合或者近似符合數據的真實分佈。

TensorFlow 中提供了常用圖片的處理函數,位於 tf.image 子模塊中。通過 tf.image.resize 函數可以實現圖片的縮放功能,我們將數據增強一般實現在預處理函數 preprocess 中,將圖片從文件系統讀取進來後,即可進行圖片數據增強操作。

def preprocess(x,y):
# 預處理函數
# x: 圖片的路徑,y:圖片的數字編碼 
    x = tf.io.read_file(x)
    x = tf.image.decode_jpeg(x, channels=3)  # RGBA 
# 圖片縮放到 244x244 大小,這個大小根據網絡設定自行調整 
x = tf.image.resize(x, [244, 244])

 # 圖片逆時針旋轉 180 度
x = tf.image.rot90(x,2)
# 隨機水平翻轉
x = tf.image.random_flip_left_right(x)
# 隨機豎直翻轉
x = tf.image.random_flip_up_down(x)

# 圖片先縮放到稍大尺寸
x = tf.image.resize(x, [244, 244])
# 再隨機裁剪到合適尺寸
x = tf.image.random_crop(x, [224,224,3])

 

通過生成模型在原有數據上進行訓練,學習到真實數據的分佈,從而利用生成模型獲 得新的樣本,這種方式也可以在一定程度上提升網絡性能。如通過條件生成對抗網絡 (Conditional GAN,簡稱 CGAN)可以生成帶標籤的樣本數據

以實心網格所在的像素爲參考點,它周邊 歐式距離小於或等於 𝑘 的像素點以矩形網格表示,網格內的像素點重要性較高,網格外的

像素點較低。這個高寬爲𝑘的窗口稱爲感受野(Receptive Field),它表徵了每個像素對於中心 像素的重要性分佈情況,網格內的像素纔會被考慮,網格外的像素對於中心像素會被簡單地忽略。

這種基於距離的重要性分佈假設特性稱爲局部相關性,它只關注和自己距離較近的部 分節點,而忽略距離較遠的節點。在這種重要性分佈假設下,全連接層的連接模式變成了 如圖 10.4 所示,輸出節點𝑗只與以𝑗爲中心的局部區域(感受野)相連接,與其它像素無連 接。

2014 年,Matthew D. Zeiler 等人 [5]嘗試利用可視化的方法去理解卷積神經網絡到底 學到了什麼。通過將每層的特徵圖利用“反捲積”網絡(Deconvolutional Network)映射回輸 入圖片,即可查看學到的特徵分佈,如圖 10.32 所示。可以觀察到,第二層的特徵對應到 邊、角、色彩等底層圖像提取;第三層開始捕獲到紋理這些中層特徵;第四、五層呈現了 物體的部分特徵,如小狗的臉部、鳥類的腳部等高層特徵。通過這些可視化的手段,我們 可以一定程度上感受卷積神經網絡的特徵學習過程。

圖片數據的識別過程一般認爲也是表示學習(Representation Learning)的過程,從接受到 的原始像素特徵開始,逐漸提取邊緣、角點等底層特徵,再到紋理等中層特徵,再到頭 部、物體部件等高層特徵,最後的網絡層基於這些學習到的抽象特徵表示(Representation) 做分類邏輯的學習。學習到的特徵越高層、越準確,就越有利於分類器的分類,從而獲得 較好的性能。從表示學習的角度來理解,卷積神經網絡通過層層堆疊來逐層提取特徵,網 絡訓練的過程可以看成特徵的學習過程,基於學習到的高層抽象特徵可以方便地進行分類 任務。

應用表示學習的思想,訓練好的卷積神經網絡往往能夠學習到較好的特徵,這種特徵 的提取方法一般是通用的。比如在貓、狗任務上學習到頭、腳、身軀等特徵的表示,在其 它動物上也能夠一定程度上使用。基於這種思想,可以將在任務 A 上訓練好的深層神經網 絡的前面數個特徵提取層遷移到任務 B 上,只需要訓練任務 B 的分類邏輯(表現爲網絡的 最末數層),即可取得非常好的效果,這種方式是遷移學習的一種,從神經網絡角度也稱爲 網絡微調(Fine-tuning)。

可以觀察到,通過循環移動感受野的方式並沒有改變網絡層可導性,同時梯度的推導也並 不復雜,只是當網絡層數增大以後,人工梯度推導將變得十分的繁瑣。不過不需要擔心, 深度學習框架可以幫我們自動完成所有參數的梯度計算與更新,我們只需要設計好網絡結 構即可。

 

參數標準化很難從理論 層面解釋透徹

網絡層輸入𝑥分佈相近,並且分佈在較小範圍內時(如 0 附近),更有利於函數的優化。

那麼如何保證輸入𝑥的分佈相近呢?數據標準化可以實現此目的,通過數據標準化操作可以將數據𝑥映射到𝑥̂:

\hat{x} = \frac{x - \mu _{r}}{\sqrt{\sigma _{r}^{2} + \epsilon }}     公式1

\hat{x} = \frac{x - \mu _{r}}{\sqrt{\sigma _{r}^{2} + \epsilon }}

\mu _{r}\sigma _{r}^{2}來自統計的所有數據的均值和方差。\epsilon是爲防止出現除 0 錯誤而設置的較小數字,如 e−8。

在基於 Batch 的訓練階段,如何獲取每個網絡層所有輸入的統計數據𝜇𝑟、𝜎𝑟2呢?

\mu _{B} = \frac{1}{m}\sum_{m}^{i = 1}x_{i}     公式2

\sigma _{B}^{2} = \frac{1}{m}\sum_{m}^{i = 1}(x_{i} - \mu _{B})^{2}    公式3

所以在訓練階段,通過公式1標準化輸入,並記錄每個Batch的期望與方差,

實際上,爲了提高 BN 層的表達能力,BN 層作者引入了“scale and shift”技巧,將𝑥̂變量再次映射變換:

𝑥̃ = 𝑥̂ ∙ 𝛾 + 𝛽

𝛾參數實現對標準化後的𝑥̂再次進行縮放,𝛽參數實現對標準化的𝑥̂進行平移,不同的 是,𝛾、𝛽參數均由反向傳播算法自動優化,實現網絡層“按需”縮放平移數據的分佈的目的。

訓練階段:

𝜇𝑟 ←momentum∙𝜇𝑟 +( −momentum)∙𝜇𝐵

𝜎𝑟2 ← momentum ∙ 𝜎𝑟2 + ( − momentum) ∙ 𝜎𝐵2

迭代更新全局訓練數據的統計值𝜇𝑟和𝜎𝑟2,其中 momentum 是需要設置一個超參數,用於平 衡𝜇𝑟、𝜎𝑟2的更新幅度:當momentum= 時,𝜇𝑟和𝜎𝑟2直接被設置爲最新一個Batch的𝜇𝐵 和𝜎𝐵2;當momentum= 時,𝜇𝑟和𝜎𝑟2保持不變,忽略最新一個Batch的𝜇𝐵和𝜎𝐵2,在 TensorFlow 中,momentum 默認設置爲 0.99。

測試階段:

計算輸出𝑥̃ ,其中𝜇 、𝜎 2、𝛾、𝛽均來自訓練階段統計或優化的結果,在測試階段直接使用,並不會更新這些參數。

普通的卷積層爲了減少網絡的參數量,卷積核的設計通常選擇較小的 × 和3×3感受 野大小。小卷積核使得網絡提取特徵時的感受野區域有限,但是增大感受野的區域又會增 加網絡的參數量和計算代價,因此需要權衡設計。

空洞卷積(Dilated/Atrous Convolution)的提出較好地解決這個問題,空洞卷積在普通卷 積的感受野上增加一個 Dilation Rate 參數,用於控制感受野區域的採樣步長,如下圖 10.51 所示:當感受野的採樣步長 Dilation Rate 爲 1 時,每個感受野採樣點之間的距離爲 1,此時的空洞卷積退化爲普通的卷積;當 Dilation Rate 爲 2 時,感受野每 2 個單元採樣一 個點,如圖 10.51 中間的綠色方框中綠色格子所示,每個採樣格子之間的距離爲 2;同樣 的方法,圖 10.51 右邊的 Dilation Rate 爲 3,採樣步長爲 3。儘管 Dilation Rate 的增大會使 得感受野區域增大,但是實際參與運算的點數仍然保持不變。

以輸入爲單通道的 × 張量,單個3×3卷積核爲例,如下圖10.52所示。在初始位 置,感受野從最上、最右位置開始採樣,每隔一個點採樣一次,共採集 9 個數據點,如圖 10.52 中綠色方框所示。這 9 個數據點與卷積核相乘運算,寫入輸出張量的對應位置。

 

卷積核窗口按着步長爲𝑠 = 向右移動一個單位,如圖 10.53 所示,同樣進行隔點採 樣,共採樣 9 個數據點,與卷積核完成相乘累加運算,寫入輸出張量對應位置,直至卷積 核移動至最下方、最右邊位置。需要注意區分的是,卷積核窗口的移動步長𝑠和感受野區域 的採樣步長 Dilation Rate 是不同的概念。

空洞卷積在不增加網絡參數的條件下,提供了更大的感受野窗口。但是在使用空洞卷 積設置網絡模型時,需要精心設計 Dilation Rate 參數來避免出現網格效應,同時較大的 Dilation Rate 參數並不利於小物體的檢測、語義分割等任務。

轉置卷積通過在輸入之間填充大量的 padding 來 實現輸出高寬大於輸入高寬的效果,從而實現向上採樣的目的,

轉置卷積並不是普通卷積的逆過程,但是二者之間有一定的聯繫,同時轉置卷積也是 基於普通卷積實現的。在相同的設定下,輸入𝒙經過普通卷積運算後得到𝒐 = Conv(𝒙),我 們將𝒐送入轉置卷積運算後,得到𝒙′ = ConvTranspose(𝒐),其中𝒙′ ≠ 𝒙,但是𝒙′與𝒙形狀相 同。

深度殘差網絡並沒有增加新的網絡層類型,只是通過在輸入和輸出之間添加一條 Skip Connection,因此並沒有針對 ResNet 的底層實現。在 TensorFlow 中通過調用普通卷積層即 可實現殘差模塊。

循環神經網絡:

卷積神經網絡利用數據的局部相關性和權值共享的思想大大減少了網絡的參數量,非 常適合於圖片這種具有空間(Spatial)局部相關性的數據,已經被成功地應用到計算機視覺領 域的一系列任務上。自然界的信號除了具有空間維度之外,還有一個時間(Temporal)維度。 具有時間維度的信號非常常見,比如我們正在閱讀的文本、說話時發出的語音信號、隨着 時間變化的股市參數等。這類數據並不一定具有局部相關性,同時數據在時間維度上的長 度也是可變的,卷積神經網絡並不擅長處理此類數據。

那麼如何解決這一類信號的分析、識別等問題是將人工智能推向通用人工智能路上必 須解決的一項任務。本章將要介紹的循環神經網絡可以較好地解決此類問題。在介紹循環 神經網絡之前,首先我們來介紹對於具有時間先後順序的數據的表示方法。

具有先後順序的數據一般叫作序列(Sequence),比如隨時間而變化的商品價格數據就是 非常典型的序列。

我們已經知道神經網絡本質上是一系列的矩陣相乘、相加等數學運算,它並 不能夠直接處理字符串類型的數據。如果希望神經網絡能夠用於自然語言處理任務,那麼 怎麼把單詞或字符轉化爲數值就變得尤爲關鍵。接下來我們主要探討文本序列的表示方 法,其他非數值類型的信號可以參考文本序列的表示方法。

我們把文字編碼爲數值的過程叫作 Word Embedding。One-hot 的編碼方式實現 Word Embedding 簡單直觀,編碼過程不需要學習和訓練。但是 One-hot 編碼的向量是高維度而 且極其稀疏的,大量的位置爲 0,計算效率較低,同時也不利於神經網絡的訓練。

從語義 角度來講,One-hot 編碼還有一個嚴重的問題,它忽略了單詞先天具有的語義相關性。舉個 例子,對於單詞“like”、“dislike”、“Rome”、“Paris”來說,“like”和“dislike”在語義角 度就強相關,它們都表示喜歡的程度;“Rome”和“Paris”同樣也是強相關,他們都表示 歐洲的兩個地點。對於一組這樣的單詞來說,如果採用 One-hot 編碼,得到的向量之間沒 有相關性,不能很好地體現原有文字的語義相關度,因此 One-hot 編碼具有明顯的缺陷。

在自然語言處理領域,有專門的一個研究方向在探索如何學習到單詞的表示向量(Word Vector),使得語義層面的相關性能夠很好地通過 Word Vector 體現出來。一個衡量詞向量之 間相關度的方法就是餘弦相關度(Cosine similarity):

similarity(a, b) = cos(\theta ) = \frac{a \cdot b}{|a|\cdot|b|}

similarity(a, b) = cos(\theta ) = \frac{a \cdot b}{|a|\cdot|b|}

其中𝒂和𝒃代表了兩個詞向量。下圖演示了單詞“France”和“Italy”的相似度,以及單 詞“ball”和“crocodile”的相似度,𝜃爲兩個詞向量之間的夾角。可以看到cos(𝜃)較好地 反映了語義相關性。

所以詞向量是怎麼來的?

在神經網絡中,單詞的表示向量可以直接通過訓練的方式得到,我們把單詞的表示層 叫作 Embedding 層。Embedding 層負責把單詞編碼爲某個詞向量𝒗,它接受的是採用數字 編碼的單詞編號𝑖,如 2 表示“I”,3 表示“me”等,系統總單詞數量記爲𝑁vocab,輸出長 度爲𝑛的向量𝒗: 𝒗 = 𝑓 (𝑖|𝑁 , 𝑛)

Embedding 層的查詢表是隨機初始化的,需要從零開始訓練。實際上,我們可以使用 預訓練的 Word Embedding 模型來得到單詞的表示方法,基於預訓練模型的詞向量相當於 遷移了整個語義空間的知識,往往能得到更好的性能。

目前應用的比較廣泛的預訓練模型有 Word2Vec 和 GloVe 等。它們已經在海量語料庫 訓練得到了較好的詞向量表示方法,並可以直接導出學習到的詞向量表,方便遷移到其它 任務。

那麼如何使用這些預訓練的詞向量模型來幫助提升 NLP 任務的性能?非常簡單,對於 Embedding 層,不再採用隨機初始化的方式,而是利用我們已經預訓練好的模型參數去初始化 Embedding 層的查詢表。

經過預訓練的詞向量模型初始化的 Embedding 層可以設置爲不參與訓練:net.trainable = False,那麼預訓練的詞向量就直接應用到此特定任務上;如果希望能夠學到區別於預訓 練詞向量模型不同的表示方法,那麼可以把 Embedding 層包含進反向傳播算法中去,利用 梯度下降來微調單詞表示方法。

現在我們來考慮如何處理序列信號,以文本序列爲例,考慮一個句子:

“I hate this boring movie”

通過 Embedding 層,可以將它轉換爲 shape 爲[𝑏, 𝑠, 𝑛]的張量,𝑏爲句子數量,𝑠爲句子長 度,𝑛爲詞向量長度。上述句子可以表示爲 shape 爲[1,5,10]的張量,其中 5 代表句子單詞 長度,10 表示詞向量長度。

情感分類任務通過分析給出的文本序列,提煉出文本數據表達的整 體語義特徵,從而預測輸入文本的情感類型:正面評價或者負面評價。從分類角度來看, 情感分類問題就是一個簡單的二分類問題,與圖片分類不一樣的是,由於輸入是文本序 列,傳統的卷積神經網絡並不能取得很好的效果。

首先我們想到的是,對於每個詞向量,分別使用一個全連接層網絡

𝒐 = 𝜎(𝑾𝑡𝒙𝑡 + 𝒃𝑡)

提取語義特徵,如圖 11.4 所示,各個單詞的詞向量通過𝑠個全連接層分類網絡 1 提取每個 單詞的特徵,所有單詞的特徵最後合併,並通過分類網絡 2 輸出序列的類別概率分佈,對 於長度爲𝑠的句子來說,至少需要𝑠個全網

絡層。

缺點:

網絡參數量是相當可觀的,內存佔用和計算代價較高,同時由於每個序列的長度𝑠並不 相同,網絡結構是動態變化的

每個全連接層子網絡𝑾𝑖和𝒃𝑖只能感受當前詞向量的輸入,並不能感知之前和之後的語 境信息,導致句子整體語義的缺失,每個子網絡只能根據自己的輸入來提取高層特 徵,有如管中窺豹。

所以需要去解決。

上面𝑠個全連接層的網絡並沒有實現權值同享。我們嘗試將這𝑠個網絡層 參數共享,這樣其實相當於使用一個全連接網絡來提取所有單詞的特徵信息

通過權值共享後,參數量大大減少,網絡訓練變得更加穩定高效。但是,這種網絡結 構並沒有考慮序列之間的先後順序,將詞向量打亂次序仍然能獲得相同的輸出,無法獲取 有效的全局語義信息。

如何賦予網絡提取整體語義特徵的能力呢?或者說,如何讓網絡能夠按序提取詞向量 的語義信息,並累積成整個句子的全局語義信息呢?我們想到了內存(Memory)機制。如果 網絡能夠提供一個單獨的內存變量,每次提取詞向量的特徵並刷新內存變量,直至最後一 個輸入完成,此時的內存變量即存儲了所有序列的語義特徵,並且由於輸入序列之間的先 後順序,使得內存變量內容與序列順序緊密關聯。

 

我們將上述Memory機制實現爲一個狀態張量,如圖11.6所示,除了原來的𝑾 參數共享外,這裏額外增加了一個𝑾 參數,每個時間戳𝑡上狀態張量 刷新機制爲:

h𝑡=𝜎(𝑾 𝒙𝑡+𝑾 𝑡−1+𝒃)

其中狀態張量 爲初始的內存狀態,可以初始化爲全0,經過𝑠個詞向量的輸入後得到網絡最終的狀態張量 𝑠, 𝑠較好地代表了句子的全局語義信息,基於 𝑠通過某個全連接層分類器即可完成情感分類任務。

通過一步步地探索,我們最終提出了一種“新型”的網絡結構,如圖 11.7 所示,在每個時間戳𝑡,網絡層接受當前時間戳的輸入𝒙𝑡和上一個時間戳的網絡狀態向量 h𝑡−1,變換後得到當前時間戳的新狀態向量 ,並寫入內存狀態中,其中𝑓 代表了網絡的運算邏輯,𝜃爲網絡參數集。

在循環神經網絡中,激活函數更多地採用 tanh 函數,並且可 以選擇不使用偏執𝒃來進一步減少參數量。狀態向量 𝑡可以直接用作輸出,即𝒐𝑡 = h𝑡,也 可以對 𝑡做一個簡單的線性變換𝒐𝑡 = 𝑊 𝑜 𝑡後得到每個時間戳上的網絡輸出h𝒐𝑡。

需要注意的是,在 TensorFlow 中,RNN 表示通用意義上的循環神經網絡,對於我們 目前介紹的基礎循環神經網絡,它一般叫做 SimpleRNN。SimpleRNN 與 SimpleRNNCell 的 區別在於,帶 Cell 的層僅僅是完成了一個時間戳的前向運算,不帶 Cell 的層一般是基於 Cell 層實現的,它在內部已經完成了多個時間戳的循環運算,因此使用起來更爲方便快 捷。

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章