动手学PyTorch | (31) 循环神经网络

天涯浪子 提交于 2019-11-26 07:31:28

上⼀节介绍的n元语法中,时间步t的词

基于前⾯所有词的条件概率只考虑了最近时间步的n-1个词。如果要考虑⽐t-(n-1)更更早时间步的词对

的可能影响,我们需要增⼤n.但这样模型参数的数量将随之呈指数级增长。

本节介绍循环神经网络。它并非刚性地记忆所有固定长度的序列,⽽是通过隐藏状态来存储之前时间步的信息。⾸先我们回忆一下前面介绍过的多层感知机,然后描述如何添加隐藏状态来将它变成循环神经网络。

目录

1. 不含隐藏状态的神经网络

2. 含隐藏状态的循环神经网络

3. 应用:基于字符级循环神经网络的语言模型

4. 小结


1. 不含隐藏状态的神经网络

让我们考虑一个含单隐藏层的多层感知机。给定样本数为n,输入个数(特征数或特征向量维度)为d的小批量数据样本

.设隐藏层的激活函数为

,那么隐藏层的输出

计算为:

其中隐藏层权􏰀重参数 

,隐藏层偏差参数

,h为隐藏单元数。上式相加的两项形状不同,因此将按照⼴播机制相加。把隐藏变量H作为输出层的输入,且设输出个数为q(如分类问题中的类别数),输出层的输出为:

其中输出变量

,输出层权重参数

,输出层偏差参数 

.如果是分类问 题,我们可以使⽤softmax(O)来计算输出类别的概率分布。

 

2. 含隐藏状态的循环神经网络

现在我们考虑输入数据存在时间相关性的情况。假设

是序列中时间步t的小批量输入,

是该时间步的隐藏变量。与多层感知机不同的是,这里我们保存上一时间步的隐藏变量

,并引⼊一个新的权􏰀重参数

,该参数⽤来描述在当前时间步如何使用上一时间步的隐藏变量。具体来说,时间步t的隐藏变量的计算由当前时间步的输⼊和上一时间步的隐藏变量共同决定:

与多层感知机相比,我们在这里添加了

⼀项。由上式中相邻时间步的隐藏变量

之 间的关系可知,这里的隐藏变量能够捕捉截至当前时间步的序列的历史信息,就像是神经⽹络当前时间步的状态或记忆一样。因此,该隐藏变量也称为隐藏状态。由于隐藏状态在当前时间步的定义使用了上一时间步的隐藏状态,上式的计算是循环的。使⽤循环计算的网络即循环神经⽹络(recurrent neural network)。

循环神经网络有很多种不同的构造方法。含上式所定义的隐藏状态的循环神经网络是极为常⻅的一种。 若无特别说明,之后几节中的循环神经网络均基于上式中隐藏状态的循环计算。在时间步t ,输出层的输出和多层感知机中的计算类似:

循环神经网络的参数包括隐藏层的权重􏰀

和偏差

,以及输出层的权重􏰀

和偏差

。值得⼀提的是,即便在不同时间步,循环神经⽹络也始终使⽤这些模型参数。因此,循环神经网络模型参数的数量不随时间步的增加⽽增长(参数共享)。

下图展示了循环神经网络在3个相邻时间步的计算逻辑。在时间步t,隐藏状态的计算可以看成是将输⼊

和和前⼀时间步隐藏状态

连结后输入⼀个激活函数为

的全连接层。该全连接层的输出就是当前时间步的隐藏状态

,且模型参数为

的连接,偏差为

.当前时间步t的隐藏状态

将参与下⼀个时间步t+1的隐藏状态

的计算,并输入到当前时间步t的全连接输出层。

我们刚提到,隐藏状态中

的计算等价于

连结后的矩阵乘以

连结后的矩阵。接下来,我们⽤⼀个具体的例子来验证这一点。首先,我们构造矩阵X、W_xh、H和W_hh,它们的形状分别为(3,1)、(1,4)、(3,4)、(4,4)。将X与W_xh、H与W_hh分别相乘,再把两个乘法运算的结果相加,得到形状为(3, 4)的矩阵。
 import torch print(torch.__version__)
 X, W_xh = torch.randn(3, 1), torch.randn(1, 4) #(batch_size,features)  H, W_hh = torch.randn(3, 4), torch.randn(4, 4) #(batch_size,hidden_units) torch.matmul(X, W_xh) + torch.matmul(H, W_hh)

将矩阵X和H按列(维度1)连结,连结后的形状为(3,5).可见,连结后的矩阵在维度1的长度为矩阵X和H在维度1的长度之和(1+4).然后将矩阵W_xh和W_hh按行(维度0)拼接,连结后的矩阵形状为(5,4).最后两个链接后的矩阵相乘,得到形状和结果相同的矩阵。

 torch.matmul(torch.cat((X, H), dim=1), torch.cat((W_xh, W_hh), dim=0))

 

3. 应用:基于字符级循环神经网络的语言模型

最后我们介绍如何应用循环神经网络来构建一个语言模型。设⼩批量中样本数为1(batch_size=1),⽂本序列 为“想”“要”“有”“直”“升”“机”。下图演示了如何使用循环神经网络基于当前和过去的字符来预测下一个字符。在训练时,我们对每个时间步的输出层输出使用softmax运算,然后使用交叉熵损失函数来计算它与标签的误差。在下图中,由于隐藏层中隐藏状态的循环计算,时间步3的输出

取决于⽂本序列“想”“要”“有”。 由于训练数据中该序列的下⼀个词为“直”,时间步3的损失将取决于该时间步基于序列“想”“要”“有”生成下⼀个词的概率分布与该时间步的标签“直”。

因为每个输⼊词是一个字符,因此这个模型被称为字符级循环神经⽹络(character-level recurrent neural network)。因为不同字符的个数远小于不同词的个数(对于英⽂尤其如此),所以字符级循环神经网络的计算通常更加简单。在接下来的⼏节里,我们将介绍它的具体实现。

 

4. 小结

1)使用循环计算的网络即循环神经⽹络。

2)循环神经网络的隐藏状态可以捕捉截⾄当前时间步的序列的历史信息。

3)循环神经网络模型参数的数量不随时间步的增加而增长(参数共享)。

4)可以基于字符级循环神经网络来创建语言模型。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!