说起循环神经网络,如果需要自己去实现一个双向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)