1. 程式人生 > 實用技巧 >NLP經典模型入門-TextRNN與TextRCNN

NLP經典模型入門-TextRNN與TextRCNN

前言:筆者之前是cv方向,因為工作原因需要學習NLP相關的模型,因此特意梳理一下關於NLP的幾個經典模型,由於有基礎,這一系列不會關注基礎內容或者公式推導,而是更側重對整體原理的理解。順便推薦兩個很不錯的github專案——開箱即用的中文教程以及演算法更全但是有些跑不通的英文教程

一. RNN與LSTM

RNN

CNN與RNN的對比如上圖所示,最大的區別是RNN的神經元之間彼此是關聯的,因此RNN特別適合做序列模型。

RNN的中間層每個神經元的計算公式如下所示:

LSTM

上面的公式中,啟用函式一般使用sigmoid或者tanh。這就導致,在水平方向上,也很容易出現梯度彌散,而且後面的序列比較難獲取前面序列的資訊,因此出現了LSTM。LSTM是長短期記憶網路,核心就在於有上下兩條之路。下路更關注短序列之間的資訊傳遞,上路則更關注把資訊傳遞得更長,LSTM的網路結構如下所示:

LSTM的最小單元構成圖和具體公式如下:


x號是LSTM特有的門機制,它有兩個輸入,一個輸入是原始資訊,另一個輸入則一般經過啟用函式被約束到0~1之間、可以看做一個開關。兩者相乘,原始資訊會按照開關大小進行保留。先看\(C_{t-1}\)經過的路線:

  • 最左面的x號,長時間記憶有多少保留了下來,開關多少由當前輸入計算得來
  • 中間的+號,長時間記憶會把當前輸入的資訊新增進來,這裡當前輸入會自己同時產生原始資訊並做開關,有點類似self-attention的做法
  • 最右面的x號,融合後的長時間記憶做開關,決定當前輸入有多少流入下一層

Bi-LSTM

如上圖所示。其實就是把序列正著來一遍然後反著來一遍,然後相同位置的輸入拿出來直接連線在一起作為當前位置神經元的最終輸出。可以更好地捕捉上下文資訊。同理,RNN也可以搞雙向,本質上只是模組不同,一個是LSTM模組另一個是RNN塊。LSTM更先進一些。

LSTM在Pytorch中可以直接使用:

# define
self.lstm = nn.LSTM(config.embed, config.hidden_size, config.num_layers,
bidirectional=True, batch_first=True, dropout=config.dropout)
## num_layers: 若干個lstm堆疊
## hidden_size:中間隱藏的特徵數量

# use
out, _ = self.lstm(embed)

二. TextRNN與TextRCNN

  • TextRNN比較簡單,一般在embedding後,接若干個lstm後直接接fc,然後計算損失函式即可。可以加入cat操作連綴embed和feature,具體操作間RCNN
out = self.embedding(x)  # [batch_size, seq_len, embeding]
out, _ = self.lstm(out)
out = self.fc(out[:, -1, :])  # 句子最後時刻的 hidden state
  • TextRCNN的一個核心思想是引入最大池化層,模仿CNN的那種效果,並且使用雙向的RNN(這裡直接用更好的LSTM替代了)
embed = self.embedding(x)  # [batch_size, seq_len, embeding]
out, _ = self.lstm(embed)
out = torch.cat((embed, out), 2) # seq_len固定,連綴特徵長度
out = F.relu(out)
out = out.permute(0, 2, 1)
out = self.maxpool(out).squeeze() # 此處seq_len會消失
out = self.fc(out)