機器學習筆記 — Recurrent Neural Network(RNN) Part I

Ginny Hsieh
13 min readFeb 4, 2023

--

source:李宏毅教授影片

李宏毅教授的影片很精彩 :D))

應用說明:

  1. 智慧訂票系統:
    需要 Slot filling,在這個訂票系統中有兩個 slot 叫Destination & Time of arrival. 這個系統要知道這個人講的這段話,其中的每一個詞彙它屬於哪一個 Slot。
  • Ex: Taipei 屬於 Destination 這個 slot。 November 2nd 屬於 Time of arrival, 其他詞彙就不屬於任何 slot。

Q. 這個問題要如何解:

  1. Feedforward Neural Network 來解 Slot filling:

Input: a word

Ex: 將 Taipei 作為一個 Vector,丟到 Network 中。

  • 其中將字彙轉換成 Vector 的方式很常見,使用 1-of-N encoding,但在這之中,需要如下圖左邊加入 other 的選項,其他我們不 care 的字彙就會被歸類到此項中。
  • 也可以用某個詞彙的字母的 n-gram 來表示 Vector,則不會有歸類落空的問題。

Output:
Probability distribution hat the input word belonging to the slots
(此 input 屬於每一個 slot 的機率)

但對於訂票機制來說有一個問題,如下圖所示
對於 arrive Taipei 來說,Taipei 是目的地 destination,
但對於 leave Taipei 來說,Taipei 是出發地 place of departure
但對模型來說 它不管前面 input 的動詞是什麼,Taipei 對它來說 output 就是destination。

所以我們會需要模型是有記憶力的

記得在看到Taipei前它記得他是看過什麼動詞 arrive or leave,這樣就可以解決 input 同樣的字彙,但 output 是不同的問題。

Recurrent Neural Network(RNN)

終於進入正題,這種有記憶力的神經網路稱為 Recurrent Neural Network(RNN)。

  • 在 RNN 裡,每一次 hidden layer 裡面的 neuron 產生 output 時,都會被存到 memory 裡,如下圖所示,用藍色的方塊表示 memory。
  • 當下一次有input 時,hidden layer 裡的 neuron 不會只考慮 input 的 x1 & x2 ,它還會考慮存在 memory 裡的值。也就是說 a1 & a2 也會影響到他的 Output。

Example:

假設下圖的這個 Network 它所有的 weight 都是 1,所有的 neuron 都沒有任何的 bias 值,假設所有的 activation function 都是 linear。

Steps:

  1. 初始 memory value 0, 0
  2. 所以對於左邊綠色的 neuron 來說,它不只接到 input [1, 1],它還接到來自 memory [0, 0]。所以左右的 綠色 neuron 都是2 ,再來紅色的neuron 都是 4,所以整個模型 output 就是 [4, 4]。
  3. 模型執行結束後,將綠色的 neuron 值存到 memory 裡面去。所以memory 值變成 [2, 2]。
  4. 下一輪,input [1, 1],綠色 [6, 6],紅色[12, 12]。
  5. 更新藍色 [6, 6]。
  6. 重複 1–2 步驟。

RNN 會考慮 Input sequence 順序

做 RNN 時有一件重要的事,input sequence 並非 independent,也就是說當我把例子中的input 不同組 [x1, x2] 順序顛倒時,像是[2, 2] 移到 [1, 1] 前面時,output 會完全不同。

使用 RNN 來處理 Slot filling

首先說明一個使用者的例子

Ex: 一個使用者說 “arrive Tapei on November 2nd

Steps:

  1. arrive 變成一個 vector,作為 input x1, hidden layer neuron a1, 產生output y1 代表 ”arrive” 在每個 slot 的機率。最後 a1 存到藍色 memory 裡面。
  2. Taipei 作為 vector 進到 input x2,此時的 hidden layer neuron a2 會同時考慮到 x2 及 memory 中的 a1,得到 a2,再產生 y2 代表 “Taipei” 在每個slot 中的機率。最後 a2 存到藍色 memory 裡面。
  3. 後續重複 1–2步驟執行。

注意:這邊不是三個 Networks, 是同一個 Network,在三個時間點被使用了3次。

Ex: Arrive Tapei on November 2nd

用下圖來說明兩個動詞 arrive & leave 在 RNN 中產生不同 output。

  • 同樣是輸入 Taipei ,但紅色台北前面接 leave,綠色台北前面接 arrive,兩邊動詞輸入的 vector 不同,所以各自的 hidden layer output 也不同,所以存在 memory 裡的值 a1 也不同。所以進而影響到 Taipei 的 hidden layer ouput a2 & y2 會產生不同的結果。

RNN 架構

講完以上 RNN 基本觀念,RNN 架構是可以任意設計的。

可以deep 很多hidden layer 的RNN:

可以為 deep 代表多個 hidden layers,每個的hidden layers 都會被存在memory 裡面,下一個時間點會再把前一個時間點存的值讀出來作為參考,如下圖所示,這個過程就一直持續下去。

可以deep 很多hidden layer 的RNN

RNN 有不同的變形:

  1. Elman Network:把 hidden layer 的值存起來,然後在下一個時間點讀出來。
  2. Jordan Network:存的是整個 Network 的 output 值,然後在下一個時間點讀到hidden layer 裡。
  • 兩者的比較:
    傳說 Jordan 可以得到比較好的 performance,因為 Elman 的 hidden layer 是沒有 target 的,比較難控制它學到什麼樣的 hidden information,難控制它把什麼放在 memory。
  • 但 Jordan 的 y 是有 target 的,我們就可以比較清楚知道他放在memory 裡的是怎麼樣的東西。

Bidirectional RNN(雙向的)

剛剛介紹的 RNN,都是 input 一個句子,它就從句首一直讀到句尾。但是他的讀取方向也可以是反過來的。

如下圖所示,我們可以同時 train 一個正向的 RNN,及一個逆向的 RNN,然後把這兩個 RNN 的 hidden layer 拿出來,都接給一個 output layer,得到最後的 y。

好處:你的 network 在產生 output 時,它看的範圍比較廣。
只有使用正向的 RNN 時,產生 y^t & y^(t+1) 時,你的 network 只看過 x1 到 x^(t+1) 的部份。

但如果我們今天是 Bidirectional RNN ,在產生 y^(t+1) 的時候,你的 network 不只看了 x1 到 x^(t+1) 的部份,它也看了句尾一直到 x^(t+1) 的部份。也就等於說,你的網路是看了整個 sentence 以後,才決定每一個詞會的 slot 應該是甚麼,當然會比只看一半句子得到更好的 performance。

最 Simple 的版本

Long Short-term Memory(LSTM)

剛剛提到最簡單的版本,就是memory 可以隨時存隨時讀,但現在比較常用的 memory 稱之為 Long Short-term Memory(LSTM)。

LSTM 它有三個 gates:

  • Input Gate:當外界某個 neuron 的 ouput 想要被寫到 memory cell 的時候,它必須先通過一個閘門 Input gate,當此閘門打開時你才能把值寫進memory cell。至於 Input Gate 在什麼時候打開什麼時候關起來,是neuron network 自己學的。
  • Output Gate:決定外界其他 neuron 可不可以從 memory 裡把值讀出來,與 Input Gate 相同,打開&關起來的時機由模型自己學。
  • Forget Gate:決定什麼時候 memory 要把過去記得的東西忘掉,或是它何時要把過去記得的東西做一下 format。與上面兩個 Gate 相同,format的時機由模型自己學。

總結:LSTM 有 4 個 Inputs & 一個 Output

Inputs:
1. 想要被存進 memory cell 裡的值。
2. 操控 Input gate 的訊號。
3. 操控 Output gate 的訊號。
4. 操控 Forget gate 的訊號。

Outputs:
1. memory 的值。

用更難懂一點的方式來看上述那張 LSTM 圖

  • 假設要被存進 memory cell 裡的值為 Z
    操控 Input Gate 的 signal 為 Z^i
    操控 Output Gate 的 signal 為 Z^o
    操控 Forget Gate 的 signal 為 Z^f
    Output 為 a
    假設在其他 signal 動作之前,cell 裡面存的值為 c

Q. Output a 會長什麼樣子?

  • Z 通過 activation function g 產生 g(Z)
  • Z^i 通過 activation function f 產生 f(Z^i),通常 activation function會選擇 sigmoid function,因為它產生的值是介於 0-1 之間 ,這個值代表 Gate 被打開的程度,如果值為 1 代表打開,其他值代表關起來。
  • 將 g(Z) 乘上 f(Z^i) 得到 g(Z)f(Z^i)
  • Z^f 也通過 activation function f 產生 f(Z^f),值同樣介於 0–1 之間。1 表示打開,要記得這個值 c,關起來表示遺忘 c。
  • 將 cell 裡的值 c 乘上 f(Z^f) 得到 cf(Z^f)
  • 將 cf(Z^f) 加上 g(Z)f(Z^i) 得到 c’ = g(Z)f(Z^i)+cf(Z^f)
    此 c’ 即為新的存在 memory 裡的值。
  • c’ 通過 activation function h 產生 h(c’)
  • Z^o 通過 activation function f 產生 f(Z^o)
  • 將 h(c’) 乘上 f(Z^o) 得到 a = h(c’)f(Z^o)

LSTM - Example

人體 LSTM :D)

在這個例子中,只有一個 LSTM cell
Input : 3 維 vector
Output : 1 維 vector

如下圖,在這資料中有一些條件

  • 假設 x2 = 1 時,x1 的值會被寫進 memory
  • 假設 x2 = -1 時,memory 會被 forget
  • 假設 x3 = 1 時,output 才會輸出

藍色區塊為 hidden layer neuron value
紅色區塊為 output value

實際運算:

LSTM cell 有四個 input,皆為scalar,scalar 是 input 三維的 vector 經過 linear transform 得到的值。
白話一點就是 input 分別乘上下圖中藍色灰色的值,再加上綠色的 bias。

在下面的例子中:

  • 看到 Input gate 的部份,假設 x2 沒有值的時候,此項加上 bias 值 -10 ,在通過 sigmoid function 時會接近 0的值,通常平常都是被關閉的。所以要開啟就需要x2 有正值,才能給予一個比 bias 大的值。
  • 在 Forget gate 的部份,因為 bias 值 = 10,代表平常是開啟狀態,只有在x2 有負值時,門才會關閉。
  • Output gate 與 Input gate 很像,平常都是關閉的模式,只有在 x3 有正值時,gate 才會打開。

Q. LSTM 跟原來的網路差在哪裡?

其實沒有差,只是換個角度,把hidden layer 的 neuron 換成 LSTM cell 。

  • 原來的網路(左圖)只需要一個 input 就可以產生一個 output。
  • 而 LSTM (將左圖 neuron 用 LSTM cell 替換成右圖的樣子)要有四個 input ,且都不一樣,所以 LSTM 的參數量會是一般的 NN 的 4 倍。

LSTM 架構圖

假設我們現在有一整排的 neurons,每一個 LSTM cell 裡面都存有一個 scalar 值,將所有值接在一起,就變成一個 vector c^t-1

在時間點 t, input 一個 vector x^t,

  • x^t 會先 linear transform 乘上一個 matrix 變成 vector z,其中 z 每一個 dimension (vector 中的每個元素) 就代表操控每一個對應的 LSTM cell input,所以 vector z 的長度會是剛好 LSTM cell 的數目。
  • x^t 會再乘上另一個 transform 變成vector z^i,跟 z 一樣,vector 中的每個 dimension 都對應到一個 LSTM cell。
  • 其他 z^f, z^o 皆與 z^i 相同。

所有 cell 是可以一起被共同運算的

如同上面的描述(Q. Output a 會長什麼樣子?這段) 的作法,產生下面的流程圖。

但上述只是 LSTM 的簡單版本,真正的 LSTM 會將左圖中紅圈框起來的 hidden layer 的輸出一起當作下一次的 input 。

以及右圖的所提到的peehole,是把存在 memory cell 裡的值也加入下一次的 input。

總結:LSTM 的 input 會同時考慮 x, h, c。

Multiple-layer LSTM

現在的LSTM 一層不夠,一定要多層才開心:D)

雖然第一次看到 LSTM 的人都會像右圖一樣,但 LSTM is quite standard now!

現在 Keras 支援

  • LSTM
  • GRU (LSTM 簡化版本,只有兩個 gate,據說performance 跟LSTM 差不多,但少了1/3的參數,比較不會 overfitting)
  • SimpleRNN (課堂上講的最簡單的 RNN)

--

--

Ginny Hsieh

Hello! I am Ginny. I graduated from NTUST with a major in Information Engineering. I am currently on a journey of combining my technical skills with my passion.