RNN

Dawn ·
更新时间:2024-09-20
· 642 次阅读

不含隐藏状态的神经网络

考虑一个含单隐藏层的多层感知机。给定样本数为nnn、输入个数(特征数或特征向量维度)为ddd的小批量数据样本X∈Rn×d\boldsymbol{X} \in \mathbb{R}^{n \times d}X∈Rn×d。设隐藏层的激活函数为ϕ\phiϕ,那么隐藏层的输出H∈Rn×h\boldsymbol{H} \in \mathbb{R}^{n \times h}H∈Rn×h计算为

H=ϕ(XWxh+bh),\boldsymbol{H} = \phi(\boldsymbol{X} \boldsymbol{W}_{xh} + \boldsymbol{b}_h),H=ϕ(XWxh​+bh​),

其中隐藏层权重参数Wxh∈Rd×h\boldsymbol{W}_{xh} \in \mathbb{R}^{d \times h}Wxh​∈Rd×h,隐藏层偏差参数 bh∈R1×h\boldsymbol{b}_h \in \mathbb{R}^{1 \times h}bh​∈R1×h,hhh为隐藏单元个数。上式相加的两项形状不同,因此将按照广播机制相加。把隐藏变量H\boldsymbol{H}H作为输出层的输入,且设输出个数为qqq(如分类问题中的类别数),输出层的输出为

O=HWhq+bq,\boldsymbol{O} = \boldsymbol{H} \boldsymbol{W}_{hq} + \boldsymbol{b}_q,O=HWhq​+bq​,

其中输出变量O∈Rn×q\boldsymbol{O} \in \mathbb{R}^{n \times q}O∈Rn×q, 输出层权重参数Whq∈Rh×q\boldsymbol{W}_{hq} \in \mathbb{R}^{h \times q}Whq​∈Rh×q, 输出层偏差参数bq∈R1×q\boldsymbol{b}_q \in \mathbb{R}^{1 \times q}bq​∈R1×q。如果是分类问题,我们可以使用softmax(O)\text{softmax}(\boldsymbol{O})softmax(O)来计算输出类别的概率分布。

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

现在考虑输入数据存在时间相关性的情况。假设Xt∈Rn×d\boldsymbol{X}_t \in \mathbb{R}^{n \times d}Xt​∈Rn×d是序列中时间步ttt的小批量输入,Ht∈Rn×h\boldsymbol{H}_t \in \mathbb{R}^{n \times h}Ht​∈Rn×h是该时间步的隐藏变量。与多层感知机不同的是,这里我们保存上一时间步的隐藏变量Ht−1\boldsymbol{H}_{t-1}Ht−1​,并引入一个新的权重参数Whh∈Rh×h\boldsymbol{W}_{hh} \in \mathbb{R}^{h \times h}Whh​∈Rh×h,该参数用来描述在当前时间步如何使用上一时间步的隐藏变量。具体来说,时间步ttt的隐藏变量的计算由当前时间步的输入和上一时间步的隐藏变量共同决定:

Ht=ϕ(XtWxh+Ht−1Whh+bh).\boldsymbol{H}_t = \phi(\boldsymbol{X}_t \boldsymbol{W}_{xh} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{hh} + \boldsymbol{b}_h).Ht​=ϕ(Xt​Wxh​+Ht−1​Whh​+bh​).

与多层感知机相比,我们在这里添加了Ht−1Whh\boldsymbol{H}_{t-1} \boldsymbol{W}_{hh}Ht−1​Whh​一项。由上式中相邻时间步的隐藏变量Ht\boldsymbol{H}_tHt​和Ht−1\boldsymbol{H}_{t-1}Ht−1​之间的关系可知,这里的隐藏变量能够捕捉截至当前时间步的序列的历史信息,就像是神经网络当前时间步的状态或记忆一样。因此,该隐藏变量也称为隐藏状态。由于隐藏状态在当前时间步的定义使用了上一时间步的隐藏状态,上式的计算是循环的。使用循环计算的网络即循环神经网络(recurrent neural network)。

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

Ot=HtWhq+bq.\boldsymbol{O}_t = \boldsymbol{H}_t \boldsymbol{W}_{hq} + \boldsymbol{b}_q.Ot​=Ht​Whq​+bq​.

循环神经网络的参数包括隐藏层的权重Wxh∈Rd×h\boldsymbol{W}_{xh} \in \mathbb{R}^{d \times h}Wxh​∈Rd×h、Whh∈Rh×h\boldsymbol{W}_{hh} \in \mathbb{R}^{h \times h}Whh​∈Rh×h和偏差 bh∈R1×h\boldsymbol{b}_h \in \mathbb{R}^{1 \times h}bh​∈R1×h,以及输出层的权重Whq∈Rh×q\boldsymbol{W}_{hq} \in \mathbb{R}^{h \times q}Whq​∈Rh×q和偏差bq∈R1×q\boldsymbol{b}_q \in \mathbb{R}^{1 \times q}bq​∈R1×q。值得一提的是,即便在不同时间步,循环神经网络也始终使用这些模型参数。因此,循环神经网络模型参数的数量不随时间步的增加而增长。

下图展示了循环神经网络在3个相邻时间步的计算逻辑。在时间步ttt,隐藏状态的计算可以看成是将输入Xt\boldsymbol{X}_tXt​和前一时间步隐藏状态Ht−1\boldsymbol{H}_{t-1}Ht−1​连结后输入一个激活函数为ϕ\phiϕ的全连接层。该全连接层的输出就是当前时间步的隐藏状态Ht\boldsymbol{H}_tHt​,且模型参数为Wxh\boldsymbol{W}_{xh}Wxh​与Whh\boldsymbol{W}_{hh}Whh​的连结,偏差为bh\boldsymbol{b}_hbh​。当前时间步ttt的隐藏状态Ht\boldsymbol{H}_tHt​将参与下一个时间步t+1t+1t+1的隐藏状态Ht+1\boldsymbol{H}_{t+1}Ht+1​的计算,并输入到当前时间步的全连接输出层。
RNN计算逻辑
隐藏状态中XtWxh+Ht−1Whh\boldsymbol{X}_t \boldsymbol{W}_{xh} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{hh}Xt​Wxh​+Ht−1​Whh​的计算等价于Xt\boldsymbol{X}_tXt​与Ht−1\boldsymbol{H}_{t-1}Ht−1​连结后的矩阵乘以Wxh\boldsymbol{W}_{xh}Wxh​与Whh\boldsymbol{W}_{hh}Whh​连结后的矩阵。接下来,我们用一个具体的例子来验证这一点。首先,我们构造矩阵XW_xhHW_hh,它们的形状分别为(3, 1)、(1, 4)、(3, 4)和(4, 4)。将XW_xhHW_hh分别相乘,再把两个乘法运算的结果相加,得到形状为(3, 4)的矩阵。

import torch X, W_xh = torch.randn(3, 1), torch.randn(1, 4) H, W_hh = torch.randn(3, 4), torch.randn(4, 4) torch.matmul(X, W_xh) + torch.matmul(H, W_hh)

输出:

tensor([[ 5.2633, -3.2288, 0.6037, -1.3321], [ 9.4012, -6.7830, 1.0630, -0.1809], [ 7.0355, -2.2361, 0.7469, -3.4667]])

将矩阵XH按列(维度1)连结,连结后的矩阵形状为(3, 5)。可见,连结后矩阵在维度1的长度为矩阵XH在维度1的长度之和(1+41+41+4)。然后,将矩阵W_xhW_hh按行(维度0)连结,连结后的矩阵形状为(5, 4)。最后将两个连结后的矩阵相乘,得到与上面代码输出相同的形状为(3, 4)的矩阵。

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

输出:

tensor([[ 5.2633, -3.2288, 0.6037, -1.3321], [ 9.4012, -6.7830, 1.0630, -0.1809], [ 7.0355, -2.2361, 0.7469, -3.4667]]) 总结 循环神经网络的隐层状态可以捕捉截止到当前时间步的序列和历史信息 循环神经网络模型参数的数量不随时间步的增加而增长 RNN容易出现梯度衰减或爆炸

参考:

动手学pytorch


作者:栋次大次



rnn

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章