嗯,你們這羣人壞的很,收藏都上去好多了,連個贊都不點個!!!

更新ELMO在QACNN上的應用,如果你們調參得到更好的結果,也請告訴我啊!如果有相關ELMO,BERT在答案選擇上的文章,也請推薦給我一下啊!

傳送門

----------------------------------- 2019.4.12 update --------------------------------------

現在談EMLO,倒是有點食之微味,棄之可惜的意思。2018年,BERT的橫空出世撼動了NLP的半壁江山,nlper無不知曉,多項刷榜記錄讓多數奮戰在一線鑽研演算法的工程師們一剎那覺得自己的努力也僅僅只是感動了自己而已,自然而然,BERT的風光掩蓋了ELMO。

但是,我個人覺得,從word2vec,glove到ELMO,BERT,ELMO算是一個比較精彩的轉折點吧,有著承前啟後的作用,於是,今天就來小談下ELMO。

為什麼出現了ELMO?

在word2vec的時代,詞向量是上下文無關的,然而在語言中一詞多義的現象是很常見的,比如may,有可能的意思,也有五月的意思;apple,是可以喫的蘋果,還是那個apple公司,完全取決於語境。在答案選擇領域,那麼多複雜的模型,無非不就是為了獲得句子的語義信息,句子由片語成,細微處看,就是在摸索詞之間的聯繫與含義,如果一個詞沒有根據下游任務改變自己的能力,那麼往往就需要外界力量去推動她來展示不同層面的意思,而這個外界力量就是那些複雜的模型結構。那麼,何不追本溯源,從一開始就讓詞向量擁有可以根據不同下游任務而變換的能力呢?ELMO因此誕生。

雙向語言模型

  • 前向語言模型:

p(t_1, t_2, cdots, t_N) = prod_{k=1}^N p(t_k|t_1, t_2, cdots, t_{k-1})

  • 後向語言模型:

 p(t_1, t_2, cdots, t_N) = prod_{k=1}^N p(t_k|t_{k+1}, t_{k+2}, cdots, t_{N})

那麼其損失函數語言模型標準的最大化似然函數:

 sum_{k=1}^N (  log ,, p(t_k|t_1, t_2, cdots, t_{k-1}; Theta_x, overrightarrow{Theta_{LSTM}}, Theta_s )   \ +  , log ,, p(t_k|t_{k+1}, t_{k+2}, cdots, t_{N}; Theta_x, overleftarrow{Theta_{LSTM}}, Theta_s )

上面的雙向語言模型其實就是統計語言模型的一個近似,什麼是統計語言模型呢?統計語言模型就是通過統計方法計算一個句子的概率的模型。以前向語言模型為例,我們可以根據這個概率公式來計算下一個詞出現的概率。比如「the cat sat on the mat」,我們可以根據「the cat sat on the」來預測下一個詞是「mat」的概率,有種完形填空的味道。

ELMO要點

一、模型結構

從圖的結構上來看,我們可以很清晰的看到ELMO模型的主要結構就是L層的雙向LSTM,對於L層的雙向lstm語言模型,一共會有有2L+1個representations。在多層模型中,淺層往往蘊含的是句法,語法信息,而高層蘊含的是語義信息,因此你可以選擇ELMO中各層的輸出作為最後的輸出,也可以將各層的輸出進行綜合作為最後的輸出。

上面2個公式就可以很好的說明瞭整個流程:ELMO 經過 L 層的雙向語言模型, 然後將字元級表示x_k, 每層的隱層輸出overrightarrow{h}_{k}, overleftarrow{h}_{k}組合起來, 形成一個2L + 1 個向量。s^{task}是不同層的參數經過softmax結果(也就是說s_0+s_1+…+s_L=1),值得一提的是, 縮放因子gamma^{task}是考慮到雙向語言模型中的每一層的輸出具有不同的分佈,其某種程度上相當於在 Weighting 前對每一層的向量做 Layer Normalization。 論文中有提到,如果將每層向量提前做Normalization, 也能夠有所幫助[1]。

論文的作者有預訓練好的ELMo模型,同時LSTM的層數L=2,我們以2層的ELMO來具體看ELMO的結構。

  1. E1:word embedding部分,這個部分可以用wrod2vec或者glove來得到上下文無關general embedding。文中使用的Jozefowicz的CNN-BIG-LSTM[2].
  2. L=2,作者用2層的bilstm進行encoder,同時將每一層lstm得到的hidden state(隱狀態) 作為每個詞的上下文相關的word vectors.
  3. 1+2*2 = 5,現在總共有5個上下文相關的word vectors,那麼將詞向量進行線性組合,針對不同的任務,不同層的向量做相應的權重加和。

二、模型精髓

  1. ELMO的各層參數實際上就是為各種有監督的下游任務準備的,因此ELMO可以被認為是一種遷移學習(transfer learning)。
  2. 通過這樣的遷移策略,那些對詞義消歧有需求的任務就更容易通過訓練給第二隱層一個很大的權重,而對詞性、句法有明顯需求的任務則可能對第一隱層的參數學習到比較大的值(實驗結論)。總之,這樣便得到了一份」可以被下游任務定製「的特徵更為豐富的詞向量。[3]

三、ELMO缺點

  • lstm是串列機制,訓練時間長,從這一點來看ELMO註定成為不了大哥
  • 相比於Transformer,lstm提取特徵的能力還是不夠的,我覺得未來lstm可能會被淘汰,畢竟屁股決定腦袋,時間為上!

四、ELMO詞向量使用方式

論文中提到, 使用ELMO 有兩種方式:

  • 將 ELMO 的向量 與 Word2Vec等普通詞向量進行連接,連接的方式可以有多種多樣
  • 將 ELMO 的向量與上下文表示層的 h (通過 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個問題!

  1. batch_size設置的太大的話,內存直接爆炸
  2. 因為調用的是elmo的網址,然而在測試的時候我的pc老是掉線,因此很惱火,所以我採用了第二種方式訓練了

目前還在跑模型,總結用法後會放上來,如果感興趣,請關注我的 github

Reference:

  1. 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.github.com/allenai/alle

5.github.com/allenai/bilm

6.tfhub.dev/google/elmo/2

推薦閱讀:

相關文章