0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PyTorch教程-9.3. 语言模型

jf_pJlTbmA9 来源:PyTorch 作者:PyTorch 2023-06-05 15:44 次阅读

在9.2 节中,我们将看到如何将文本序列映射到标记中,其中这些标记可以被视为一系列离散的观察结果,例如单词或字符。假设文本序列中的标记长度T依次是 x1,x2,…,xT. 语言模型的目标是估计整个序列的联合概率:

(9.3.1)P(x1,x2,…,xT),

其中可以应用第 9.1 节中的统计工具。

语言模型非常有用。例如,一个理想的语言模型将能够自行生成自然文本,只需一次绘制一个标记即可 xt∼P(xt∣xt−1,…,x1). 与使用打字机的猴子完全不同,从这种模型中出现的所有文本都将作为自然语言传递,例如英文文本。此外,只需在先前的对话片段上调节文本,就足以生成有意义的对话。显然,我们离设计这样一个系统还有很长的路要走,因为它需要理解文本,而不仅仅是生成语法合理的内容。

尽管如此,语言模型即使在其有限的形式下也能提供很好的服务。例如,“to recognize speech”和“to wreck a nice beach”这两个短语听起来非常相似。这可能会导致语音识别中出现歧义,这很容易通过一种语言模型来解决,该模型拒绝将第二种翻译认为是古怪的。同样,在文档摘要算法中,值得知道“狗咬人”比“人咬狗”更频繁,或者“我想吃奶奶”是一个相当令人不安的陈述,而“我想吃,奶奶”要温和得多。

import torch
from d2l import torch as d2l

from mxnet import np, npx
from d2l import mxnet as d2l

npx.set_np()

from jax import numpy as jnp
from d2l import jax as d2l

No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)

import tensorflow as tf
from d2l import tensorflow as d2l

9.3.1. 学习语言模型

显而易见的问题是我们应该如何对文档甚至一系列标记进行建模。假设我们在单词级别标记文本数据。让我们从应用基本概率规则开始:

(9.3.2)P(x1,x2,…,xT)=∏t=1TP(xt∣x1,…,xt−1).

例如,包含四个单词的文本序列的概率为:

(9.3.3)P(deep,learning,is,fun)=P(deep)P(learning∣deep)P(is∣deep,learning)P(fun∣deep,learning,is).

9.3.1.1. 马尔可夫模型和n-克

在9.1节的序列模型分析中,我们将马尔可夫模型应用到语言建模中。序列上的分布满足一阶马尔可夫性质,如果 P(xt+1∣xt,…,x1)=P(xt+1∣xt). 更高的阶数对应更长的依赖关系。这导致我们可以应用一些近似值来对序列建模:

(9.3.4)P(x1,x2,x3,x4)=P(x1)P(x2)P(x3)P(x4),P(x1,x2,x3,x4)=P(x1)P(x2∣x1)P(x3∣x2)P(x4∣x3),P(x1,x2,x3,x4)=P(x1)P(x2∣x1)P(x3∣x1,x2)P(x4∣x2,x3).

涉及一个、两个和三个变量的概率公式通常分别称为一元模型、二元模型和三元模型。为了计算语言模型,我们需要计算单词的概率和给定前几个单词的单词的条件概率。请注意,此类概率是语言模型参数

9.3.1.2. 词频

在这里,我们假设训练数据集是一个大型文本语料库,例如所有维基百科词条、古腾堡计划和网络上发布的所有文本。可以根据训练数据集中给定单词的相对单词频率计算单词的概率。例如,估计P^(deep)可以计算为任何以单词“deep”开头的句子的概率。一种不太准确的方法是计算“deep”这个词的所有出现次数,然后除以语料库中的单词总数。这工作得很好,特别是对于频繁出现的单词。继续,我们可以尝试估计

(9.3.5)P^(learning∣deep)=n(deep, learning)n(deep),

在哪里n(x)和n(x,x′)分别是单个词和连续词对的出现次数。不幸的是,估计单词对的概率有点困难,因为“深度学习”的出现频率要低得多。特别是,对于一些不常见的单词组合,可能很难找到足够多的出现次数来获得准确的估计。正如第 9.2.5 节中的实证结果所表明的那样,对于三词组合及以上,情况会变得更糟。将有许多我们可能不会在我们的数据集中看到的似是而非的三词组合。除非我们提供一些解决方案来分配此类单词组合的非零计数,否则我们将无法在语言模型中使用它们。如果数据集很小或者单词非常罕见,我们可能连一个都找不到。

9.3.1.3. 拉普拉斯平滑

一种常见的策略是执行某种形式的拉普拉斯平滑。解决方案是为所有计数添加一个小常数。表示为n 训练集中的单词总数和m唯一单词的数量。该解决方案有助于单例,例如,通过

(9.3.6)P^(x)=n(x)+ϵ1/mn+ϵ1,P^(x′∣x)=n(x,x′)+ϵ2P^(x′)n(x)+ϵ2,P^(x″∣x,x′)=n(x,x′,x″)+ϵ3P^(x″)n(x,x′)+ϵ3.

这里ϵ1,ϵ2, 和ϵ3是超参数。拿ϵ1例如:当 ϵ1=0, 没有应用平滑;什么时候ϵ1 接近正无穷大,P^(x)接近均匀概率1/m. 以上是其他技术可以实现的相当原始的变体 (Wood等人,2011 年)。

不幸的是,由于以下原因,这样的模型很快就会变得笨拙。首先,如第 9.2.5 节所述 ,许多n-grams 很少出现,这使得拉普拉斯平滑不适合语言建模。其次,我们需要存储所有计数。第三,这完全忽略了文字的意思。例如,“cat”和“feline”应该出现在相关的语境中。很难将此类模型调整到其他上下文,而基于深度学习的语言模型非常适合将这一点考虑在内。最后,长单词序列几乎肯定是新颖的,因此简单地计算以前见过的单词序列频率的模型在这方面肯定表现不佳。因此,我们将在本章的其余部分重点介绍使用神经网络进行语言建模。

9.3.2. 困惑

接下来,让我们讨论如何衡量语言模型的质量,这将在后续部分中用于评估我们的模型。一种方法是检查文本有多令人惊讶。一个好的语言模型能够用高精度的标记来预测我们接下来会看到什么。考虑不同语言模型提出的短语“It is raining”的以下延续:

“外面下雨了”

“香蕉树下雨了”

“正在下雨 piouw;kcj pwepoiut”

就质量而言,示例 1 显然是最好的。言辞合情合理,逻辑连贯。虽然它可能不能完全准确地反映出哪个词在语义上跟随(“在旧金山”和“在冬天”将是完全合理的扩展),但该模型能够捕捉到哪个词跟随在后面。示例 2 通过生成无意义的扩展而变得相当糟糕。尽管如此,至少该模型已经学会了如何拼写单词以及单词之间的某种程度的相关性。最后,示例 3 表明训练有素的模型无法正确拟合数据。

我们可以通过计算序列的可能性来衡量模型的质量。不幸的是,这是一个难以理解和比较的数字。毕竟,较短的序列比较长的序列更有可能出现,因此评估托尔斯泰的巨著《战争与和平》中的模型将不可避免地产生比圣埃克苏佩里的中篇小说《小王子》小得多的可能性。缺少的是相当于平均值。

信息论在这里派上用场。我们在介绍 softmax 回归时定义了熵、惊奇和交叉熵(第 4.1.3 节)。如果我们想压缩文本,我们可以询问在给定当前标记集的情况下预测下一个标记。更好的语言模型应该能让我们更准确地预测下一个标记。因此,它应该允许我们在压缩序列时花费更少的比特。所以我们可以通过对所有数据进行平均的交叉熵损失来衡量它n序列的标记:

(9.3.7)1n∑t=1n−log⁡P(xt∣xt−1,…,x1),

在哪里P由语言模型给出,并且xt是在时间步观察到的实际标记t从序列。这使得不同长度文档的性能具有可比性。由于历史原因,自然语言处理领域的科学家更喜欢使用一种叫做困惑度的量。简而言之,它是(9.3.7)的指数:

(9.3.8)exp⁡(−1n∑t=1nlog⁡P(xt∣xt−1,…,x1)).

困惑度可以最好地理解为我们在决定下一步选择哪个标记时所拥有的实际选择数量的几何平均值。让我们看一些案例:

在最好的情况下,模型总是完美地将目标标记的概率估计为 1。在这种情况下,模型的困惑度为 1。

在最坏的情况下,模型总是预测目标标记的概率为 0。在这种情况下,困惑度为正无穷大。

在基线上,该模型预测词汇表中所有可用标记的均匀分布。在这种情况下,困惑度等于词汇表中唯一标记的数量。事实上,如果我们要在不进行任何压缩的情况下存储序列,这将是我们对它进行编码所能做的最好的事情。因此,这提供了一个重要的上限,任何有用的模型都必须击败它。

9.3.3. 分区序列

我们将使用神经网络设计语言模型,并使用困惑度来评估模型在给定文本序列中的当前标记集的情况下预测下一个标记的能力。在介绍该模型之前,我们假设它一次处理一小批具有预定义长度的序列。现在的问题是如何随机读取输入序列和目标序列的小批量。

假设数据集采用一系列的形式T中的令牌索引corpus。我们将把它分成子序列,其中每个子序列有n令牌(时间步长)。为每个时期迭代(几乎)整个数据集的所有标记并获得所有可能的长度 -n子序列,我们可以引入随机性。更具体地说,在每个时代的开始,丢弃第一个d令牌,在哪里d∈[0,n)是随机均匀采样的。然后将序列的其余部分划分为 m=⌊(T−d)/n⌋子序列。表示为 xt=[xt,…,xt+n−1]长度-n 从令牌开始的子序列xt在时间步t. 所结果的m分区子序列是 xd,xd+n,…,xd+n(m−1).每个子序列将用作语言模型的输入序列。

对于语言建模,目标是根据我们目前看到的标记预测下一个标记,因此目标(标签)是原始序列,移动一个标记。任何输入序列的目标序列xt是xt+1有长度n.

pYYBAGR9NmyAYow8AAIPqjz08xs740.svg

图 9.3.1从分割的长度为 5 的子序列中获得 5 对输入序列和目标序列。

图 9.3.1显示了获得 5 对输入序列和目标序列的示例n=5和d=2.

@d2l.add_to_class(d2l.TimeMachine) #@save
def __init__(self, batch_size, num_steps, num_train=10000, num_val=5000):
  super(d2l.TimeMachine, self).__init__()
  self.save_hyperparameters()
  corpus, self.vocab = self.build(self._download())
  array = torch.tensor([corpus[i:i+num_steps+1]
            for i in range(len(corpus)-num_steps)])
  self.X, self.Y = array[:,:-1], array[:,1:]

@d2l.add_to_class(d2l.TimeMachine) #@save
def __init__(self, batch_size, num_steps, num_train=10000, num_val=5000):
  super(d2l.TimeMachine, self).__init__()
  self.save_hyperparameters()
  corpus, self.vocab = self.build(self._download())
  array = np.array([corpus[i:i+num_steps+1]
            for i in range(len(corpus)-num_steps)])
  self.X, self.Y = array[:,:-1], array[:,1:]

@d2l.add_to_class(d2l.TimeMachine) #@save
def __init__(self, batch_size, num_steps, num_train=10000, num_val=5000):
  super(d2l.TimeMachine, self).__init__()
  self.save_hyperparameters()
  corpus, self.vocab = self.build(self._download())
  array = jnp.array([corpus[i:i+num_steps+1]
            for i in range(len(corpus)-num_steps)])
  self.X, self.Y = array[:,:-1], array[:,1:]

@d2l.add_to_class(d2l.TimeMachine) #@save
def __init__(self, batch_size, num_steps, num_train=10000, num_val=5000):
  super(d2l.TimeMachine, self).__init__()
  self.save_hyperparameters()
  corpus, self.vocab = self.build(self._download())
  array = tf.constant([corpus[i:i+num_steps+1]
            for i in range(len(corpus)-num_steps)])
  self.X, self.Y = array[:,:-1], array[:,1:]

为了训练语言模型,我们将在小批量中随机抽取输入序列和目标序列对。以下数据加载器每次从数据集中随机生成一个小批量。参数 batch_size指定每个小批量中子序列示例的数量,并且num_steps是以标记为单位的子序列长度。

@d2l.add_to_class(d2l.TimeMachine) #@save
def get_dataloader(self, train):
  idx = slice(0, self.num_train) if train else slice(
    self.num_train, self.num_train + self.num_val)
  return self.get_tensorloader([self.X, self.Y], train, idx)

正如我们在下面看到的,可以通过将输入序列移动一个标记来获得一小批目标序列。

data = d2l.TimeMachine(batch_size=2, num_steps=10)
for X, Y in data.train_dataloader():
  print('X:', X, 'nY:', Y)
  break

X: tensor([[ 0, 5, 10, 14, 6, 15, 20, 10, 16, 15],
    [ 5, 10, 7, 7, 6, 19, 6, 15, 4, 6]])
Y: tensor([[ 5, 10, 14, 6, 15, 20, 10, 16, 15, 0],
    [10, 7, 7, 6, 19, 6, 15, 4, 6, 0]])

data = d2l.TimeMachine(batch_size=2, num_steps=10)
for X, Y in data.train_dataloader():
  print('X:', X, 'nY:', Y)
  break

X: [[14. 6. 15. 21. 0. 14. 26. 0. 5. 6.]
 [ 0. 2. 0. 7. 16. 22. 19. 21. 9. 0.]]
Y: [[ 6. 15. 21. 0. 14. 26. 0. 5. 6. 2.]
 [ 2. 0. 7. 16. 22. 19. 21. 9. 0. 5.]]

data = d2l.TimeMachine(batch_size=2, num_steps=10)
for X, Y in data.train_dataloader():
  print('X:', X, 'nY:', Y)
  break

X: [[13 10 14 10 21 20 0 22 20 0]
 [ 0 14 16 23 6 20 0 10 15 21]]
Y: [[10 14 10 21 20 0 22 20 0 21]
 [14 16 23 6 20 0 10 15 21 6]]

data = d2l.TimeMachine(batch_size=2, num_steps=10)
for X, Y in data.train_dataloader():
  print('X:', X, 'nY:', Y)
  break

X: tf.Tensor(
[[13 26 0 21 24 16 0 5 10 14]
 [22 20 15 6 20 20 0 14 16 23]], shape=(2, 10), dtype=int32)
Y: tf.Tensor(
[[26 0 21 24 16 0 5 10 14 6]
 [20 15 6 20 20 0 14 16 23 6]], shape=(2, 10), dtype=int32)

9.3.4. 总结与讨论

语言模型估计文本序列的联合概率。对于长序列,n-grams 通过截断依赖关系提供了一个方便的模型。然而,有很多结构但没有足够的频率来通过拉普拉斯平滑有效地处理不常见的单词组合。因此,我们将在后续部分重点介绍神经语言建模。为了训练语言模型,我们可以在小批量中随机抽取输入序列和目标序列对。训练结束后,我们将使用 perplexity 来衡量语言模型的质量。

语言模型可以随着数据大小、模型大小和训练计算量的增加而扩展。大型语言模型可以通过给定输入文本指令预测输出文本来执行所需的任务。正如我们稍后将讨论的(例如, 第 11.9 节),目前,大型语言模型构成了跨不同任务的最先进系统的基础。

9.3.5. 练习

假设有100,000训练数据集中的单词。一个四文库需要存储多少词频和多词邻频?

你将如何模拟对话?

您还能想到哪些其他方法来读取长序列数据?

考虑我们在每个纪元开始时丢弃前几个标记的均匀随机数的方法。

它真的会导致文档序列的完美均匀分布吗?

你必须做些什么才能使事情变得更加统一?

如果我们想让一个序列示例是一个完整的句子,这在小批量抽样中会引入什么样的问题?我们如何解决这个问题?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 语言模型
    +关注

    关注

    0

    文章

    520

    浏览量

    10268
  • pytorch
    +关注

    关注

    2

    文章

    807

    浏览量

    13200
收藏 人收藏

    评论

    相关推荐

    请问电脑端Pytorch训练的模型如何转化为能在ESP32S3平台运行的模型

    由题目, 电脑端Pytorch训练的模型如何转化为能在ESP32S3平台运行的模型? 如何把这个Pytorch模型烧录到ESP32S3上去?
    发表于 06-27 06:06

    Pytorch模型训练实用PDF教程【中文】

    模型部分?还是优化器?只有这样不断的通过可视化诊断你的模型,不断的对症下药,才能训练出一个较满意的模型。本教程内容及结构:本教程内容主要为在 PyTorch 中训练一个
    发表于 12-21 09:18

    Pytorch模型如何通过paddlelite部署到嵌入式设备?

    Pytorch模型如何通过paddlelite部署到嵌入式设备?
    发表于 12-23 09:38

    怎样去解决pytorch模型一直无法加载的问题呢

    rknn的模型转换过程是如何实现的?怎样去解决pytorch模型一直无法加载的问题呢?
    发表于 02-11 06:03

    pytorch模型转化为onxx模型的步骤有哪些

    首先pytorch模型要先转化为onxx模型,然后从onxx模型转化为rknn模型直接转化会出现如下问题,环境都是正确的,论坛询问后也没给出
    发表于 05-09 16:36

    怎样使用PyTorch Hub去加载YOLOv5模型

    在Python>=3.7.0环境中安装requirements.txt,包括PyTorch>=1.7。模型和数据集从最新的 YOLOv5版本自动下载。简单示例此示例从
    发表于 07-22 16:02

    通过Cortex来非常方便的部署PyTorch模型

    到软件中。如何从“跨语言语言模型”转换为谷歌翻译?在这篇博客文章中,我们将了解在生产环境中使用 PyTorch 模型意味着什么,然后介绍一种允许部署任何
    发表于 11-01 15:25

    Pytorch模型转换为DeepViewRT模型时出错怎么解决?

    我正在寻求您的帮助以解决以下问题.. 我在 Windows 10 上安装了 eIQ Toolkit 1.7.3,我想将我的 Pytorch 模型转换为 DeepViewRT (.rtm) 模型,这样
    发表于 06-09 06:42

    如何将PyTorch模型与OpenVINO trade结合使用?

    无法确定如何转换 PyTorch 掩码 R-CNN 模型以配合OpenVINO™使用。
    发表于 08-15 07:04

    pytorch模型转换需要注意的事项有哪些?

    什么是JIT(torch.jit)? 答:JIT(Just-In-Time)是一组编译工具,用于弥合PyTorch研究与生产之间的差距。它允许创建可以在不依赖Python解释器的情况下运行的模型
    发表于 09-18 08:05

    PyTorch教程9.3.语言模型

    电子发烧友网站提供《PyTorch教程9.3.语言模型.pdf》资料免费下载
    发表于 06-05 09:59 0次下载
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>9.3.</b>之<b class='flag-5'>语言</b><b class='flag-5'>模型</b>

    如何加速生成2 PyTorch扩散模型

    加速生成2 PyTorch扩散模型
    的头像 发表于 09-04 16:09 1099次阅读
    如何加速生成2 <b class='flag-5'>PyTorch</b>扩散<b class='flag-5'>模型</b>

    使用PyTorch搭建Transformer模型

    Transformer模型自其问世以来,在自然语言处理(NLP)领域取得了巨大的成功,并成为了许多先进模型(如BERT、GPT等)的基础。本文将深入解读如何使用PyTorch框架搭建T
    的头像 发表于 07-02 11:41 1598次阅读

    如何使用PyTorch建立网络模型

    PyTorch是一个基于Python的开源机器学习库,因其易用性、灵活性和强大的动态图特性,在深度学习领域得到了广泛应用。本文将从PyTorch的基本概念、网络模型构建、优化方法、实际应用等多个方面,深入探讨使用
    的头像 发表于 07-02 14:08 405次阅读

    pytorch中有神经网络模型

    当然,PyTorch是一个广泛使用的深度学习框架,它提供了许多预训练的神经网络模型PyTorch中的神经网络模型 1. 引言 深度学习是一种基于人工神经网络的机器学习技术,它在图像
    的头像 发表于 07-11 09:59 692次阅读