我们遗忘假定的目标是,在给定观测的情况下,在时间序列的上下文中或者在语言模型的上下文中,对下一个输出进行建模,虽然这是一个典型场景,但不是唯一的,可能发生什么其他情况,考虑以下3个在文本序列中填空的任务。
根据可获得的信息,我们可以分别用不同的词填空,很明显,每个短语的下文传达了重要信息,而这些信息关乎选择哪个词来填空,无法利用这一点的序列模型将在相关任务上面表现不佳。如果要做好命名实体识别,不同长度的上下文范围的重要性是相同的,位了获得一些解决问题的灵感,我们先回到概率图模型
9.4.1 隐马尔可夫模型中的动态规划
本来用来说明动态规划问题,具体的技术细节对于理解深度学习模型并不重要,有助于我们思考为什么要使用深度学习,以及为什么要选择特定的架构。
如果我们想用概率图模型来解决这个问题,可以设计一个隐变量的模型,在任意时间步t假设存在某个隐变量h,通过概率P(xt|Ht)控制我们观测到的Xt, 任何Ht - Ht+1 转移都由一些状态转移概率P(Ht+1|Ht)给出,这个概率图模型就是一个隐马尔可夫模型HMM
因此,对于有T个观测值的序列,在观测状态和隐状态上具有以下联合概率分布
P(X1,...Xt,Ht) = PI P(Ht|Ht-1) P(Xt|Ht) 其中P(Ht|Ho) = P(Ht)
假设出了Xt, 我们观测到所有的Xt, 并且我们的目标是计算P(Xj|X-j),其中X-j = (Xj,Xj-1, Xt) 由于P(Xj|X-j)中没有隐变量,因此我们考虑对H1, Ht 选择构成的所有可能组合进行求和,如果任何Ht可以接受k个不同的值,就意味着我们需要对K^t 个项求和,这个任务显然难于登天。幸运的是,有个巧妙的解决方案,动态规划。
要了解动态规划的工作方式,我们考虑对隐变量H1, Ht依次求和,将得到
P(X1,,,Xt)
= Sigma P(X1,,,Xt, H1,,HT)
= Sigma Ht PiT()P(Xt|Ht)
通常,我们将前向递归写为
Pit+1(Ht+1) = Sigma Pi(t)P(Xt|Ht) P(Ht+1|Ht)
递归被初始化为PiT(Ht) = P(ht), 也可以写成PIt+1 = f(PIt, Xt) 其中f是可学习的函数,这看起来就像我们在循环神经网络中讨论的隐变量模型中的更新方程。
P(Xt,,,XT)
我们可以将后向传递写为
Pt-1(h-1) = SigmaP(Ht|Ht-1)P(Xt|Ht)
初始化Pt(Ht)为1,前向递归和后向递归都允许对T个隐变量在O(Kt)的时间范围内对(ht,,,,Ht)的所有值求和。这是使用图模型进行概率推理的巨大优势之一,通用消息传递算法的一个非常特殊的例子,结合前向递归和后向递归,我们能够计算。
P(Xj|X-j) = Sigma Pi(Hj)Pj(Hj)P(Xj|Hj)
因为符号简化的需要,后向递归也可以写为Pt-1 = g(Pt, Xt)其中g是一个可以学习的函数,这样看起来非常像一个更新方程,不像我们在循环神经网络中看到的那样前向计算,而是后向计算。知道未来数据何时可用对隐马尔可夫模型是有益的,信号处理学家将知道未来观测这两种情况时区分为内插和外推。
9.4.2 双向模型
我们希望在循环神经网络中拥有一种机制,使之能够提供与隐马尔可夫模型类似的前瞻能力,我们就需要修改循环神经网络的设计,在概念上很容易,只需要增加一个从最后一个词元开始从后向前运行的循环神经网络,而不是只有一个在前向模式下,从第一个词元开始运行的循环神经网络。双向循环神经网络添加了反向传递信息的隐层,以便更灵活的处理此信息,图9-10展示了具有单个隐藏层的双向循环神经网络架构。
事实上,这与隐马尔可夫模型中的动态规划的前向递归和后向传递没有太大区别。主要区别是,在隐马尔可夫模型中的方程具有特定的统计意义,而双向循环神经网络没有这样容易理解,我们只能把他们当作通用的,可学习的函数,这种转变集中体现了现代深度网络的设计原则,使用经典统计模型的函数依赖类型,然后将其参数花的通用形式。
1 定义
双向循环神经网络是由参考文献提出的,关于各类架构的详细讨论请参阅 参考文献,我们看看这样一个网络的细节。
对于任意时间步t,给定一个小批量的输入数据Xt属于Rnxd,并且令隐藏层激活函数为Sigma, 在双向架构中,我们设该时间步的前向隐藏状态和反向隐状态分别为Ht属于Rnxh和Ht属于Rnxh,其中h是隐藏单元数,前向隐藏状态和反向隐状态的更新分别如下
Ht = Sigma(XtWxh + Ht-1Whh + Bh)
接下来,将前向隐状态Ht和反向隐状态Ht连接起来,获得需要送入输出层的隐状态Ht属于Rnx2h。在具有多个隐藏层的深度双向循环神经网络中,该信息作为输入传递到下一个双向层,输出层计算得到的输出为Ot属于Rlxq是输出层的模型参数,这两个方向可以拥有不同数量的隐藏单元。
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()
trian_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)
#通过设置 bidirectuve = True 来定义双向LSTM模型
vocab_szie, num_hiddens, num_layers = len(vocab), 256, 2
num_inputs = vocab_size
lstm_layer = nn.LSTM(num_inputs, num_hiddens, num_layers, bidirectictional=True)
model = d2l.RNNModel(lstm_layer, len(vocab))
model = model.to(device)
#训练模型
num_epochs, lr = 500, l
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)
上述结果显然令人瞠目结舌,关于如何更有效的使用双向循环神经网络的讨论。
小结:
1 在双向循环神经网络中,每个时间步的隐状态由当前时间步后数据同时决定
2 双向循环神经网络于概率图模型中 前向 后向 算法具有相似性
3 双向循环神经网络主要用于序列编码和给定双向上下文的观测估计
4 由于梯度更长,因此以双向循环神经网络的训练成本非常高
529

被折叠的 条评论
为什么被折叠?



