PyTorch和TensorFlow如何實現雙向循環神經網絡RNN/LSTM/GRU的?

說起循環神經網絡,如果需要自己去實現一個雙向RNN/LSTM/GRU模型,那麼如何去實現呢?

首先需要熟悉循環神經網絡的基本原理。

假如輸入的序列是{x_1, x_2, ..., x_t, x_n} (不得不吐槽,csdn公式編輯器有點爛),x_1是1時刻下單詞對應的向量,假設是1*128維度的。

實際上,正向的LSTM,就是從左往右走,計算一遍LSTM,得到{h_1^\rightarrow , h_2^\rightarrow, ..., h_t^\rightarrow, h_n^\rightarrow},這裏h_1是1時刻的輸出,也是個向量。有些博客和教程用y_1來表示,比容易弄混淆,使用h_1其實更加準確。

反向的LSTM,則是從右往左走,計算一遍LSTM,先從x_n開始算起,再算x_{n-1},一直算到x_1,然後得到的是反向的輸出

{h_n^\leftarrow , h_t^\leftarrow, ..., h_2^\leftarrow, h_1^\leftarrow}, 然後再把這個向量reverse,翻轉一下,把兩者連接起來即可。

PyTorch的實現裏有個非常關鍵的方法:

其中steps控制了是反向還是正向的計算方法,input則是輸出的{x_1, x_2, ..., x_t, x_n}。

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)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章