## Language model 的演進 ### 1. N-Gram language modeling 語言模型,可以透過考慮前面 i - 1 個字並輸出第 i 個字,但在 N-Gram language modele 中僅考慮輸出第 i 個字之前的 n 個字,其餘更前面的文字皆忽略不看,並且從訓練資料(training data)中預測下一個字的機率。 但是存在一個問題,如果在訓練資料中沒有對應的資料,那機率永遠是零,例如訓練資料有兩筆資料是狗在跑、貓在叫,請問出現狗在叫的機率是多少呢?沒錯,就是零。為了避免這種狀況,通常會給予一個小的機率值 = 0.0001,這個動作叫做 smoothing,但這樣的機率往往是不準確的。 ![image](https://hackmd.io/_uploads/r1cFKCzSC.png) ### 2. Neural Language modeling 在 Neural network 中,先準備好大量訓練資料,一開始先丟入輸入 "START" 的 vector,代表正式開始訓練並且期望輸出 "wreck",再將輸出當成輸入丟到 NN 中,期望產生新的輸出 "a",以此類推。 這些丟入的輸入向量,如果說在 Word representation 中的關係是接近的,即使訓練資料中只有狗在跑、貓在叫,因為貓跟狗的關係是接近的,所以出現狗在叫的機率也不會是零,等於是自動完成 smoothing 的效果。 但也是要考慮到有可能第一個字與第十個字有關,或者與第一百個字有關,而目前的 Neural Language modeling 僅能考慮固定的 Window 裡的字,例如 window = 1 僅考慮前一個字輸出下一個字,而無法考慮到更多的字。 ![image](https://hackmd.io/_uploads/Sk8D20fSC.png) ### 3. Recurrent Neural Network Language Model, RNNLM 利用 RNNLM 就能夠解決固定 window 的問題,最主要的差異在於能將過往的資訊傳遞給下一層的隱藏層,便能在後面輸出第十或一百個字時,也能考慮到之前的文字,進而預測出較佳的輸出結果,這便是 RNNLM 的優點。 ![image](https://hackmd.io/_uploads/HknpJJXBC.png) ## 介紹 RNNLM RNNLM 具體運作流程如下圖,考慮前一個隱藏層的向量(hₜ₋₁)以及輸入向量(xₜ),並且乘上對應的矩陣 W、U,得到 sₜ₋₁ 再乘上 V 矩陣得到輸出 oₜ₋₁,以此類推。 ![image](https://hackmd.io/_uploads/B1AqtOrBR.png) ### 不同的 RNN 架構 ![image](https://hackmd.io/_uploads/rkSW-buo1e.png) ![image](https://hackmd.io/_uploads/HyLlbW_j1g.png) :::info Bidirectional RNN,同時考慮左側以及右側的資訊。 ![image](https://hackmd.io/_uploads/S1y9HYBHR.png) Deep Bidirectional RNN ![image](https://hackmd.io/_uploads/SJql8KHHC.png) ::: ## Backpropagation Through Time 為什麼要加上 through time 呢?這是因為 RNNLM 的特色是有時序性,必須要等到上一個輸出結果結束後作為輸入,才能再輸出下一個,存在時間先後順序的差異,因此被稱為 Backpropagation Through Time。 以下圖片出自於「[Gadient descent & Backpropagation](https://hackmd.io/@lcaMuWOwR1Ox5o5yeTEupA/SJCapzVSR)」的文章,根據後一層(δˡ⁺¹)的結果推算出前一層(δˡ)的結果,但這樣的最佳化方式,可能存有兩個潛藏的問題,分別是 Vanishing gradient 以及 Exploding gradient,因為會一直乘上相同的矩陣 w,可以想像成一直乘上比 1 大(例如 2)的數字結果會越來越大,反之一直乘上比 1 小(例如 0.5)的數字結果會越來越小。 ![image](https://hackmd.io/_uploads/HJXwaQVrA.png) ### 什麼是 Vanishing gradient 以及 Exploding gradient? 從下方兩張圖可以看到,在更新參數 50 次後,會變得相當極端,只出現在非常接近於零(非常平緩)的地方,代表 Vanishing gradient,也會出現在非常大的數值(非常陡峭),代表 Exploding gradient。 ![image](https://hackmd.io/_uploads/S15nCOSSR.png =40%x) ![image](https://hackmd.io/_uploads/SyQRR_HH0.png =50%x) ### 解決 Exploding gradient 的方式 - 梯度剪裁 需要先設定閥值(threshold),然後在梯度大於該閥值時縮小梯度。 #### 1. 按值裁減,定義梯度的最小和最大閾值 ex: 更新參數後的梯度計算為 [0.9, -1.4, 5.2],將裁切閾值設為 -1 和 1 時,調整後的梯度將變為 [0.9, -1, 1]。 #### 2. 按比例裁減,梯度按比例縮小以與該閾值對齊 ex: 更新參數後的梯度計算為 [1.6, 0.6, 1.8],將裁切閾值設為 1 且縮放因子為 0.5 時,調整後的梯度將變為 [0.8, 0.6, 0.9]。 ### 解決 vanishing gradient 的方式 - Gating #### 1. Long Short-Term Memory (LSTM) 與 Vanilla RNN 最大差別在於,具有一個上方通道只做 Linear transform(加、乘之運算),不做任何數值壓縮導致消失,能夠確保資訊一直被保留下來,並且 LSTM 擁有三個 gate,分別是 forget gate、input gate 以及 output gate。 a. forget gate:決定要遺忘(或丟棄)哪些過去資訊,若 fₜ = 1 則完全保留,fₜ = 0 則完全遺忘。 b. input gate:決定哪些新的輸入資訊可以更新在 cell state 中。 c. output gate:決定哪些資訊可以作為輸出。 :::info Cell state update,同時考慮 forget gate 以及 input gate,決定遺忘哪些資訊並且新增哪些資訊,藉由 fₜ 與 iₜ 控制每一次的遺忘與更新,讓 Cₜ 可以保有我們所需要的資訊。 ::: ![image](https://hackmd.io/_uploads/SkeN2hIBR.png) #### 2. Gated Recurrent Unit (GRU) 相較於 LSTM,GRU 只有兩個 gate,分別是 update gate 以及 reset gate。 a. update gate:結合 forget gate 和 input gate b. reset gate 特別注意的地方在於 rₜ * hₜ₋₁,當 rₜ = 0 代表完全忽略先前的資訊,只儲存新資訊。 ![image](https://hackmd.io/_uploads/SkYE33LSA.png) :::info LSTM v.s. GRU 由於 GRU 少了一個 gate,因此參數量是較少的,在更新參數上會比 LSTM 快,但如果有非常大量的資料,還是建議使用 LSTM 較能夠幫助模型表現得更好。 ::: ## 總結 RNN 在文章中,我們提到了 Language Model 的演進,說明 RNN 能夠考慮先前的資料,因此在預測下一個字的輸出結果較良好,但也由於資訊不斷地往下傳遞,存在了最佳化(Optimization)的問題,就是 Vanishing gradient 以及 Exploding gradient,並且針對這兩種情境介紹了對應的解決方法。 --- :::info 以上就是這篇文章「循環神經網絡(Recurrent Neural Network, RNN)」的所有內容,第一次看的人會花比較多時間消化吸收,這是很正常的事情,若有任何問題,歡迎在下方與我聯繫、討論,接下來也會繼續分享相關文章,敬請期待。