【2019斯坦福CS224N笔记】(6)RNN和与语言模型

2023-11-07 15:30

本文主要是介绍【2019斯坦福CS224N笔记】(6)RNN和与语言模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

csdn:https://blog.csdn.net/abcgkj

github:https://github.com/aimi-cn/AILearners


一、传统的语言模型

1.什么是语言模型

语言建模是一项基准测试任务,它帮助我们衡量我们在理解语言方面的进展。语言建模是许多NLP任务的子组件,特别是那些涉及生成文本或估计文本概率的任务:预测输入、语音识别、手写识别、拼写/语法修正、身份识别、机器翻译、摘要、对话等。

在实际应用中,我们经常需要解决这样一类问题:如何计算一个句子的概率?而语言模型就是用来解决该问题的。比如我们每天用手机发信息,输入法会自动“联想”你可能输入的下一个字或者词,这就用到了语言模型。
在这里插入图片描述
其实,语言模型就是计算一个单词序列(句子)的概率的模型。那么我们如何计算一个句子的概率呢?给定一个句子(词语序列):S = w1,w2,…,wk,它的概率可以表示为:P(S) = P(w1,w2,…,wk) = p(w1)p(w2|w1)…p(wk|w1,w2,…,wk-1)。但是这样的方法有着严重的缺陷:

  • 參数空间过大:条件概率p(wn|w1,w2,…,wn-1)的可能性太多,无法估算,不可能有用;
  • 数据稀疏严重:对于非常多词对的组合,在语料库中都没有出现,依据最大似然估计得到的概率将会是0。

因此,为了解决上述问题。引入了马尔科夫假设(Markov Assumption):随意一个词出现的概率只与它前面出现的有限的一个或者几个词有关。由此也就有了n-gram语言模型。

2.n-gram语言模型

首先我们看一元语言模型,我们的句子概率定义为:此时整个句子的概率可表示为最大似然估计:
在这里插入图片描述
观察可知,在一元语模型中,整个句子的概率等于各个词语概的乘积。言下之意就是:各个词之间都是相互独立的,这无疑是完全损失了句中的词序信息,所以一元模型的效果并不理想。

接下来是二元语言模型和三元语言模型,此时整个句子的概率可表示为:
在这里插入图片描述
观察可知,在二元模型和三元模型中,整个句子的概率等于n个条件概率相乘,以此类推,就有了n-gram语言模型。那么如何计算上述概率呢?我们可以用统计学的方法近似计算出上述概率。计算方法如下图所示:
在这里插入图片描述
下面我们举一个例子(例子来源于https://class.coursera.org/nlp/):

这个例子来自大一点的语料库,为了计算对应的二元模型的参数,即P(wi | wi-1),我们要先计数即c(wi-1,wi),然后计数c(wi-1),再用除法可得到这些条件概率。可以看到对于c(wi-1,wi)来说,wi-1有语料库词典大小(记作|V|)的可能取值,wi也是,所以c(wi-1,wi)要计算的个数有|V|^2。

c(wi-1,wi)计数结果如下:
在这里插入图片描述
c(wi-1)的计数结果如下:
在这里插入图片描述
那么二元模型的参数计算结果如下:
在这里插入图片描述
比如计算其中的P(want | i) = 0.33如下:
在这里插入图片描述
那么针对这个语料库的二元模型建立好了后,我们可以计算我们的目标,即一个句子的概率了。显然当n>=2时,该模型是可以保留一定的词序信息的,而且n越大,保留的词序信息越丰富,但是计算成本也呈指数级增长,并且这也就有了n-gram模型的两个问题:稀疏性和存储问题。

首先,对于稀疏性问题主要来源于两个方面:

  • 分子为0,即count(w1,w2,w3)等于0,则进而导致P(w3|w1,w2)等于0,模型试图说明这个句子不太可能出现,而事实上只是它以前没有见过而已,所以我们需要采取“平滑”方法来解决这个问题,它的解决问题的基本思想就是把在训练集中看到的概率分一点给未看到的,并保持概率和为1。
  • 分目为0,即count(w1,w2)等于0,我们可以采取“回退”的方法。比如说:要计算p(wn | wn-2,wn-1),但没有相关的三元统计,就可以使用二元语法P(wn | wn-2)来估计,如果没有相关的二元统计,那么我们就用一元模型P(wn)来估计。因此,n的增加使稀疏性问题变得更糟,所以一般情况下n不能大于5。

如果大家想了解更多关于解决稀疏性问题的方法,可以参考Statistical language model 统计语言模型

其次,是存储问题。需要存储在语料库中看到的所有n-gram的计数。随着n的增加(或者语料库大小的增加),模型的大小也随之增加。

二、基于窗口的神经语言模型

Bengio et al提出了第一个大规模深度学习自然语言处理模型,只不过是用前n个单词的词向量来做同样的事情(上文建模)而已,其网络结构如下:
在这里插入图片描述
公式如下:
在这里插入图片描述
这里W(3)x+b(3)就是前n个单词词向量的线性运算,虽然这种模型名字里有“Neural”,但依然属于传统模型。

三、Recurrent Neural Networks

1.初识RNN语言模型

利用RNN对序列建模,复用不同时刻的线性非线性单元及权值,理论上之前所有的单词都会影响到预测单词。
在这里插入图片描述
上图为RNN的结构,其中垂直矩形框是时间步长t处的隐藏层,每个隐藏层包含多个神经元,每个神经元对其输入进行线性矩阵运算,然后进行非线性运算(如tanh())。在每个时间步长中,隐藏层有两个输入:前一层的输出h_{t-1}和该时刻的输入x_t。最后通过输出层获得预测下一个单词。

举个例子来说,假设我们输入一个单词序列: the students opened their,来预测下一个单词,如下图所示:
在这里插入图片描述

  • 输入层x^(t)是每个单词的one-hot向量编码,再乘上word embedding矩阵E得到e^t

  • 隐藏层的状态计算如下图所示:
    在这里插入图片描述
    如上图可以看到,每个时间步的隐藏层状态都由之前隐藏层状态和当前的输入决定。

  • 输出层可以通过一个softmax函数进行预测下一个单词

  • 这里需要注意的是,在整个过程中学习的权重W_h和W_e是一样的,因此减少了需要学习的参数数量,并且参数的数量与输入序列的长度无关,因此不会出现n-gram存在的问题。

我们来小结一下RNN语言模型的优点:

  • 可以处理任意长度的输入
  • 步骤t的计算(理论上)可以使用来自之前所有步骤的信息,而不仅是一个窗口
  • 模型大小不会随着输入时间的增加而增加。在每个时间步上应用相同的权重。

当然,这样做也有一些缺点:

  • RNN计算是十分缓慢的。因为每个时间步的计算都需要先计算之前的序列,所以不能并行计算多个时间步
  • 在实践中,存在梯度消失和爆炸问题,因此很难从许多步骤中获取信息

2.如何训练RNN语言模型

  • 首先我们需要一个大的文本语料库

  • 把其放到RNN语言模型中,计算每个时间步t的输出

  • 定义损失函数,一般采用分类问题中常见的交叉熵损失函数:
    在这里插入图片描述

  • 取平均值,得到整个训练集的总损失
    在这里插入图片描述
    然而,在整个语料库上计算需要花费大量的时间。所以,在实际中我们可以采用随机梯度下降法批量计算损失和梯度然后进行更新。

  • 反向传播用于RNN,计算loss的导数
    在这里插入图片描述
    在这里插入图片描述
    (如果对反向传播不是很了解的童鞋可以点击反向传播)

四、评估语言模型

语言模型的标准评价指标是“perplexity”
在这里插入图片描述
这等于交叉熵损失的指数:
在这里插入图片描述
几种语言模型perplexity的比较:
在这里插入图片描述

五、使用RNN语言模型生成文本

你可以在任何类型的文本上训练RNN-LM,然后生成这种样式的文本。让我们来看一些RNN语言模型一些有趣的例子。

1.RNN-LM训练奥巴马演讲

链接
在这里插入图片描述
在这里插入图片描述

2.RNN-LM训练哈利波特

链接
在这里插入图片描述
在这里插入图片描述

3.RNN-LM训练食谱

链接
在这里插入图片描述
在这里插入图片描述

4.RNN-LM训练颜色名称

链接
在这里插入图片描述
除此之外,RNN还有许多的作用。比如:词性标注、命名实体识别、情感分类、句子分类、回答问题,机器翻译,许多其他任务!更为重要的是,RNN可以用作编码器模块。

在接下来的课程中,我们将会介绍RNN的梯度消失问题,以及RNN的其他版本:GRU、LSTM等结构。

喜欢的童鞋记得分享给别的小伙伴哈。AIMI-CN AI学习交流群【1015286623】 获取更多AI资料扫码加群:

分享技术,乐享生活:我们的公众号每周推送“AI”系列资讯类文章,欢迎您的关注!
在这里插入图片描述

这篇关于【2019斯坦福CS224N笔记】(6)RNN和与语言模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/364579

相关文章

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Go语言如何判断两张图片的相似度

《Go语言如何判断两张图片的相似度》这篇文章主要为大家详细介绍了Go语言如何中实现判断两张图片的相似度的两种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个

Go语言中Recover机制的使用

《Go语言中Recover机制的使用》Go语言的recover机制通过defer函数捕获panic,实现异常恢复与程序稳定性,具有一定的参考价值,感兴趣的可以了解一下... 目录引言Recover 的基本概念基本代码示例简单的 Recover 示例嵌套函数中的 Recover项目场景中的应用Web 服务器中

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

Go语言中使用JWT进行身份验证的几种方式

《Go语言中使用JWT进行身份验证的几种方式》本文主要介绍了Go语言中使用JWT进行身份验证的几种方式,包括dgrijalva/jwt-go、golang-jwt/jwt、lestrrat-go/jw... 目录简介1. github.com/dgrijalva/jwt-go安装:使用示例:解释:2. gi

Go 语言中的 Struct Tag 的用法详解

《Go语言中的StructTag的用法详解》在Go语言中,结构体字段标签(StructTag)是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如JSON、XML)、ORM映... 目录一、结构体标签的基本语法二、json:"token"的具体含义三、常见的标签格式变体四、使用示例五、使用

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态:

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

如何合理管控Java语言的异常

《如何合理管控Java语言的异常》:本文主要介绍如何合理管控Java语言的异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、Thorwable类3、Error4、Exception类4.1、检查异常4.2、运行时异常5、处理方式5.1. 捕获异常