双向循环神经网络 Bi-RNN
2022-09-27 本文已影响0人
小黄不头秃
(一)双向循环神经网络
我们首先回顾一下前面学习的序列模型中的求某个时刻,该事件发生的概率的推导公式:
在时间t观察得到了一个数据,那么得到T个不独立的随机变量 ~ 。使用条件概率展开(乘法法则):
我们可以看这个公式在直观上的表达,也就是后续的概率是基于前面的概率的。当然也可以反过来。
我们知道计算这个概率的时候,可以选择从前往后看,也可以选择从后往前看。这就构成了双向循环神经网络的核心思想。
举个例子:
对于某个词的预测,可能后面的内容也很重要。
- 填空的词取决于过去和未来的上下文
- 目前的RNN都是只看过去
- 在填空的时候我们可以看未来
(1)网络结构
这个图看起来挺复杂的,我们只看前两个。
正常情况下,x通过隐藏层H然后输出为O,然后隐状态向下传递。就是如图所示的->->。
接下来我们看,除了正常情况,他还有一个箭头直接传向了逆,然后将隐状态传向上一层的逆然后与正向的共同作用输出。
所以说一共有两条链,第一条是正向的,第二条是逆向的,他们共同作用输出结果,这就是双向RNN的网络结构了。
(2)训练和预测
训练是好训练的,但是那么我怎么用来预测呢?所以双向神经网络是不能用在预测下一个词的情况的。
这里没有实现从零开始写,但是说一下简单的操作流程:
- 把输入复制一遍
- 在前向传到的时候,正常输出第一个隐藏层的结果
- 第二个隐藏层把输入反向,并输出反向
- 然后把两个隐藏层的输出一一对应的连接
双向神经网络的主要作用是对一个句子做特征提取。例如,提取摘要、填空等。
(二)代码实现
(1)简洁实现
这个应用场景是错误的,因为双向神经网络无法用于预测未来,也就是说下面的网络是没有意义的。只是用来说明怎么使用。
import torch
from torch import nn
from d2l import torch as d2l
# 加载数据
batch_size, num_steps, device = 32, 35, d2l.try_gpu()
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)
# 通过设置“bidirective=True”来定义双向LSTM模型
vocab_size, num_hiddens, num_layers = len(vocab), 256, 2
num_inputs = vocab_size
lstm_layer = nn.LSTM(num_inputs, num_hiddens, num_layers, bidirectional=True)
model = d2l.RNNModel(lstm_layer, len(vocab))
model = model.to(device)
# 训练模型
num_epochs, lr = 500, 1
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)