NLP学习笔记(一) RNN基本介绍

简介: NLP学习笔记(一) RNN基本介绍

前言


大家好,我是半虹,这篇文章来讲循环神经网络 (Recurrent Neural Network, RNN)

文章行文思路如下:

  1. 首先通过前馈神经网络引出为啥需要循环神经网络
  2. 然后介绍循环神经网络的核心思想与运作方式
  3. 最后拓展两个循环神经网络常见且常用的变体


正文


在讲循环神经网络前,先来回顾下前馈神经网络,这是深度学习中最基础的网络结构之一

前馈神经网络也称为多层感知机,由多个隐藏层叠加得到,每个隐藏层可看作是一个线性模型加激活函数

为简单起见,这里先以单层感知机为例进行介绍

888.png


上图是单层感知机的结构示意图,其中,X XX 是输入,H HH 是输出


对应的公式表达如下所示:

H=α(XWxh+bh)


其中,Wxh 和Bh都是隐藏层的参数,表示可学习的权重矩阵,α \alphaα 是激活函数


研究表明,前馈神经网络具有很强的学习能力,只要有足够多训练数据,理论上能拟合任意函数


既然如此,那为什么还需要有循环神经网络呢


这是因为前馈神经网络只能单独处理每个输入,对于网络而言,前一个输入和后一个输入是没有任何关系的


这在处理时序数据时前馈神经网络就会显得力不从心,一个典型的场景就是文本处理



举个例子,假设现在我们需要完成一个词性标注任务,给定的句子是:我在看画


如果用前馈神经网络完成上述任务时,就会出现下面的情况:

8.png

这是因为前馈神经网络对于句子中的每个词都是独立处理的


对于画这个词,在不给定上下文的情况下,它既可以是动词,也可以是名词,这时候网络无法判断它的词性


而人是怎么判断词性的呢?当我们发现看是动词时,自然就能推断画是名词,因为动词后接的是名词

这就引出一个重要的结论,在处理文本时,网络需要根据之前的词语来理解当前的词语

9.png

这就是循环神经网络的核心,在处理序列当前的数据时,同时考虑序列之前的数据

循环神经网络是怎么做到这一点的呢?答案就是:使用一个隐状态保存之前的信息,具体网络结构请看下图:

要注意这里的隐状态跟隐藏层不是一回事噢

66.png


上图左半部分是循环神经网络的结构示意图,右半部分是其按时间展开的示意图

可以看到,循环神经网络当前隐藏层的输出不仅取决于当前的输入,而且取决于先前隐藏层的输出

对应的公式表达如下所示:

Ht=α(XtWxh+Ht1Whh+bh)

其中,Ht是当前隐藏层,Xt是当前输入,H t − 1是先前隐藏层,Wxh、Whh和bh都是可学习的参数


对比循环神经网络和前馈神经网络的结构表示和公式表达,可以很清楚地发现两者的区别


在结构表示上,循环神经网络增加了一个隐状态,能保存上一个隐藏层的信息


在公式表达上,循环神经网络计算当前隐藏层时,不仅取决于当前输入,还会考虑先前的隐藏层


能理解这两点,就能理解循环神经网络的核心思想



为了帮助大家进一步理解循环神经网络的工作方式,下面我们举一个例子来说,并给出关键代码


假设我们用循环神经网络对下面这个句子进行编码:我在画画

import torch
import torch.nn as nn
# 定义输入数据
# 对于输入句子我在画画,首先用独热编码得到其向量表示
x1 = torch.tensor([1, 0, 0]).float() # 我
x2 = torch.tensor([0, 1, 0]).float() # 在
x3 = torch.tensor([0, 0, 1]).float() # 画
x4 = torch.tensor([0, 0, 1]).float() # 画
h0 = torch.zeros(5) # 初始化隐状态
# 定义模型参数
# 模型的输入是三维向量,这里定义模型的输出是五维向量
W_xh = nn.Parameter(torch.randn(3, 5), requires_grad = True)
W_hh = nn.Parameter(torch.randn(5, 5), requires_grad = True)
b_h  = nn.Parameter(torch.randn(5)   , requires_grad = True)
# 前向传播
h1 = torch.tanh(torch.matmul(x1, W_xh) + torch.matmul(h0, W_hh) + b_h)
h2 = torch.tanh(torch.matmul(x2, W_xh) + torch.matmul(h1, W_hh) + b_h)
h3 = torch.tanh(torch.matmul(x3, W_xh) + torch.matmul(h2, W_hh) + b_h)
h4 = torch.tanh(torch.matmul(x4, W_xh) + torch.matmul(h3, W_hh) + b_h)
# 结果验证
# 可以发现,即使是对于同一个词语,得到的表示也是不一样的
# 这是因为在计算当前词语时,会考虑先前的词语
print(h3) # tensor([0.9787, 0.9974, 0.9995, 0.9999, 0.9970])
print(h4) # tensor([0.6867, 0.6352, 0.9994, 0.2269, 0.9801])

至此,我们已经介绍了循环神经网络的基本原理


下面再补充循环神经网络的两个变体,深度循环神经网络以及双向循环神经网络



不知道大家是否还记得,文章开头我们是通过单层感知机来引出循环神经网络的


对比单层感知机拓展成多层感知机时,普通的循环神经网络同理可以拓展成深度循环神经网络


其按时间展开的示意图如下所示:

cc.png

可以看到,上图有 L 个隐藏层、T 个时间步,其中 X 是输入,H 是隐藏层的输出


从横向看,上一步隐藏层输出作为下一步隐藏层输入,这和普通的循环神经网络是一样的


从纵向看,上一层隐藏层输出作为下一层隐藏层输入,这是普通的循环神经网络上进行的堆叠


不难发现,当 L=1时,就是普通的循环神经网络


在实际应用中,通常会取最后一层隐藏层的输出 H t ( L )  作为每个时间步输入Xt的表示


而另一个循环神经网络的变种是双向循环神经网络


上面我们所讲的循环神经网络都是从左往右递推的,这让我们可以根据前文的语义理解当前的词语


但有的时候,后文的语义对于当前词语的理解也同样重要


因此我们不妨在从左往右递推的基础上,补一个从右往左的递推,这就是双向循环神经网络


其按时间展开的示意图如下所示:

啊啊.png

如图所示,其中 X是输入,H →是从左往右的隐藏层输出,H ← 是从右往左的隐藏层输出


在实际应用中,通常会取两个隐藏层输出的拼接 [ H → t   ;   H ← t ]  作为每个时间步输入Xt的表示


至此本文结束,要点总结如下:


循环神经网络可以有效地处理时序数据,弥补前馈神经网络的缺陷


循环神经网络的核心在于当前输出不仅由当前输入决定,还由先前的输出决定

这是通过增加隐状态在上一时间步保存、在下一时间步读取而实现的


深度循环神经网络和双向循环神经网络是循环神经网络的两个变体


目录
相关文章
|
12月前
|
机器学习/深度学习 存储 自然语言处理
图解NLP模型发展:从RNN到Transformer
本文以NLP模型发展为脉络,详细地解释了RNN、LSTM、GRU、seq2seq、注意力机制和Transformer。每一个技术都给出了清晰的图形化解释,便于大家理解。其中重点解释了Transformer的各个部分,因为Transformer 作为一个重要的里程碑,影响并创建了许多先进的 NLP 模型,如 GPT-3、BERT 等。
690 1
图解NLP模型发展:从RNN到Transformer
|
自然语言处理 算法
NLP学习笔记(十) 分词(下)
NLP学习笔记(十) 分词(下)
103 0
|
机器学习/深度学习 自然语言处理
NLP学习笔记(八) GPT简明介绍 下
NLP学习笔记(八) GPT简明介绍
131 0
|
自然语言处理
NLP学习笔记(八) GPT简明介绍 上
NLP学习笔记(八) GPT简明介绍
112 0
|
自然语言处理
NLP学习笔记(七) BERT简明介绍 下
NLP学习笔记(七) BERT简明介绍
151 0
NLP学习笔记(七) BERT简明介绍 下
|
机器学习/深度学习 自然语言处理
NLP学习笔记(七) BERT简明介绍 上
NLP学习笔记(七) BERT简明介绍
93 0
|
机器学习/深度学习 自然语言处理 计算机视觉
NLP学习笔记(六) Transformer简明介绍
NLP学习笔记(六) Transformer简明介绍
142 0
|
机器学习/深度学习 自然语言处理
NLP学习笔记(五) 注意力机制
NLP学习笔记(五) 注意力机制
114 0
|
机器学习/深度学习 自然语言处理
NLP学习笔记(四) Seq2Seq基本介绍
NLP学习笔记(四) Seq2Seq基本介绍
120 0
|
机器学习/深度学习 自然语言处理
NLP学习笔记(三) GRU基本介绍
NLP学习笔记(三) GRU基本介绍
196 0

热门文章

最新文章