上面2個公式就可以很好的說明瞭整個流程:ELMO 經過 L 層的雙向語言模型, 然後將字元級表示 , 每層的隱層輸出 組合起來, 形成一個2L + 1 個向量。 是不同層的參數經過softmax結果(也就是說 ),值得一提的是 , 縮放因子 是考慮到雙向語言模型中的每一層的輸出具有不同的分佈,其某種程度上相當於在 Weighting 前對每一層的向量做 Layer Normalization。 論文中有提到,如果將每層向量提前做Normalization, 也能夠有所幫助[1]。
論文的作者有預訓練好的ELMo模型,同時LSTM的層數L=2,我們以2層的ELMO來具體看ELMO的結構。
E1:word embedding部分,這個部分可以用wrod2vec或者glove來得到上下文無關general embedding。文中使用的Jozefowicz的CNN-BIG-LSTM[2].
L=2,作者用2層的bilstm進行encoder,同時將每一層lstm得到的hidden state(隱狀態) 作為每個詞的上下文相關的word vectors.
1+2*2 = 5,現在總共有5個上下文相關的word vectors,那麼將詞向量進行線性組合,針對不同的任務,不同層的向量做相應的權重加和。
二、模型精髓
ELMO的各層參數實際上就是為各種有監督的下游任務 準備的,因此ELMO可以被認為是一種遷移學習(transfer learning)。
通過這樣的遷移策略,那些對詞義消歧 有需求的任務就更容易通過訓練給第二隱層一個很大的權重 ,而對詞性、句法 有明顯需求的任務則可能對第一隱層的參數學習到比較大的值 (實驗結論)。總之,這樣便得到了一份」可以被下游任務定製「的特徵更為豐富的詞向量。[3]
三、ELMO缺點
lstm是串列機制,訓練時間長,從這一點來看ELMO註定成為不了大哥
相比於Transformer,lstm提取特徵的能力還是不夠的,我覺得未來lstm可能會被淘汰,畢竟屁股決定腦袋,時間為上!
四、ELMO詞向量使用方式
論文中提到, 使用ELMO 有兩種方式:
將 ELMO 的向量 與 Word2Vec等普通詞向量進行連接,連接的方式可以有多種多樣
將 ELMO 的向量與上下文表示層的 (通過 LSTM/Transformer處理傳統詞向量得到) 進行連接, 連接的方式同樣有多種多樣。
論文中還提到, 適當的 Dropout 或者在損失中加入L2正則是有幫助的。
五、ELMO實踐
搬運一下!
有三種方法可以使用預訓練好的elmo模型。
一、elmo官方allenNLP發布的基於pytorch實現的版本[4];
二、elmo官方發布的基於tensorflow實現的版本[5];
三、tensorflow-hub中google基於tensorflow實現的elmo的版本[6]。
本節內容介紹第三個版本,tensorflow-hub
下面看代碼的簡單上手使用,大家可能需要先安裝tensorflow_hub。
import tensorflow_hub as hub
# 載入模型
elmo = hub . Module ( "https://tfhub.dev/google/elmo/2" , trainable = True )
# 輸入的數據集
texts = [ "the cat is on the mat" , "dogs are in the fog" ]
embeddings = elmo (
texts ,
signature = "default" ,
as_dict = True )[ "default" ]
上述代碼中,hub.Module載入模型,第一次會非常慢,因為要下載模型,甚至可能要科學上網。該模型是訓練好的模型,也就是lstm中的參數都是固定的。下面的代碼是另一種實現,我們可以看到區別在於輸入的數據格式不一樣!
elmo = hub . Module ( "https://tfhub.dev/google/elmo/2" , trainable = True )
# 另一種方式輸入數據
tokens_input = [[ "the" , "cat" , "is" , "on" , "the" , "mat" ],
[ "dogs" , "are" , "in" , "the" , "fog" , "" ]]
# 長度,表示tokens_input第一行6一個有效,第二行5個有效
tokens_length = [ 6 , 5 ]
# 生成elmo embedding
embeddings = elmo (
inputs = {
"tokens" : tokens_input ,
"sequence_len" : tokens_length
},
signature = "tokens" ,
as_dict = True )[ "default" ]
EMLO可以以batch的形式訓練 ,但是我在測試上面方法的時候發現有2個問題!
batch_size設置的太大的話,內存直接爆炸
因為調用的是elmo的網址,然而在測試的時候我的pc老是掉線,因此很惱火,所以我採用了第二種方式訓練了
目前還在跑模型,總結用法後會放上來,如果感興趣,請關注我的 github
Reference:
ELMO: Deep contextualized word representations
2.Jozefowicz R, Vinyals O, Schuster M, et al. Exploring the limits of language modeling[J]. arXiv preprint arXiv:1602.02410, 2016.
3.NLP的遊戲規則從此改寫?從word2vec, ELMo到BERT
4.https:// github.com/allenai/alle nnlp/blob/master/tutorials/how_to/elmo.md
5.https:// github.com/allenai/bilm -tf
6.https:// tfhub.dev/google/elmo/2
推薦閱讀: