# 自然語言處理 02:RNN、LSTM、seq2seq ###### tags: `NLP` ## 本篇都用 "You say goodbye and I say hello." 為例 ## 1. RNN ### 1-1. 語言模型 語言模型是針對字詞排列給予機率,也就是用機率評估字詞排列有多自然。若要把 CBOW 模型套用到語言模型中(通常不會),則必須指定上下文的長度,若超過此長度模型則會忽略,因此無法獲得長時間的資訊;此外 CBOW 會在中間層會計算詞向量的和,忽略上下文的順序。為了解決這個問題就會用到 RNN。 <font size=4>$$h_t = tanh(h_{t-1}W_h+x_tW_x+b)$$</font> <br> ### 1-2. Backpropagation Through Time(BRTT) RNN 進行反向傳播時,會往時間方向展開類神經網路,也稱作 BPTT,但此法必須將各時刻 RNN 層的中間資料儲存在記憶體內,消耗的運算資源會正比於時間序列的大小。 <br> ### 1-3. Truncated BRTT Truncated BRTT 是會切斷長時間軸的反向傳播法,藉由截斷過長的類神經網路反向傳播鍊,針對每個小型神經網路做反向傳播。  此做法有兩個好處: 1. 降低梯度消失發生機率 2. 降低運算量及記憶體使用量 <br> ### 1-4. RNN Language Model(RNNLM) 使用 RNN 的語言模型稱作 RNN Language Model,並以每個 Batch 的加總平均作為 loss。第一層是 Embedding 層,把字詞轉換成分散式向量,再把詞向量傳遞給 RNN 層,最後經過 Affine 層傳遞給 Softmax 層。如此一來可以記憶目前為止輸入過的資訊,並預測下一個字詞。  <br> ### 1-5. 評估語言模型 語言模型會用過去提供的資料,輸出下一個出現字詞的機率分布,並常用**困惑度**當作指標。 困惑度代表機率的倒數,數值越小越精準,舉例來說:假設下一個出現的字為 "say",模型一預測出的機率為 0.8,可以計算出困惑度為 1.25;模型二預測出的機率為 0.2,則困惑度為 5。另外也可以以分歧數解釋:良好模型的分歧數是 1.25,代表下一個出現的候選答案是一個,而不良模型則有五個。 當輸入多個資料時,則將所有資料以下方公式求出 L 並取平均後計算困惑度。 <font size=4>$$L = - \frac{1}{N} \sum\limits_n\sum\limits_k t_{nk} \space \log y_{nk}$$</font> <font size=4>$$perplexity = e^L$$</font> 其中資料為 $N$ 個,$t_n$ 是 one-hot 的正確標籤,$t_{nk}$ 是第 n 個資料的第 k 個值,$y_{nk}$ 代表機率分布,$L$ 為神經網路的 loss,$e^L$ 為困惑度。 <br> --- ## 2. LSTM 傳統 RNN 使用 tanh(x) 當作激活函數,而 $y = tanh(x)$ 的微分是 $\frac{dx}{dy} = 1-y^2$,其曲線如下:  其數值幾乎都在 1.0 以下,因此代表在反向傳播時,梯度每次通過 tanh 就會逐漸變小,造成梯度消失。而 RNN 隨著時間回溯,幾乎都會走向梯度消失或梯度爆炸。 - 梯度爆炸 可使用梯度剪裁,當梯度的 L2 norm 高於某一個閥值時,透過下列方式修正梯度: <font size=4>$$\hat g = \frac{threshold}{||\hat g||}\hat g$$</font> 須注意 LSTM 無法解決梯度爆炸問題。 - 梯度消失 若要改善時間方向的梯度消失,可以使用 LSTM/GRU,若要改善深度方向的梯度消失,可以使用殘差連接。 <br> ### 2-1. 記憶單元 RNN 和 LSTM 的差異在於 LSTM 含有 **記憶單元 $c$**,記憶單元只在 LSTM 層內傳遞資料,不會輸出給其他層,外面也看不到 $c$。  <br> ### 2-2. 輸出閘門 **輸出閘門可以解釋成上一時刻的隱藏狀態有多重要**。是由輸入 $x_t$ 乘上 $W_x^o$ 及上一個隱藏狀態 $h_{t-1}$ 乘上 $W_h^o$ 計算出來,再加上偏權值 $b^o$ 後,通過 sigmoid 輸出 $o$,<font color="#f00">**用來代表輸出的重要程度**</font> <font size=4>$$o = sigmoid(x_tW_x^o + h_{t-1}W_h^o + b^o)$$</font> 最後乘上 $tanh(c_t)$ 輸出 $h_t$ <font size=4>$$h_t = o \times tanh(c_t)$$</font>  <br> ### 2-3. 遺忘閘門 **遺忘閘門可以解釋成要忘記上一層的什麼資訊**。是由輸入 $x_t$ 乘上 $W_x^f$ 及上一個隱藏狀態 $h_{t-1}$ 乘上 $W_h^f$ 計算出來,再加上偏權值 $b^f$ 後,通過 sigmoid 輸出 $f$,<font color="#f00">**用來代表資料遺忘程度**</font> <font size=4>$$f = sigmoid(x_tW_x^f + h_{t-1}W_h^f + b^f)$$</font> 最後乘上 $c_{t-1}$ 輸出 $c_{t}$ <font size=4>$$c_t = f \times c_{t-1}$$</font>  <br> ### 2-4. 新的記憶單元 只使用遺忘閘門會導致只會遺忘資訊,而不會增加新資訊,因此加入新的記憶單元。是由輸入 $x_t$ 乘上 $W_x^g$ 及上一個隱藏狀態 $h_{t-1}$ 乘上 $W_h^g$ 計算出來,再加上偏權值 $b^g$ 後,通過 tanh 輸出 $g$,<font color="#f00">**用來代表輸出的重要程度**</font> <font size=4>$$g = tanh(x_tW_x^g + h_{t-1}W_h^g + b^g)$$</font> 加上原本的通過遺忘層的資訊 $f \times c_{t-1}$ 輸出 $c_{t}$ <font size=4>$$c_t = f \times c_{t-1} + g $$</font>  <br> ### 2-5. 輸入閥門 **針對新增的記憶單元新增輸入閘門,用來判斷新資訊的價值**。是由輸入 $x_t$ 乘上 $W_x^i$ 及上一個隱藏狀態 $h_{t-1}$ 乘上 $W_h^i$ 計算出來,再加上偏權值 $b^i$ 後,通過 sigmoid 輸出 $g$,<font color="#f00">**用來代表輸出的重要程度**</font> <font size=4>$$i = sigmoid(x_tW_x^i + h_{t-1}W_h^i + b^i)$$</font> 最後乘上 $g$ 加上上一層經過遺忘閘門後的資訊輸出最終 $c_{t}$ <font size=4>$$c_t = f \times c_{t-1} + g \times i$$</font>  <br> ### 2-5. LSTM 語言模型 此時可以用 LSTM 替換 RNNLM 內傳統 RNN cell,改善梯度消失,另外可以用三種方式改良此模型: 1. 堆疊多層 LSTM 2. 在深度方向使用 Dropout 3. 在 Embedding 層和 Affine 層使用相同權重,減少學習參數並控制 Overfitting <br> ### 2-6. 用 RNN 產生文章 語言模型會從目前提供的字詞中,輸出下一個單字的機率分布,而挑選字詞有兩種方法: 1. 挑選機率最高的字詞,此法的結果只有一個 2. 隨機以該機率分布挑選字詞,此法的結果每次都可能改變 <br> ## 3. seq2seq seq2seq 也稱為 Encoder-Decoder 模型,Encoder 是將輸入資料編碼,Decoder 是將編碼後的資料解碼。Encoder 先利用 RNN 將任意時間序列資料轉換成固定長度的隱藏狀態向量 h,再將其當作 Decoder 的輸入用來轉換成字詞。   然而單純使用 seq2seq 模型處理加法問題準確度僅 10% 左右,因此需要其他改良方式。 <br> ### 3-1. 反轉輸入資料 未反轉的序列,訊息可能在 encode 過程中遺失,當第一個輸出錯了,後面也會跟著錯。因此反轉輸入資料的順序,使輸入內容的開頭部分與有對應關係的輸出部分距離變近,比較容易傳遞梯度,提高學習效率,此種方法也不會改變平均的字詞距離。 舉例來說,輸入為 ABC_,輸出為XYZ_,A 對應到 X,且相距 4 步(A-B-C-_-X),平均也是 4 步;反轉後 _CBA,則 A 對應到 X,且相距 1 步(A-X),以此類推,平均距離仍為 4 步。 應用到加法資料準確度為 60%。 <br> ### 3-2. 窺伺(Peeky) 傳統 Decoder 僅將 h 傳遞給第一個時刻的 LSTM,窺伺(Peeky)則是將其提供給 Decoder 的其他層。 應用到加法資料準確度接近 100%。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up