03.25 如何使用LSTM在Keras中快速實現情感分析任務

本文對 LSTM 進行了簡單介紹,並講述瞭如何使用 LSTM 在 Keras 中快速實現情感分析任務。

長短期記憶網絡通常被稱為 LSTM,它是由 Hochreiter 和 Schmiduber 提出的,被廣泛地應用在語音識別、語言建模、情感分析和文本預測中。在深入 LSTM 之前,我們首先應該理解對 LSTM 的需求,這個可以通過 RNN 在實際應用中的缺陷來解釋。所以我們就從 RNN 開始吧。

循環神經網絡(RNN)

我們人類在看電影的時候,理解任何事件的時候每次都不是從零開始的,我們會從電影中最近發生的事中學習。但是,傳統的神經網絡是無法從之前的事件中學習的,因為這些信息沒有從一步傳遞到下一步。相反,RNN 從與之緊接的前一步中學習。

例如,電影中有這麼一幕:一個人在籃球場。那麼我們會在未來的畫面中即興聯想籃球活動:有人在奔跑、跳躍很可能被打上打籃球的標籤,而一個人坐著觀看很可能是觀眾在觀看球賽。

如何使用LSTM在Keras中快速實現情感分析任務

典型 RNN(圖源:http://colah.github.io/posts/2015-08-Un

如何使用LSTM在Keras中快速實現情感分析任務

常見的 RNN 如上所示:其中 X(t) 是輸入,h(t) 是輸出,A 是一個在循環中從前一步獲得信息的神經網絡。一個單元的輸出被傳送到下一個單元,信息也被傳遞了。

但是,有時候我們需要網絡不僅僅能夠從最近的過去信息中學習。假設我們要預測下面這句話中空格里面的內容:「David,一個 36 歲的男子,住在舊金山。他有一位女性朋友 Maria。Maria 在紐約一家著名的餐館當廚師,最近他在一次校友會上遇到了他。瑪麗亞告訴他,她總是對_ _ 有熱情」。這裡,我們希望網絡能夠從「廚師」(cook)中學習,預測出「烹飪」(cooking)一詞。然而我們期望預測的內容和期望被預測的位置之間存在距離,這被稱作長期依賴。任何比三元語法更大的東西我們都稱之為長期依賴。不幸的是,RNN 在這種情況下並不會成功。

為什麼 RNN 在實際中並不會成功?

在訓練 RNN 的過程中,信息在循環中一次又一次的傳遞會導致神經網絡模型的權重發生很大的更新。這是因為每次更新中的誤差梯度都會積累起來,因此會導致一個不穩定的網絡。在極端情況下,權值可能會變得過大以至於溢出並形成一個非數值(NaN)。網絡層之間的梯度(值大於 1)重複相乘導致梯度爆炸,而小於 1 的梯度重複相乘會造成梯度消失。

長短期記憶

上面提到的 RNN 的缺陷促使科學家發明了一種 RNN 模型的新變體,它就是長短期記憶(LSTM)。LSTM 可以解決這個問題,因為它使用了門機制來控制記憶過程。

讓我們來理解 LSTM 的結結構,並將它與 RNN 進行對比:

如何使用LSTM在Keras中快速實現情感分析任務

LSTM 單元(圖源:http://colah.github.io/posts/2015-08-Un

圖中使用的符號含義如下:

a) X:信息

b) +:增加信息

c) σ:Sigmoid 層

d) tanh:tanh 層

e) h(t-1):上一個 LSTM 單元的輸出

f) c(t-1):上一個 LSTM 單元的記憶

g) X(t):當前輸入

h) c(t):新更新的記憶

i) h(t):當前輸出

為什麼使用 tanh?

為了克服梯度消失問題,我們需要一個二階導數在到達 0 之前能夠持續很長範圍的函數。tanh 函數就是滿足這一屬性的合適函數。

為什麼使用 Sigmoid?

Sigmoid 可以輸出 0 或 1,因此它可用來遺忘或者記住信息。

信息通過很多此類 LSTM 單元傳遞。LSTM 有三個主要組成部分,正如上圖中所標記出來的:

  1. LSTM 具備一種特殊的結構,能夠讓網絡忘記不必要的信息。Sigmoid 層以 X(t) 和 h(t-1) 為輸入,並且決定舊輸出的哪一部分應該被刪除(通過輸出 0)。在我們的例子中,當輸入是「他有一位女性朋友 Maria」時,「David」的性別可以被忘記了,因為這裡的主語已經變成「Maria」了。這個門被稱作「遺忘門」f(t)。遺忘門的輸出是 f(t)*c(t-1)。

  2. 下一步就是利用 cell 狀態的新輸入 X(t) 做決策並存儲信息。Sigmoid 層決定哪個新信息應該被更新或者被忽略。tanh 層從新輸入中創建一個新向量,向量的值是所有可能的值。然後這兩個值相乘來更新新的 cell 狀態。然後這個新記憶和舊的記憶 c(t-1) 加起來得到 c(t)。在我們的例子中,對於新的輸入「他有一位女性朋友 Maria」,Maria 的性別就會被更新。當輸入是「Maria 在紐約一家著名餐廳當廚師,最近他在一次校友會上遇到了她」(Maria works as a cook in a famous restaurant in New York whom he met recently in a school alumni meet)時,像「famous」、「school alumni meet」這些詞可以被忽略,而「cooking」、「restaurant」以及「New York」這樣的詞將被更新。

  3. 最後,我們需要決定輸出什麼。sigmoid 層決定了我們要輸出 cell 狀態的哪一部分。然後,我們使 cell 狀態通過 tanh 層來生成所有可能的值,並將它與 sigmoid 門的輸出相乘,所以我們只輸出想要輸出的部分。在我們的例子中,我們想要預測空格中的單詞,模型可以從記憶中得知它是一個與「cook」相關的詞,因此它就可以很容易地回答這個詞是「cooking」。我們的模型不是從瞬時依賴中學習這個答案,而是從長期依賴中學到的。

我們可以看到,經典 RNN 和 LSTM 的結構存在很大的差異。在 LSTM 中,我們的模型學會了在長期記憶中保存哪些信息,丟掉哪些信息。

使用 LSTM 進行情感分析的快速實現

這裡,我在 Yelp 開放數據集(https://www.yelp.com/dataset)上使用 Keras 和 LSTM 執行情感分析任務。

下面是數據示例。

如何使用LSTM在Keras中快速實現情感分析任務

數據集

我使用 Tokenizer 將文本進行向量化,在限制 Tokenizer 僅僅使用前 2500 個常用詞之後,把文本轉換成整數序列。我使用 pad_sequences 將生成的整數序列轉換成 2 維的 numpy 數組。

<code>#I have considered a rating above 3 as positive and less than or equal to 3 as negative.data['sentiment']=['pos'if(x>3)else'neg'for x in data['stars']]/<code>

<code>data['text']= data['text'].apply((lambda x: re.sub('[^a-zA-z0-9\\s]','',x)))/<code>

<code>for idx,row in data.iterrows():/<code>

<code> row[0]= row[0].replace('rt',' ')/<code>

<code>data['text']=[x.encode('ascii')for x in data['text']]/<code>

<code>tokenizer =Tokenizer(nb_words=2500, lower=True,split=' ')/<code>

<code>tokenizer.fit_on_texts(data['text'].values)/<code>

<code>#print(tokenizer.word_index) # To see the dicstionary/<code>

<code>X = tokenizer.texts_to_sequences(data['text'].values)/<code>

<code>X = pad_sequences(X)/<code>

接下來,我構建自己的 LSTM 網絡,該網絡具備以下超參數:

1. embed_dim:嵌入層把輸入序列編碼成維度為 embed_dim 的密集向量序列。

2. lstm_out:LSTM 網絡將向量序列轉換成一個 lstm_out 向量,它包含整個序列的信息。

其他超參數和卷積神經網絡類似,例如 dropout、batch_size。

我使用 softmax 作為激活函數。

如何使用LSTM在Keras中快速實現情感分析任務

LSTM 網絡

<code>embed_dim =128/<code>

<code>lstm_out =200/<code>

<code>batch_size =32/<code>

<code>model =Sequential()/<code>

<code>model.add(Embedding(2500, embed_dim,input_length = X.shape[1], dropout =0.2))/<code>

<code>model.add(LSTM(lstm_out, dropout_U =0.2, dropout_W =0.2))/<code>

<code>model.add(Dense(2,activation='softmax'))/<code>

<code>model.compile(loss ='categorical_crossentropy', optimizer='adam',metrics =['accuracy'])/<code>

<code>print(model.summary())/<code>

如何使用LSTM在Keras中快速實現情感分析任務

現在,我在訓練集上訓練我的模型,然後在驗證集上檢驗準確率。

<code>Y = pd.get_dummies(data['sentiment']).values/<code>

<code>X_train, X_valid, Y_train, Y_valid = train_test_split(X,Y, test_size =0.20, random_state =36)/<code>

<code>#Here we train the Network./<code>

<code>model.fit(X_train, Y_train, batch_size =batch_size, nb_epoch =1, verbose =5)/<code>

如何使用LSTM在Keras中快速實現情感分析任務

在僅僅 1 個 epoch 之後,我就得到了 86% 的準確率,而這只是在一個小型數據集(包括所有行業)上運行。

下一步的工作:

1. 我們可以過濾特定的行業(如餐廳),並使用 LSTM 做情感分析。

2. 我們可以使用更大的數據集和更多的 epoch,來得到更高的準確率。

3. 我們可以使用更多隱藏密集層來提升準確率。我們也可以調整其他的超參數。

結論

當我們期望模型能夠從長期依賴中學習的時候,LSTM 優於其他模型。LSTM 遺忘、記憶和更新信息的能力使得它領先 RNN 一步。

  • 我的 GitHub repo:https://github.com/nsinha280/lstm-on-Yelp-review-data

  • 理解 LSTM:http://colah.github.io/posts/2015-08-Understanding-LSTMs/

  • RNN 和 LSTM 新手指引:https://deeplearning4j.org/lstm.html

  • 探索 LSTM:http://blog.echen.me/2017/05/30/exploring-lstms/

  • 關於 LSTM 的研究論文:http://www.bioinf.jku.at/publications/older/2604.pdf


分享到:


相關文章: