目前为止,只讨论了具有一个单向隐藏层的循环神经网络,其中隐变量和观测值域具体的函数形式的交互方式是相当随意的。只要交互类型建模具有足够的灵活性,不是一个单问题。然而,对一个单层来说,可能具有相当的挑战性。之前的线性模型中,我们通过添加更多的层来解决这个问题,而在循环神经网络中,我们首先需要确定如何添加更多的层,以及在哪里添加额外的非线性层。
事实上,我们可以将多层循环神经网络堆叠在一起,通过对几个简单层的组合,产生一种灵活的机制,特别是,数据可能与不同层的堆叠有关,例如,我们可能希望保持有关金融市场状况的宏观数据可用,而微观数据只记录较为短期的时间动态。
图9-8展示了一个具有L个隐藏层的深度循环神经网络,每个隐状态都连续的传递当前层的下一个时间步和下一层的当前时间步。
9.3.1 函数依赖关系
我们可以将深度架构中的函数依赖关系形势化,这个架构由图9-8中展示的L个隐藏层构成,后续的讨论主要集中在经典的循环神经网络模型上,但是这些讨论也适应于其他序列模型
假设在时间步t又一个小批量输入数据Xt属于Rnxd,同时,将第l个隐藏层,输出层变量设为Ot属于Rnxq, 设置Ht = Xt,第l个隐藏层的隐状态使用激活函数Sigmal,则。
Ht = Sigma (Ht Wxh + Ht-1Whh + Bh)
权重Wxh属于Rhxh,Whh属于Rhh和偏置Bh属于Rlxh 都是第l个隐藏层的模型参数
Ot = HtWhq + Bq
其中,权重Whq属于Rhxq和偏置Bq属于Rlxq都是输出层的模型参数
与多层感知机一样,隐藏层数L和隐藏单元数h都是超参数,也就是说,他们可以由我们调整,用门控循环单元或者长短期记忆网络的隐状态来代替9.8中的隐状态进行计算,可以很容易的得到深度门控循环神经网络或者深度长短期记忆神经网络。
9.3.2 简洁实现
实现多层循环神经网络所需的许多逻辑细节在高级API中都是现成的,为简单起见,我们仅仅示范使用此类内置函数的实现方式,长短期记忆网络模型为例,其实现代码与之前在9.2节中使用的代码非常相似,实际上唯一的区别是我们指定了层的数量,而不是使用单一层这个默认值,像之前一样,我们从加载数据集开始。
import torch
from torch import nn
from d2l import torch as d2l
batch_size, num_steps = 32,35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)
这样超参数类型架构决策也与9.2节中的决策非常相似,因为我们有不同的词元,所以输入和输出都选择相同的数量,即vocab_size,隐单元的数量仍然为256, 唯一的区别是,我们现在通过num_layers 的值来设定隐藏层数。
vocab_size, num_hiddens, num_layers = len(vocab), 256, 2
num_inputs = vocab_size
device = d2l.try_gpu()
lstm = nn.LSTM(num_inputs, num_hiddens, num_layers)
model = d2l.RNNModel(lstm_layer, len(vocab))
model=model.to(device)
9.3.3 训练与预测
使用了长短期记忆网络模型来实例化两个层,因此训练速度大大降低了。
num_epochs, lr = 500, 2
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)
小结:
在深度循环神经网络中,隐状态的信息被传递到当前层的下一个时间步和下一层的当前时间步
有许多不同风格深度循环神经网络,如长短期记忆网络,门控循环单元或常规循环神经网络,这些模型在深度学习框架的高级API中都有涵盖
总体而言,深度循环神经网络需要大量的调参,来确保合适的收敛,模型的初始化也需要谨慎