当先锋百科网

首页 1 2 3 4 5 6 7

RNN

什么是RNN

RNN(Recurrent Neural Network),循环神经网络,他一般是一类用于处理序列数据。通过网络内部结构设计有效捕捉序列之间的关系特征,一般也是以序列形式进行。

一般单层神经结构

在这里插入图片描述

RNN单层循环网络结构

输入经过隐藏层并不是直接就输出,而是在隐藏层中循环很多次之后再输出

以时间步对RNN进行展开后的单层网络

在这里插入图片描述
循环N层就有N个
在这里插入图片描述
RNN的循环机制使模型隐藏层上一时间步产生的结果,能够作为当下时间步输入的一部分(当下时间步的输入除了正常的输入外还包括上一步的隐藏层输出)对当下时间步的输出产生影响。

作用

因为RNN结构能够很好的利用序列之间的关系,因此针对自然界具有连续性的输入序列,如人类的语言,语音等。

以NLP为例

输入:What time is it?
RNN是按照序列工作的,每次只接收一个单词进行处理。
第一步:对句子进行分词,
What
time
is
it
5部分
第二步:首先将单词‘What’输送给RNN,它产生一个输出O1
在这里插入图片描述
第三步:继续将单词“time”输送给RNN,但此时RNN不仅仅用“time”来产生输出O2,还会使用来自上一层隐藏层输出的O1作为输入信息
在这里插入图片描述

第四步:重复这样的步骤,知道处理完所有的单词
在这里插入图片描述
第五步:最终将隐藏层输出的O进行处理来解析用户意图
在这里插入图片描述

分类

1.从输入和输出的结构角度

N vs N-RNN

RNN基础的结构形式,最大特点就是:输入和输出序列是等长的,由于限制存在,使其适用范围小,可用于生成等长度的合辙诗句
在这里插入图片描述

N vs 1-RNN

有时候我们要处理的问题输入是-一个序列,而要求输出是-个单独的值而不是序列,应该怎样建模呢?我们只要在最后-一个隐层输出h上进行线性变换就可以了,大部分情况下,为了更好的明确结果,还要使用sigmoid或者softmax进行处理.这种结构经常被应用在文本分类上。
在这里插入图片描述

1 vs N-RNN

如果输入不是序列而输出为序列的情况怎么处理呢?我们最常采用的一种方式就是使该输入作用于每次的输出之上.这种结构可用于将图片生成文字任务等.
在这里插入图片描述

N vs M-RNN

这是一种不限输入输出长度的RNN结构,它由编码器和解码器两部分组成,两者的内部结构都是某类RNN,它被称作为seq2seq架构。输入数据首先通过编码器,最终输出一个隐含变量c,之后最常用的做法是使用这个隐含变量c作用在解码器进行解码的每一步 上,以保证输入信息被有效利用。
在这里插入图片描述
seq2seq架构最早被提出应用于机器翻译,因为其输入输出不受限制,如今也是应用最广泛的RNN模型结构。在机器翻译,阅读理解,文本摘要等众多领域进行了非常多的应用实践。

2. 从RNN内部构造

传统RNN

传统RNN内部结构
在这里插入图片描述
t时的输入是上一个时间步的隐藏层输出和 xt共同作用到当前时间步的隐藏层中,由tanh激活函数激活,输出ht,重复步骤往后。

将中间隐藏层细致分析
在这里插入图片描述
内部结构分析:
●我们把目光集中在中间的方块部分,它的输入有两部分,分别是h(t-1)以及x(t),代表上一时间步的隐层输出,以及此时间步的输入,它们进入RNN结构体后,会"融合"到-起,这种融合我们根据结构解释可知,是将二者进行拼接,形成新的张量[x(t), h(t-1)], 之后这个新的张量将通过一个全连接层(线性层),该层使用tanh作为激活函数,最终得到该时间步的输出h(t),它将作为下一一个时间步的输入和x(t+1)-起进入结构体.以此类推.

根据结构分析得出内部计算公式:
h t = t a n h ( W t [ X t , h t − 1 ] + b t ) h_t=tanh(W_t[X_t,h_{t-1}]+b_t) ht=tanh(Wt[Xt,ht1]+bt)

激活函数的作用:
用于帮助调节流经网络的值,tanh函数将值压缩再-1到1之间
函数如下所示:
在这里插入图片描述

代码实现
nn.RNN类初始化主要参数解释:
●input size: 输入张量x中特征维度的大小.
●hidden_ size: 隐层张量h中特征维度的大小
●num_ layers: 隐含层的数量.
●nonlinearityE激活函数的选择,默认是tanh.

●nn.RNN类实例化对象主要参数解释:
●input: 输入张量x.
●h0: 初始化的隐层张量h.

import torch
import torch.nn.as nn
rnn = nn. RNN(561)
'''5-输入张量维度inputsize
6-隐藏层神经元个数hiddensize
1-只包含一个隐藏层'''

input = torch.randn(1, 35)
'''
1-输入张量的序列长度-比如一次一个字母
3-3个样本
5-输入张量维度,与RNN对应
'''

h0 = torch. randn(1, 3,6)
'''
1-与RNN中的1对应
3-3个样本
6-对应隐藏层维度
'''
output, hn = rnn(input,h0)
output#最终输出
'''
tensor([[[ 0.4282,-0.8475, -0.0685, -0.4601, -0.8357, 0. 1252]
[ 0.5758, -0.2823, 0.4822, -0. 4485,-0.7362, 0. 0084 ]
0.9224,-0.7479, -0.3682, -0.5662, -0.9637, 0.4938]]],
grad_ fn=<StackBackward> )'''

hn
#最后一个神经元输出
'''tensor([[[ 0.4282, -0.8475, -0.0685, -0.4601, -0.8357, 0.1252 ]
0.5758,-0.2823, 0.4822, -0.4485, -0.7362, 0. 0084 ]
0.9224,-0.7479, -0.3682, -0.5662, -0.9637, 0. 4938]]],
grad_ fn=<StackBackward> )'''

传统RNN的优势

●由于内部结构简单,对计算资源要求低,相比之后我们要学习的RNN变体:L .STM和GRU模型
参数总量少了很多,在短序列任务,上性能和效果都表现优异.

传统RNN缺点

●传统RNN的缺点:
●传统RNN在解决长序列之间的关联时,通过实践,证明经典RNN表现很差,原因是在进行反
向传播的时候,过长的序列导致梯度的计算异常,发生梯度消失或爆炸.

●梯度消失或爆炸的危害:
●如果在训练过程中发生了梯度消失,权重无法被更新,最终导致训练失败;梯度爆炸所带
来的梯度过大,大幅度更新网络参数,在极端情况下,结果会溢出(NaN值) .