《动手学深度学习 Pytorch版》 9.4 双向循环神经网络

发布时间 2023-10-19 12:13:58作者: AncilunKiang

之前的序列学习中假设的目标是在给定观测的情况下对下一个输出进行建模,然而也存在需要后文预测前文的情况。

9.4.1 隐马尔可夫模型中的动态规划

数学推导太复杂了,略。

9.4.2 双向模型

双向循环神经网络(bidirectional RNNs)添加了反向传递信息的隐藏层,以便更灵活地处理此类信息。

image

9.4.2.1 定义

前向和反向隐状态的更新如下:

\[\overrightarrow{\boldsymbol{H}}_t=\phi_l(\boldsymbol{X}_t\boldsymbol{W}^{(f)}_{xh}+\overrightarrow{\boldsymbol{H}}_{t-1}\boldsymbol{W}^{(f)}_{hh}+\boldsymbol{b}^{(f)}_h)\\ \overleftarrow{\boldsymbol{H}}_t=\phi_l(\boldsymbol{X}_t\boldsymbol{W}^{(b)}_{xh}+\overleftarrow{\boldsymbol{H}}_{t-1}\boldsymbol{W}^{(b)}_{hh}+\boldsymbol{b}^{(b)}_h) \]

参数字典:

  • \(\overrightarrow{\boldsymbol{H}}_t,\overleftarrow{\boldsymbol{H}}_t\in\R^{n\times h}\) 表示前向和反向隐状态

    • \(h\) 表示隐藏单元数目
  • \(\boldsymbol{W}^{(f)}_{xh},\boldsymbol{W}^{(f)}_{hh},\boldsymbol{W}^{(b)}_{xh},\boldsymbol{W}^{(b)}_{hh}\in\R^{h\times h}\) 表示权重参数

  • \(\boldsymbol{b}^{(f)}_h,\boldsymbol{b}^{(b)}_h\in\R^{1\times h}\) 表示偏重参数

接下来,将前向隐状态 \(\overrightarrow{\boldsymbol{H}}_t\) 和反向隐状态 \(\overleftarrow{\boldsymbol{H}}_t\) 连接起来,获得需要送入输出层的隐状态 \(\boldsymbol{H}_t\in\R^{n\times 2h}\)

最后,输出层计算得到的输出为:

\[\boldsymbol{O}_t=\boldsymbol{H}_t\boldsymbol{W}_{hq}+\boldsymbol{b}_q \]

参数字典:

  • \(\boldsymbol{O}_t\in\R^{n\times q}\) 表示输出层输出

    • \(q\) 表示输出单元数目
  • \(\boldsymbol{W}_{hq}\in\R^{2h\times q}\) 表示权重矩阵

  • \(\boldsymbol{b}_q\in\R^{1\times q}\) 表示偏置

9.4.2.2 模型的计算成本及其应用

在训练期间,能够利用过去和未来的数据来估计现在空缺的词;而在测试期间,只有过去的数据,因此精度将会很差。下面的实验将说明这一点。

另外,双向循环神经网络的计算速度非常慢。其主要原因是网络的前向传播需要在双向层中进行前向和后向递归,并且网络的反向传播还依赖于前向传播的结果。因此,梯度求解将有一个非常长的链。

双向层的使用在实践中非常少,并且仅仅应用于部分场合。例如,填充缺失的单词、词元注释(例如,用于命名实体识别)以及作为序列处理流水线中的一个步骤对序列进行编码(例如,用于机器翻译)。

9.4.3 双向循环神经网络的错误应用

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)
perplexity 1.1, 62244.4 tokens/sec on cuda:0
time travellerererererererererererererererererererererererererer
travellerererererererererererererererererererererererererer

image

练习

(1)如果不同方向使用不同数量的隐藏单位,\(\boldsymbol{H}_t\) 的形状会发生怎样的变化?

如果一个是 \(\overrightarrow{\boldsymbol{H}}_t\in\R^{n\times h_1}\),另一个是 \(\overleftarrow{\boldsymbol{H}}_t\in\R^{n\times h_2}\) 那么最后拼接出的 \(\boldsymbol{H}_t\in\R^{n\times (h_1+h_2)}\)


(2)设计一个具有多个隐藏层的双向循环神经网络。

不会,略。


(3)在自然语言中一词多义很常见。例如,“bank”一词在不同的上下文“i went to the bank to deposit cash”和“i went to the bank to sit down”中有不同的含义。如何设计一个神经网络模型,使其在给定上下文序列和单词的情况下,返回该单词在此上下文中的向量表示?哪种类型的神经网络架构更适合处理一词多义?

那必然是双向循环网络。