时序数据的采样

随机采样

每个样本是原始序列上任意截取的一段序列。相邻的两个随机小批量在原始序列上的位置不一定相毗邻。因此,我们无法用一个小批量最终时间步的隐藏状态来初始化下一个小批量的隐藏状态。在训练模型时,每次随机采样前都需要重新初始化隐藏状态。

相邻采样

相邻的两个随机小批量在原始序列上的位置相毗邻。可以用一个小批量最终时间步的隐藏状态来初始化下一个小批量的隐藏状态,从而使下一个小批量的输出也取决于当前小批量的输入,并如此循环下去。这对实现循环神经网络造成了两方面影响:一方面, 在训练模型时,我们只需在每一个迭代周期开始时初始化隐藏状态;另一方面,当多个相邻小批量通过传递隐藏状态串联起来时,模型参数的梯度计算将依赖所有串联起来的小批量序列。同一迭代周期中,随着迭代次数的增加,梯度的计算开销会越来越大。 为了使模型参数的梯度计算只依赖一次迭代读取的小批量序列,我们可以在每次读取小批量前将隐藏状态从计算图中分离出来。

循环神经网络

Recurrent Neural Network (RNN). 下面我们讨论的架构通常被称为vanilla RNN,即最经典的RNN。

优点

  1. 能够解决记忆的问题,可以处理长序列
  2. 通过隐藏状态来存储之前时间步的信息,参数数量不随时间步的增加而增长
  3. 每个时间步的学习参数都相同

缺点

  1. 计算非常缓慢(不能并行运行)
  2. 实际上只能保存较短暂的内容,序列较长时,最前面的信息产生的作用会非常微弱
  3. 梯度消失的问题

我们首先考虑不含隐藏状态的隐藏层。假设激活函数为ϕ\phiϕ,该层的隐藏单元个数是hhh,样本数为nnn,特征维度是ddd (在此处就是字典大小)。所以数据可以表示成X∈Rn∗dX \in R^{n*d}X∈Rn∗d,该层权重是W∈Rd∗hW \in R^{d*h}W∈Rd∗h。

该隐藏层之后的输出层维度是qqq。
H=ϕ(XWxh+bh)O=HWhq+bqH = \phi(XW_{xh} + b_h) \\\\ O = HW_{hq} + b_q H=ϕ(XWxh​+bh​)O=HWhq​+bq​
现在开始考虑输入数据存在时间相关性的情况。请不要将时间步和矩阵转置混淆,所有出现在变量上方位置的时间步均有括号覆盖。数据可以表示成X(t)∈Rn∗dX^{(t)} \in R^{n*d}X(t)∈Rn∗d,而该时间步的隐藏变量可以表示成H(t)∈Rn∗hH^{(t)} \in R^{n*h}H(t)∈Rn∗h。我们需要引入一个新的权重参数描述当前时间步如何使用上一时间步的隐藏变量,记作Whh∈Rh∗hW_{hh} \in R^{h*h}Whh​∈Rh∗h。
H(t)=ϕ(H(t−1)Whh+X(t)Wxh+bh)O(t)=H(t)Whq+bqH^{(t)} = \phi(H^{(t-1)}W_{hh} + X^{(t)}W_{xh} + b_h) \\\\ O^{(t)} = H^{(t)} W_{hq} + b_q H(t)=ϕ(H(t−1)Whh​+X(t)Wxh​+bh​)O(t)=H(t)Whq​+bq​
下面我们看一个字符级循环神经网络的例子。设小批量中样本数为1,文本序列为“想要有直升机”。下图演示了如何使用循环神经网络基于当前和过去的字符来预测下一个字符。在训练时,我们对每个时间步的输出层输出使用softmax运算,然后使用交叉熵损失函数来计算它与标签的误差。

使用循环神经网络来预测一段文字的下一个词,输出个数是字典中不同词的个数。激活函数ϕ\phiϕ一般会设置为tanh或relu。

损失函数

对于每一步都预测一个词。在第t步的损失如下,
L(t)(θ)=−∑w∈Vyw(t)logy^w(t)=−logy^vec[xt+1](t)L^{(t)}(\theta) = -\sum_{w \in V} y_w^{(t)} log \hat y_w^{(t)} = -log \hat y_{vec[x_{t+1}]}^{(t)} L(t)(θ)=−w∈V∑​yw(t)​logy^​w(t)​=−logy^​vec[xt+1​](t)​
我们可以将时间步ttt的损失记为l(y^(t),y(t))l(\hat y^{(t)}, y^{(t)})l(y^​(t),y(t))。对于数据整体(时间步数为TTT)的损失就是对每一步的损失取平均值。我们称这个算式为有关给定时间步的数据样本的目标函数。
L=1T∑t=1Tl(y^(t),y(t))L = \frac 1 T \sum_{t=1}^T l(\hat y^{(t)}, y^{(t)}) L=T1​t=1∑T​l(y^​(t),y(t))

反向传播

英文是back propagation。

下面这个结论仍然是根据链式法则得到的。中间第二项是1。
∂L(T)∂Wh=∑t=1T∂L(T)∂Wh∣(t)∂Wh∣(t)∂Wh=∑t=1T∂L(t)∂Wh∣(t)\frac {\partial L^{(T)}} {\partial W_h} = \sum_{t=1}^T \frac {\partial L^{(T)}} {\partial W_h |_{(t)}} \frac {\partial W_h |_{(t)}} {\partial W_h}= \sum_{t=1}^T \frac {\partial L^{(t)}} {\partial W_h |_{(t)}} ∂Wh​∂L(T)​=t=1∑T​∂Wh​∣(t)​∂L(T)​∂Wh​∂Wh​∣(t)​​=t=1∑T​∂Wh​∣(t)​∂L(t)​
难点是我们如何计算这个算式。我们只能使用基于时间的反向传播算法(backpropagate through time, BPTT)。

上图展示时间步数为3的循环神经网络模型计算中的依赖关系。方框代表变量(无阴影)或参数(有阴影),圆圈代表运算符。

目标函数有关各时间步输出层变量的梯度比较容易计算。
∂L∂y^(t)=∂l(y^(t),y(t))T∗∂y^(t)\frac {\partial L} {\partial \hat y^{(t)}} = \frac {\partial l(\hat y^{(t)}, y^{(t)})} {T*\partial \hat y^{(t)}} ∂y^​(t)∂L​=T∗∂y^​(t)∂l(y^​(t),y(t))​
我们再计算目标函数有关参数WhqW_{hq}Whq​的梯度,该梯度取决于所有时间步的输出变量。
∂L∂Whq=∑t=1T∂L∂y^(t)∗∂y^(t)∂Whq=∑t=1T∂L∂y^(t)H(t)\frac {\partial L} {\partial W_{hq}} = \sum_{t=1}^T \frac {\partial L} {\partial \hat y^{(t)}}*\frac {\partial \hat y^{(t)}} {\partial W_{hq}} = \sum_{t=1}^T \frac {\partial L} {\partial \hat y^{(t)}} H^{(t)} ∂Whq​∂L​=t=1∑T​∂y^​(t)∂L​∗∂Whq​∂y^​(t)​=t=1∑T​∂y^​(t)∂L​H(t)
接下来我们计算隐藏状态的依赖。LLL只通过最后一个预测依赖最终时间步的隐藏状态。
∂L∂H(T)=∂L∂y^(T)∗∂y^(T)∂H(T)=WhqT∂L∂y^(T)\frac {\partial L} {\partial H^{(T)}} = \frac {\partial L} {\partial \hat y^{(T)}}*\frac{\partial \hat y^{(T)}} {\partial H^{(T)}} = W_{hq}^T \frac {\partial L} {\partial \hat y^{(T)}} ∂H(T)∂L​=∂y^​(T)∂L​∗∂H(T)∂y^​(T)​=WhqT​∂y^​(T)∂L​
不过,对于之前的时间步t<Tt < Tt<T,LLL会通过H(t+1)H^{(t+1)}H(t+1)和y^(t)\hat y^{(t)}y^​(t)依赖H(t)H^{(t)}H(t)。目标函数关于时间步ttt的隐藏状态的梯度需要按照时间步从大到小一次计算。
∂L∂H(t)=∂L∂H(t+1)∗∂H(t+1)∂H(t)+∂L∂y^(t)∗∂y^(t)∂H(t)=WhhT∂L∂H(t+1)+WhqT∂L∂y^(t)\frac {\partial L} {\partial H^{(t)}} = \frac {\partial L} {\partial H^{(t+1)}}*\frac{\partial H^{(t+1)}} {\partial H^{(t)}} + \frac {\partial L} {\partial \hat y^{(t)}}*\frac{\partial \hat y^{(t)}} {\partial H^{(t)}} \\\\ = W_{hh}^T \frac {\partial L} {\partial H^{(t+1)}} + W_{hq}^T \frac {\partial L} {\partial \hat y^{(t)}} ∂H(t)∂L​=∂H(t+1)∂L​∗∂H(t)∂H(t+1)​+∂y^​(t)∂L​∗∂H(t)∂y^​(t)​=WhhT​∂H(t+1)∂L​+WhqT​∂y^​(t)∂L​
我们可以将公式递归展开,对于任意时间步,得到目标函数有关隐藏状态的梯度的通项公式如下,
∂L∂H(t)=∑i=tT(WhhT)(T−i)WhqT∂L∂y^(T+t−i)\frac {\partial L} {\partial H^{(t)}} = \sum_{i=t}^T (W_{hh}^T)^{(T-i)} W_{hq}^T \frac {\partial L} {\partial \hat y^{(T+t-i)}} ∂H(t)∂L​=i=t∑T​(WhhT​)(T−i)WhqT​∂y^​(T+t−i)∂L​
我们可以看到,WhhW_{hh}Whh​在公式中有一个指数项,当T−iT-iT−i较大时,容易出现梯度爆炸和梯度消失的问题。而且,这个问题也会严重影响其他包含该项的梯度。
∂L∂Wxh=∑t=1T∂L∂H(t)∗xtT∂L∂Whh=∑t=1T∂L∂H(t)∗(H(t−1))T\frac {\partial L} {\partial W_{xh}} = \sum_{t=1}^T \frac {\partial L} {\partial H^{(t)}}*x_t^T \\\\ \frac {\partial L} {\partial W_{hh}} = \sum_{t=1}^T \frac {\partial L} {\partial H^{(t)}}* (H^{(t-1)})^T \\\\ ∂Wxh​∂L​=t=1∑T​∂H(t)∂L​∗xtT​∂Whh​∂L​=t=1∑T​∂H(t)∂L​∗(H(t−1))T

应用场景

语言建模,语句情感分析,词性标注。

参数更新

梯度消失

如果这些取导得到的值都非常小,那么在反向传播之后,距离输出层较远的隐层的参数更新会非常缓慢。

上面我们已经推导过一遍。为了计算简便,看起来更加直观,我们假设激活函数是单位函数ϕ(x)=x\phi(x) = xϕ(x)=x。
∂h(t)∂h(t−1)=∂ϕ(Wxx(t)+Whh(t−1)+b)∂h(t−1)=Wh\frac{\partial h^{(t)}}{\partial h^{(t-1)}} \\\\ = \frac {\partial \phi(W_{x}x^{(t)} + W_{h} h^{(t-1)} + b)} {\partial h^{(t-1)}} \\\\ = W_h ∂h(t−1)∂h(t)​=∂h(t−1)∂ϕ(Wx​x(t)+Wh​h(t−1)+b)​=Wh​
假设我们正在计算第iii步的损失的梯度,那么对于之前的第jjj步有如下算式。

∂J(i)(θ)∂h(j)=∂J(i)(θ)∂h(i)∏j<t≤i∂h(t)∂h(t−1)=∂J(i)(θ)∂h(i)∏j<t≤iWh=∂J(i)(θ)∂h(i)Whi−j\frac{\partial J^{(i)}(\theta)}{\partial h^{(j)}} \\\\ = \frac{\partial J^{(i)}(\theta)}{\partial h^{(i)}} \prod_{j<t\le i} \frac{\partial h^{(t)}} {\partial h^{(t-1)}} \\\\ = \frac{\partial J^{(i)}(\theta)}{\partial h^{(i)}} \prod_{j<t\le i} W_h \\\\ = \frac{\partial J^{(i)}(\theta)}{\partial h^{(i)}} W_h^{i-j} ∂h(j)∂J(i)(θ)​=∂h(i)∂J(i)(θ)​j<t≤i∏​∂h(t−1)∂h(t)​=∂h(i)∂J(i)(θ)​j<t≤i∏​Wh​=∂h(i)∂J(i)(θ)​Whi−j​
我们注意到,如果WhW_hWh​非常小的话,那么Whi−jW_h^{i-j}Whi−j​则是成指数倍减小。

梯度消失到底有什么坏处呢?

坏处就是导致RNN在实际应用中难以产生理论上所拥有的长期记忆。因为在经过若干步之后,前面的梯度基本不受到当前步的影响了。出现这种情况的原因既有可能是若干步之前的数据本身就对当前步没有影响,即在数据中长依赖关系本身就不存在;也有可能是参数没有被及时更新,从而导致这种长依赖无法被捕捉到。我们没有办法判断是这两种原因中的哪一种。

在文本处理中,RNN更擅长处理语序新近度(sequential recency)而非语法新近度(syntactic recency),从而更有可能导致在填词的时候判断错误。语法新近度指当前词是用来修饰之前出现过的哪一个词的,而语序新近度是指当前词的前一个词(距离最近)。

梯度爆炸

梯度爆炸出现的原因与梯度消失非常类似,只不过是梯度过大。坏处是容易导致

梯度剪裁

英文gradient clipping应该更为大家所熟知。如果梯度的模大于一个临界值,那么需要在保留方向的前提下减小其模长。

norm = np.linalg.norm(g)
if norm > threshold:g = threshold/norm * g

双向循环神经网络

英文是(Bidirectional RNN)。之前介绍的循环神经网络模型都是假设当前时间步是由前面的较早时间步的序列决定的,因此它们都将信息通过隐藏状态从前往后传递。有时候,当前时间步也可能由后面时间步决定。双向循环神经网络在机器翻译和情感分析中应用广泛,在语言建模中没有用武之地(只给出前文)。所以,使用双向循环神经网络的前提条件就是有完整的序列。
H→(t)=RNNFW(H→(t−1),X(t))H←(t)=RNNBW(H←(t+1),X(t))H(t)=[H→(t);H←(t)]\stackrel{\rightarrow}{H}^{(t)} = RNN_{FW}(\stackrel{\rightarrow}{H}^{(t-1)}, X^{(t)}) \\\\ \stackrel{\leftarrow}{H}^{(t)} = RNN_{BW}(\stackrel{\leftarrow}{H}^{(t+1)}, X^{(t)}) \\\\ {H}^{(t)} = [\stackrel{\rightarrow}{H}^{(t)}; \stackrel{\leftarrow}{H}^{(t)}] H→​(t)=RNNFW​(H→​(t−1),X(t))H←​(t)=RNNBW​(H←​(t+1),X(t))H(t)=[H→​(t);H←​(t)]

深度循环神经网络

英文是multi-layer RNN。深度循环神经网络能够学习到更复杂的信息。较浅的RNN应计算较低级别的特征,较深的RNN应计算较抽象的特征。

隐藏状态的信息不断传递至当前层的下一时间步和当前时间步的下一层。

第一隐藏层的隐藏状态和之前计算完全相同。
H(t,l)=ϕ(H(t−1,l)Whh(l)+X(t)Wxh(l)+bh(l))H^{(t,l)} = \phi(H^{(t-1,l)}W_{hh}^{(l)} + X^{(t)}W_{xh}^{(l)} + b_h^{(l)}) \\\\ H(t,l)=ϕ(H(t−1,l)Whh(l)​+X(t)Wxh(l)​+bh(l)​)
对于层数较深的隐藏层,表达式变成
H(t,l)=ϕ(H(t−1,l)Whh(l)+H(t,l−1)Wxh(l)+bh(l))H^{(t,l)} = \phi(H^{(t-1,l)}W_{hh}^{(l)} + H^{(t,l-1)}W_{xh}^{(l)} + b_h^{(l)}) \\\\ H(t,l)=ϕ(H(t−1,l)Whh(l)​+H(t,l−1)Wxh(l)​+bh(l)​)
输出层的输出仍然只基于第LLL层的隐藏状态。
O(t)=H(t,L)Whq+bqO^{(t)} = H^{(t,L)} W_{hq} + b_q O(t)=H(t,L)Whq​+bq​

Reference

  • Dive Into Deep Learning,第6章
  • Natural Language Processing with Deep Learning (Stanford CS224N), 2019 winter

时序数据采样、原始循环神经网络RNN、RNN梯度爆炸原因推导相关推荐

  1. 神经网络中的梯度爆炸

    神经网络中的梯度爆炸 参考文章:https://blog.csdn.net/Uwr44UOuQcNsUQb60zk2/article/details/78877974 一.什么事梯度爆炸? " ...

  2. 时序模型:循环神经网络(RNN)

    1. 模型定义 循环神经网络(recurrent neural network, RNN)是一类专门设计处理不定长序列数据的神经网络. 与使用一种新计算1作为核心的卷积神经网络不同,循环神经网络仍使用 ...

  3. 循环神经网络(RNN)原理通俗解释

    循环神经网络(RNN)原理通俗解释 1.RNN怎么来的? 2.RNN的网络结构及原理 3.RNN的改进1:双向RNN 4.RNN的改进2:深层双向RNN 4.1 Pyramidal RNN 5.RNN ...

  4. 循环神经网络LSTM RNN回归:sin曲线预测

    摘要:本篇文章将分享循环神经网络LSTM RNN如何实现回归预测. 本文分享自华为云社区<[Python人工智能] 十四.循环神经网络LSTM RNN回归案例之sin曲线预测 丨[百变AI秀]& ...

  5. 循环神经网络(RNN)和LSTM初学者指南 | 入门资料

    原作 Skymind  乾明 编译  量子位 出品 | 公众号 QbitAI 最近,有一篇入门文章引发了不少关注.文章中详细介绍了循环神经网络(RNN),及其变体长短期记忆(LSTM)背后的原理. 具 ...

  6. 大话循环神经网络(RNN)

    -- 原文发布于本人的微信公众号"大数据与人工智能Lab"(BigdataAILab),欢迎关注. 卷积神经网络CNN在图像识别中有着强大.广泛的应用,但有一些场景用CNN却无法得 ...

  7. PyTorch-09 循环神经网络RNNLSTM (时间序列表示、RNN循环神经网络、RNN Layer使用、时间序列预测案例、RNN训练难题、解决梯度离散LSTM、LSTM使用、情感分类问题实战)

    PyTorch-09 循环神经网络RNN&LSTM (时间序列表示.RNN循环神经网络.RNN Layer使用.时间序列预测案例(一层的预测点的案例).RNN训练难题(梯度爆炸和梯度离散)和解 ...

  8. 小常识10: 循环神经网络(RNN)与长短时记忆网络LSTM简介。

    小常识10:  循环神经网络(RNN)与长短时记忆网络LSTM简介. 本文目的:在计算机视觉(CV)中,CNN 通过局部连接/权值共享/池化操作/多层次结构逐层自动的提取特征,适应于处理如图片类的网格 ...

  9. 深度学习原理-----循环神经网络(RNN、LSTM)

    系列文章目录 深度学习原理-----线性回归+梯度下降法 深度学习原理-----逻辑回归算法 深度学习原理-----全连接神经网络 深度学习原理-----卷积神经网络 深度学习原理-----循环神经网 ...

最新文章

  1. P1047 校门外的树(线段树优化)(校门三部曲)难度⭐⭐
  2. 苹果服务器消息转发,iOS 消息推送原理及简单实现
  3. Android开发--Http操作介绍(一)
  4. SAP 物料XXXXX的强制帐户设置 (输入帐户设置类别) 的问题解决方法
  5. shiro认证+授权(使用MD5+salt+散列加密)
  6. vue安装与配置、脚手架
  7. 专家:人工智能开始对现实世界产生重大影响​​
  8. Java Number Tips
  9. 爱情测试MySQL存储_性能测试四十:Mysql存储过程造数据
  10. Ubuntu Linux下安装MySQL
  11. PHP设计模式——备忘录模式
  12. 湖南理工学院图像处理与计算机视觉,信息与通信工程一级学科硕士研究生培养方案...
  13. 干货分享|E-prime 3入门手册
  14. hysys动态模拟教程_学习记录-过程模拟实训-Aspen HYSYS教程
  15. pandas获取全部列名_pandas获取全部列名_pandas DataFrame数据重命名列名的几种方式...
  16. 六祎-简单的排版表(python)
  17. TCP协议——三次握手
  18. 如何防御DDoS攻击和CC攻击
  19. 网站被恶意刷流量解决方案
  20. 统计学——数据的分类

热门文章

  1. Windows自带的端口转发工具netsh使用方法_DOS/BAT
  2. Kubernetes集群监控方案
  3. 《Docker容器:利用Kubernetes、Flannel、Cockpit和Atomic构建和部署》——2.2 容器式Linux系统的Docker配置...
  4. webpack dev server 和 sublime text 配合时需要注意的地方
  5. ARM处理器:开放者的逆袭
  6. 【转】关于MySQL权限
  7. 【转】ASP.NET中页面传值
  8. FPGA设计中MEMORY型数据怎么综合到blockRAM里面
  9. Xilinx FPGA中SRL(移位寄存器)资源
  10. jittor 和pytorch gpu 使用效率对比(惊人jittor的算力利用率是pytorch 4-5倍)