說起循環神經網絡,如果需要自己去實現一個雙向RNN/LSTM/GRU模型,那麼如何去實現呢?
首先需要熟悉循環神經網絡的基本原理。
假如輸入的序列是{} (不得不吐槽,csdn公式編輯器有點爛),是1時刻下單詞對應的向量,假設是1*128維度的。
實際上,正向的LSTM,就是從左往右走,計算一遍LSTM,得到{},這裏是1時刻的輸出,也是個向量。有些博客和教程用來表示,比容易弄混淆,使用其實更加準確。
反向的LSTM,則是從右往左走,計算一遍LSTM,先從開始算起,再算,一直算到,然後得到的是反向的輸出
{}, 然後再把這個向量reverse,翻轉一下,把兩者連接起來即可。
PyTorch的實現裏有個非常關鍵的方法:
其中steps控制了是反向還是正向的計算方法,input則是輸出的{}。
def Recurrent(inner, reverse=False):
def forward(input, hidden, weight, batch_sizes):
output = []
steps = range(input.size(0) - 1, -1, -1) if reverse else range(input.size(0))
for i in steps:
hidden = inner(input[i], hidden, *weight)
# hack to handle LSTM
output.append(hidden[0] if isinstance(hidden, tuple) else hidden)
if reverse:
output.reverse()
output = torch.cat(output, 0).view(input.size(0), *output[0].size())
return hidden, output
return forward
Keras或者TensorFlow的實現,裏面有個叫參數叫做go_backwards, 實際上也是創建了兩個LSTM,一個正向傳遞,一個反向傳遞,實現方法大同小異。
因爲TensorFlow的RNN裏有個go_backwards參數,如果設置爲True,則就會從後往前遍歷。
keras實現方法關鍵性如下:
可見是創建了兩個layer,每個layer都是一個RNN.
self.forward_layer = copy.copy(layer)
config = layer.get_config()
config['go_backwards'] = not config['go_backwards']
self.backward_layer = layer.__class__.from_config(config)