1. 程式人生 > >Word Embedding/RNN/LSTM

Word Embedding/RNN/LSTM

參考 動態 線性 () 經典的 lda 統計 容易 problem

Word Embedding

Word Embedding是一種詞的向量表示,比如,對於這樣的“A B A C B F G”的一個序列,也許我們最後能得到:A對應的向量為[0.1 0.6 -0.5],B對應的向量為[-0.2 0.9 0.7]。

之所以希望把每個單詞變成一個向量,目的還是為了方便計算,比如“求單詞A的同義詞”,就可以通過“求與單詞A在cos距離下最相似的向量”來做到。

那麽如何進行詞嵌入呢?目前主要有三種算法:

Embedding Layer

Embedding Layer是與特定自然語言處理上的神經網絡模型聯合學習的單詞嵌入。該嵌入方法將清理好的文本中的單詞進行one hot編碼(熱編碼),向量空間的大小或維度被指定為模型的一部分,例如50、100或300維。向量以小的隨機數進行初始化。Embedding Layer用於神經網絡的前端,並采用反向傳播算法進行監督。

被編碼過的詞映射成詞向量,如果使用多層感知器模型MLP,則在將詞向量輸入到模型之前被級聯。如果使用循環神經網絡RNN,則可以將每個單詞作為序列中的一個輸入。

這種學習嵌入層的方法需要大量的培訓數據,可能很慢,但是可以學習訓練出既針對特定文本數據又針對NLP的嵌入模型。

Word2Vec/ Doc2Vec(Document to Vector)

Word2Vec是由Tomas Mikolov 等人在《Efficient Estimation of Word Representation in Vector Space》一文中提出,是一種用於有效學習從文本語料庫嵌入的獨立詞語的統計方法。其核心思想就是基於上下文,先用向量代表各個詞,然後通過一個預測目標函數學習這些向量的參數。

該算法給出了兩種訓練模型,CBOW (Continuous Bag-of-Words Model) 和 Skip-gram (Continuous Skip-gram Model)。CBOW將一個詞所在的上下文中的詞作為輸入,而那個詞本身作為輸出,也就是說,看到一個上下文,希望大概能猜出這個詞和它的意思。通過在一個大的語料庫訓練,得到一個從輸入層到隱含層的權重模型;而Skip-gram它的做法是,將一個詞所在的上下文中的詞作為輸出,而那個詞本身作為輸入,也就是說,給出一個詞,希望預測可能出現的上下文的詞。

通過在一個大的語料庫訓練,得到一個從輸入層到隱含層的權重模型。給定xx預測xxx的模型的輸入都是詞的向量,然後通過中間各種深度學習DL的CNN或RNN模型預測下一個詞的概率。通過優化目標函數,最後得到這些詞匯向量的值。

Word2Vec雖然取得了很好的效果,但模型上仍然存在明顯的缺陷,比如沒有考慮詞序,再比如沒有考慮全局的統計信息。

Doc2Vec與Word2Vec的CBOW模型類似,也是基於上下文訓練詞向量,不同的是,Word2Vec只是簡單地將一個單詞轉換為一個向量,而Doc2Vec不僅可以做到這一點,還可以將一個句子或是一個段落中的所有單詞匯成一個向量,為了做到這一點,它只是將一個句子標簽視為一個特殊的詞。

主題模型

LSA、LDA等主題模型,建立詞和主題的關系。

RNN

循環神經網絡,是非線性動態系統,將序列映射到序列,主要參數有五個:$[W_{hv}, W_{hh}, W_{oh}, b_h, b_o, h_0] $,典型的結構圖如下:

技術分享圖片

  • 和普通神經網絡一樣,RNN有輸入層輸出層和隱含層,不一樣的是RNN在不同的時間t會有不同的狀態,其中t-1時刻隱含層的輸出會作用到t時刻的隱含層.
  • 參數意義是: \(W_{hv}\):輸入層到隱含層的權重參數,\(W_{hh}\):隱含層到隱含層的權重參數,\(W_{oh}\):隱含層到輸出層的權重參數,\(b_h\):隱含層的偏移量,\(b_o\)輸出層的偏移量,\(h_0\):起始狀態的隱含層的輸出,一般初始為0.
  • 不同時間的狀態共享相同的權重w和偏移量b

RNN的計算方式

技術分享圖片

給定一個損失函數 \(L(z,y) = \sum_{t=1}^T{L(z_t, y_t)}\)

RNN因為加入了時間序列,因此訓練過程也是和之前的網絡不一樣,RNN的訓練使用的是BPTT(Back Prropagation Through TIme),該方法是由Werbo等人在1990年提出來的。

技術分享圖片

上面的算法也就是求解梯度的過程,使用的也是經典的BP算法,並沒有什麽新鮮的。但是值得一提的是,在 t-1 時刻對 \(h_{t?1}\)的求導值,也需加上t時刻的求導中對\(h_{t?1}\) 的求導值,因此BPTT也是一個鏈式的求導過程。

但是因為上面算法中的第10行,在訓練t時刻的時候,出現了t-1的參數,因此對單個的求導就變成了對整個之前狀態的求導之和。

也正是因為存在長依賴關系,BPTT無法解決長時依賴問題(即當前的輸出與前面很長的一段序列有關,一般超過十步就無能為力了),因為BPTT會帶來所謂的梯度消失或梯度爆炸問題(the vanishing/exploding gradient problem)。

這篇文章很好的解釋了為什麽會產生梯度消失和為什麽會梯度爆炸的問題,其實主要問題就是因為在BPTT算法中,以w為例,其求導過程的鏈太長,而太長的求導鏈在以tanh為激活函數(其求導值在0~1之間的BPTT中,連乘就會使得最終的求導為0,這就是梯度消失問題,也就是t時刻已經學習不到t-N時刻的參數了。當然,有很多方法去解決這個問題,如LSTMs便是專門應對這種問題的,還有一些方法,比如設計一個更好的初始參數以及更換激活函數(如換成ReLU激活函數)。

參數量

model.add(Embedding(output_dim=32, input_dim=2800, input_length=380))
model.add(SimpleRNN(units=16))
model.add(Dense(uints=256, activation=relu))
...
model.summary()
#output
simple_rnn_1 (SimpleRNN) param # 784
dense_1 (Dense) param # 4352

其中:784=16+1616+1632( \(W_{hv}\) + \(W_{hh}\) + \(b_h\)

LSTM

假設我們試著去預測“I grew up in France... I speak fluent French”最後的詞。當前的信息建議下一個詞可能是一種語言的名字,但是如果我們需要弄清楚是什麽語言,我們是需要先前提到的離當前位置很遠的 France的上下文的。這說明相關信息和當前預測位置之間的間隔就肯定變得相當的大。

不幸的是,在這個間隔不斷增大時,RNN會喪失學習到連接如此遠的信息的能力。在理論上,RNN絕對可以處理"長期依賴"問題。人們可以仔細挑選參數來解決這類問題中的最初級形式,但在實踐中,RNN 肯定不能夠成功學習到這些知識。Bengio, et al.等人對該問題進行了深入的研究,他們發現一些使訓練 RNN 變得非常困難的根本原因。

然而,幸運的是,LSTM 並沒有這個問題!

LSTM 由Hochreiter & Schmidhuber (1997)提出,並在近期被Alex Graves進行了改良和推廣。在很多問題,LSTM 都取得相當巨大的成功,並得到了廣泛的使用。

LSTM 通過刻意的設計來避免長期依賴問題。記住長期的信息在實踐中是 LSTM 的默認行為,而非需要付出很大代價才能獲得的能力!

所有 RNN 都具有一種重復神經網絡模塊的鏈式的形式。在標準的 RNN 中,這個重復的模塊只有一個非常簡單的結構。
技術分享圖片
LSTM 同樣是這樣的結構,但是重復的模塊擁有一個不同的結構。不同於單一神經網絡層,以一種非常特殊的方式進行交互。
技術分享圖片

核心思想

LSTM 中的第一步是決定我們會從細胞狀態中丟棄什麽信息。這個決定通過一個稱為忘記門層完成。
技術分享圖片
下一步是確定什麽樣的新信息被存放在細胞狀態中。
技術分享圖片
我們把舊狀態與 \(f_t\) 相乘,丟棄掉我們確定需要丟棄的信息。接著加上 \(i_t * \tilde{C}_t\)。這就是新的候選值,根據我們決定更新每個狀態的程度進行變化。
技術分享圖片
最終,我們需要確定輸出什麽值。這個輸出將會基於我們的細胞狀態,但是也是一個過濾後的版本。
技術分享圖片
我們到目前為止都還在介紹正常的 LSTM。但是不是所有的 LSTM 都長成一個樣子的。實際上,幾乎所有包含 LSTM 的論文都采用了微小的變體。

圖中最上面的一條線的狀態即 s(t) 代表了長時記憶,而下面的 h(t)則代表了工作記憶或短時記憶。

參數量

model.add(Embedding(output_dim=32, input_dim=2800, input_length=380))
model.add(LSTM(32))
model.add(Dense(uints=256, activation=relu))
...
model.summary()
#output
lstm_1 (LSTM) param # 8320

其中:8320=(32+32)324+4*32( \(W_o\) + \(W_C\) + \(W_i\) + \(W_f\) + \(b_o\) + \(b_C\) + \(b_i\) + \(b_f\))。

GRU

LSTM有很多變體,其中較大改動的是Gated Recurrent Unit (GRU),這是由 Cho, et al. (2014)提出。它將忘記門和輸入門合成了一個單一的 更新門。同樣還混合了細胞狀態和隱藏狀態,和其他一些改動。最終的模型比標準的 LSTM模型要簡單。效果和LSTM差不多,但是參數少了1/3,不容易過擬合。
技術分享圖片

參考:

理解 LSTM 網絡

Word Embedding/RNN/LSTM