Sequence Models
Sequence data 指的是一連串的 data
例如訓練 input 一連串聲音 output 成文字 (speech recognition)
我們要利用例如 Recurrent Neural Network (RNN) 來建立出 sequence model
model 將幫助我們把 non-sequence/sequence data 轉換成 non-sequence/sequence data
Notation
假設有一個 name entity recognition 案例
因為 y 跟 x 的字一模一樣,所以用 1 標示是要找的人名
因為可能有多筆 training set,若要表示第 i 筆 data 的第 t 個 word
Vocabulary (Dictionary)
通常會用一整個列表記錄所有單字,一個列表可能會有 30 ~ 100000 個單字
上面的案例是一個 10000 個單字的 dictionary
接著用 one-hot 方式來呈現單字
例如 Harry 就會是一個全為 0 但 index=4075 為 1 的 10000 長度向量
Recurrent Neural Network Model
Why not standard network ?
以 Harry 例子來說,Input 9 個單字要產生 9 個 output,每個 input/output 又都是 10000 長的 one-hot vector
第一個問題
每個 training set 的 input 跟 output 會不斷改變
第二個問題
Input features 之間並沒有 share 的關係
Recurrent Neural Network 沒有這些問題
RNNs
之後會談到雙向的 RNNs (Bidirectional RNNs)
所有的 neural networks 會共享三大參數
命名的規則 (已 ax 為例) : 跟 x 作用並產生 a
第一個 activation function 可選擇 tanh 或 ReLU
第二個 activation function 可選擇 sigmoid 或 softmax
Simplify Forward Propogation
為了講解之後較複雜的 RNNs,我們可以將 forward propogation 進一步簡化
新的 forward propogation 公式
Backpropogation through time
RNNs 的 backpropogation 又稱作 backpropogation through time
要計算 backpropogation 之前,要先知道每個單字的 loss function
這邊使用 Cross-entropy loss 作為每個單字 (或說時間點) 的 loss function
Different types of RNNs
如果要達成各式不同的 input/output 勢必需要不同的網路形式
Many-to-One
用於 sentiment classification
Many-to-many with same length
e.g. name entity recognition
Many-to-many with different length
Language model and sequence generation
Language Modelling
假設 speech recognition 時聽到了一句話
“The apple and pear salad.”
那到底是聽到上面的句子還是 “The apple and pair salad.” ?
為了判斷是哪一句話,所以給兩句話機率的方法就是 language modelling
可以看到在這個 language model 中
The apple and pear salad 的機率比較高
Build Language model with RNNs
training set 會是 large corpus of english text
corpus 是一個 NLP 名詞,代表大量句子所組成的文本
首先要 tokenize corpus 中的所有單字,也就是建立字典
tokenize 前有時會增加一個 <EOS>
代表句子結束
tokenize 會將每一個單字轉換為 one hot vector
假設有一個 10000 單字的字典,那就會在該單字的 index 設 1 其他設 0
今天遇到一個不在字典的單字,例如 Mau
那就會將他設定在 <UNK>
的位置,表示 unknown
Tokenize 後就可以將他們 input 到 RNN 訓練
為了要訓練這個 RNN 我們定義 cost function
在 predict 第 t 個單字時的 softmax loss function 為
Overall 的 Cost function 為
Sampling novel sequences
訓練好的 language model 可以用 sampling 方式來呈現他所學的結果
Sampling 方式就像 one-to-many model
以此類推直到 sampling 到 EOS 或是自訂回合數就停止
我們可以使用 character 作為每個 inputs
缺點是資料量變大,計算變大、訓練成本過高
不過隨著硬體發展,有一些專案使用 character level model
Sampling example
下圖左是一個從 news 訓練出的 model 所產生的 sampling novel sequences
下圖右則是讀完沙士比亞文章所產生的 sequences
Vanishing gradients with RNNs
人類可以記住非常前面的詞 (cat/cats) 來去判斷很後面的詞 (was/were)
但目前的 basic RNN models 很難去找出這種 Long-term Dependencies
原因跟 deep neural networks 已提過的 vanishing gradients 有著很大關係
回憶一下 vanishing gradients 是因為 backprop 的導數小於 1
Vanishing gradients in RNNs
RNN 中也有類似 vanishing gradient 的情況,在 RNN 中會出現 local influences
這造成 basic RNN model 有著無法處理 long-term dependencies 的弱點
補充 : RNN 也有可能出現 Exploding gradient 但情況較少
而且梯度爆炸比較好偵錯,只要參數有問題或是出現 numerial overflow (出現 NaN) 就會知道
並且可以用 gradient clipping 方法解決 (設定 threshold 避免梯度繼續增高)
為了處理 RNN 中的 vanishing gradient,要使用 GRU 及 LSTM 的技術
Gated Recurrent Unit (GRU)
回到原本的句子,目標是讓網路可以記憶 cat
並在之後知道要使用 was
Update Gate 最好要能 output 0/1 值,1 決定取代、0 放棄取代,所以使用 sigmoid function
由於 c 經過很長時間依然不變,且 c 就是 a,所以也解決了 vanishing gradients
Simplified GRU
Full GRU
補充 : GRU 最重要的兩篇論文 :
Long Short Term Memory (LSTM)
LSTM 跟 GRU 長的很像,但其實 LSTM 是較早出現的架構
LSTM 捨棄了 relevance gate,保留 update gate,並新增了 forget gate 和 output gate
LSTM nets
將多個 LSTM 相連在一起就是 LSTM network
Peephole Connection
這種方法稱為 Peephole connection
注意點是,若 gate 是個 100 dimensional 的 vector
那麼 c 的第 i 個值,只會影響到 gate vector 中的第 i 個值
也就是 c 和 gate 的關係是 1 對 1 的
Bidirectional RNN (BRNN)
上面兩個句子,只讀前三個字,可能會判斷兩個 Teddy 都是人名
為了解決此問題,出現了能夠雙向處理的 RNN - Bidirectional RNN (BRNN)
為了簡化問題,假設現在只讀了前四個字 He said Teddy Roosevelt
要注意的是,兩個都是 forward propogation,並非 backpropogation !
BRNN 的缺點是需要完整的句子序列,才可以訓練並預測句子中的任意單字
若用在 speech recognition,不可能等所有話講完,再慢慢處理所有文字
所以在 speech recognition 的實際應用上,不會使用 standard BRNN
但是在能夠一次取得完整句子的 NLP 應用中, standard BRNN 是很有效率的
Deep RNNs (DRNN)
到目前為止見到的只是 one hidden layer 的 RNN model
事實上 RNN 也可以有多個 hidden layer,只是不會像 CNN 那麼多
DRNN 中的每一個 blocks 可以是一般的、GRU、LSTM blocks
因為 RNN 的計算量已經相當龐大,所以 DRNN 的 hidden layers 數目並不會太多
x=Harry Potter and Hermione Granger invented a new spell.y=Harry Potter and Hermione Granger invented a new spell. HarryPotter:x<1>:x<2>... Harry:y<1>Potter:y<2>and:y<3>=1=1=0... 另外 Tx=9 表示句子的字數,同樣方式表達 y 的字數 Ty=9
X(i)<t>,y(i)<t> Tx(i)=9,Ty(i)=9 aaaron⋮and⋮Harry⋮Potter⋮zoo x<1>=00⋮1(4075th)⋮0⋮0 該 model 的目標就是給定一堆 x<t> 找出各別對應的 y<t>
在 x<1> 發現 Harry 是人名,x<87> 又是 Harry,那 1 能告訴 87 嗎?
我們會先讀第一個單字 x<1>
將他丟入 neural network 產生 y^<1>
同時會產生 a<1> 給下一個單字 x<2> 使用
通常 a<0> 是一個 0 vector
所以 x<1> 可以共享資訊給 x<3> 來產生 \hat{y}_^{<3>}
Wax,Waa,Wya
以一般化 xt 來解釋每個單字在網路中的 forward propogation
a<0>a<t>y^<t>=0=tanh(Waaa<t−1>+Waxx<t>+ba)=softmax(Wyaa<t>+by) Wa=[Waa∣Wax] 將 a<t−1> 和 x<t> 也合併起來
[a<t−1>x<t>] a<t>y^<t>=tanh(Wa[a<t−1>;x<t>]+ba)=softmax(Wya<t>+by) 也就是在 x<t> 時的 loss 表示為
L<t>(y^<t>,y<t>)=−y<t>logy^<t>−(1−y<t>)log(1−y^<t>) L(y^,y)=t=1∑TxL<t>(y^<t>,y<t>) 如此一來,就可以回推並更新 Wy,by,Wa,ba
剛剛的網路建立在 Tx=Ty 的狀況下
要注意的是該種類會把 y^ 當作下一層的 input
P(The apple and pear salad.)=5.7×10−10P(The apple and pair salad.)=3.2×10−13 The y<1> Egyptian y<2> Mau y<3> is y<4> a y<5> bread y<6> of y<7> cat .y<8> <EOS> y<9> 首先 x<1> 和 a<0> 都設為 0
第一個 timestep 算出的 y^<1> 代表字典中所有單字是句子中第一個字的機率
P(a)P(aaron)⋯P(cat)⋯P(UNK)P(EOS)
第二個 timestep 的 x<2> 就是原本句子得到的 y<1>
加上上一個 timestep 算出的 a<1>
所以算出來的 y^<2> 代表出現 cats 後字典裡每一個單字是下一個字的機率
P(average∣cats) should be the highest 以此類推,y^<3> 表示 cats average 出現後,字典中每個單字的出現機率
P(15∣cats average) should be the highest L(y^<t>,y<t>)=−i∑yi<t>logy^i<t> L=t∑L<t>(y^<t>,y<t>) 總結一下,要預測一個句子 P(y<1>,y<2>,y<3>)的機率
等於要計算 P(y<1>)
以及知道 P(y<1>) 下的 P(y<2>) 為何
再來是 P(y<1>,y<2>) 下 P(y<3>) 為何
P(y<1>,y<2>,y<3>)=P(y<1>)P(y<2>∣y<1>)P(y<3>∣y<1>,y<2>) 給定 a<0>=x<1>=0
算出 y^<1> 之後,用 np.random.choice
方式從中選取任意一個 sample
這個 sample 作為 x<2> 繼續算出 y^<2> 再選一個 sample
以上的方法每個 x<t> 都是一個單字,稱作 word level model
Vocabulary=[a,aaron,⋯,zoo,<UNK>]
Vocabulary=[a, b, c, ..., z, ., ;, 0, ..., 9, A, ...,Z]
The cat, which already ate ⋯, was full.The cats, which already ate ⋯, were full. 舉例來說 y^<3> 只會跟 x<1>,x<2>,x<3> 有較大關係
假設 was 在 y^<100> 那他就無法跟最前面的 cat/cats 互相影響了
先回顧 basic RNN 的架構,在計算 a<t> 時是這樣計算
a<t>=g(Wa[a<t−1>,x<t>]+ba)
GRU 在 basic RNN 中加入一個 memory cell (c) 的概念
The cat, which already ate ... was full.
定義每一個 c<t> 會和 a<t> 相等 c<t>=a<t>
然後定義 c~<t> 是可能取代掉 c<t> 的候補
c~<t>=tanh(Wc[c<t−1>,x<t>]+bc)
接著定義一個 Update Gate (Γu) 用來決定是否要用 c~<t> 取代掉 c<t>
Γu=σ(Wu[c<t−1>,x<t>]+bu)
最後用以下公式決定每個 time step 要不要更新 c<t>
c<t>=Γu×c~<t>+(1−Γu)×c<t−1>
當 Γu=1 時,後面被消掉,所以 c<t>=c~<t>
當 Γu=0 時,前面被消掉,所以 c<t>=c<t−1>
在 cat 時把 c~<t>=1,Γu=1
此時的 c<t> 就會被設定為 1 (假設 1 代表單數、0 代表多數)
接著句子持續下去,每一個的 Γu 都設定為 0,避免 cat 的資訊被刷掉
直到 was 的 time step 出現,我們就可以用 c<t> 告訴他是 cat 要用 was
等到 was 結束,不會再用到這個資訊,在之後的某個地方就會設定 Γu=1 更新
因為使用 sigmoid 作為 Γu 的計算方式
使得 Γu 長期都會非常接近 0 或是 1
當 Γu=1 時,c<t> 就會被更新
當 Γu=0 時,c<t> 就會保持 c<t−1>
先用 c<t−1> 和 x<t> 進行 tanh
得到 c~<t>
再用 c<t−1> 和 x<t> 進行 sigmoid
得到 Γu
然後透過紫色區塊 (就是決定是否更新) 來更新新的 c<t>=a<t>
最後跟一般一樣,產出 y^<t>
要注意的是,c<t> 可以是一個 vector
若是 c<t> 是一個 100 dimensional 的向量
那麼 c~<t>,Γu 也會是 100 dimensional
而更新 c<t> 的乘法就會是 element-wise 的乘法
c<t>=Γu∗c~<t>+(1−Γu)∗c<t−1>
在完整的 GRU 中,會再添加一個 Relevance Gate Γr
Relevance gate 用來表示 c<t> 和 c~<t> 的關聯性
我們在原本的 c~<t>
c~<t>=tanh(Wc[c<t−1>,x<t>]+bc)
c~<t>=tanh(Wc[Γr×c<t−1>,x<t>]+bc)
Γr=σ(Wr[c<t−1>,x<t>]+br)
c~<t>ΓuΓrc<t>=tanh(Wc[Γr×c<t−1>,x<t>]+bc)=σ(Wu[c<t−1>,x<t>]+bu)=σ(Wr[c<t−1>,x<t>]+br)=Γu×c~<t>+(1−Γu)×c<t−1> LSTM 不再讓 c<t>=a<t>,並將兩者分開來計算
c~<t>ΓuΓfΓoc<t>a<t>=tanh(Wc[a<t−1>,x<t>]+bc)=σ(Wu[a<t−1>,x<t>]+bu)=σ(Wf[a<t−1>,x<t>]+bf)=σ(Wo[a<t−1>,x<t>]+bo)=Γu∗c~<t>+Γf∗c<t−1>=Γo∗tanh(c<t>) 首先 t~<t> 不再使用 c<t−1> 而是使用 a<t−1> 來跟著 x<t> 一起計算
然後依次算出 Γu,Γf,Γo
更新 c<t> 時,不再是兩者取一,而是將 c<t−1> 乘上 forget gate 後,加進 update 的 t~<t>
最終用 output gate 乘上 tanh(c<t>) 來更新 a<t>
接收上一層的 c<t−1>,a<t−1>
結合 x<t> 算出三個 gate 和 c~<t>
計算出這一層的 c<t>,a<t> 給下一層使用
算出預測值 y^<t>
上面的 LSTM 的三個 gate 值只有使用 x<t>,a<t−1> 計算出來
但在實作上有一種方法將 c<t−1> 也帶入計算 gate 值
ΓuΓfΓo=σ(Wu[a<t−1>,x<t>,c<t−1>]+bu)=σ(Wf[a<t−1>,x<t>,c<t−1>]+bf)=σ(Wo[a<t−1>,x<t>,c<t−1>]+bo) He said, "Teddy bears are on sales!"He said, "Teddy Roosevelt was a great President!" 首先一如往常將句子由左至右產出 a<1>,a<2>,a<3>,a<4> (以 → 表示)
接著再將句子由右至左產出 a<4>,a<3>,a<2>,a<1> (以 ← 表示)
所以現在要計算句子中任意一個 y^<t> 都可以配合左右兩邊的資訊來計算
y^<t>=g(Wy[a<t>,a<t>]+by)
例如要計算 y^<3> 的 Teddy 為人名的機率
y^<3>=g(Wy[a<3>,a<3>]+by)
他考慮的 a<3> 考慮了 a1, a2 的 He said
他考慮的 a<3> 考慮了 a4 的 Roosevelt
<t> 用來代表第 t 個 time step
所以 a[2]<3> 代表是第 2 個 hidden layer 在第 3 個 timestep 的狀況
Wa[l] 代表在第 l 層的 Wa
ba[l] 代表在第 l 層的 ba
所以 a[2]<3> 的算法為
a[2]<3>=Wa[2][a[2]<2>,a[1]<3>]+ba[2]
DRNN 在計算 y^<t> 前,也可以先接上一連串的 fully-connected networks