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)

 

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