自然语言作为人类思想感情最基本、最直接、最方便的表达工具,无时无刻不在充斥在人类社会的各个角落。随着信息时代的到来,人们使用自然语言进行通信和交流的形式也越来越多的体现出它的多样性、灵活性和广泛性。然而人脑是如何实现自然语言的理解这一认知过程的?我们应该如何建立语言、知识与客观世界之间的对应关系,并实现有效的概念区分和语义理解?从数学角度讲,语义是否可以计算?计算机处理自然语言在大多数情况下都不能满足人类社会信息化的要求,因此打破不同语言之间的壁垒、为人际之间和人机之间信息交流提供更便捷、自然、有效和人性化的帮助与服务,已经成为极具挑战性的国际前沿研究课题、也是全球社会共同追求的目标和梦想。
NLP (Natural Language Processing)的全称是自然语言处理,是人工智能(AI)的一个子领域,涉及认知科学、计算机科学、语言学、数数学与逻辑学、心理学等多种学科。
NLP研究的内容十分广泛,我们大致可以列举如下一些研究方向:
- 机器翻译(machine translation MT)实现一种语言到另一种语言的自动翻译
- 自动文摘(automatic summarizing 或automatic abstracting)将源文档的主要内容和含义自动归纳、提炼出来、形成摘要或缩写。
- 信息检索(information retrieval)信息检索也成情报检索,就是利用计算机系统从海量文档中找到符合用户需要的相关文档。
- 文档分类(document categorization/classification)文档分类也成文本分类或信息分类,对大量的文档按照一定的标准自动分类。如情感分类(sentiment classification)或称文本倾向性识别(text orientation identification),情感分类已经为支撑舆情分析(public opinion analysis)的基本技术
- 问答系统(question-answering system)对用户提出的问题理解,利用自动推理等手段,在有关知识资源中自动求解并作出相应的回答,有时与语音技术和多模态输入、输出技术、以及人机交互技术等相结合构成人机对话系统(human-computer dialogue system)
- 信息过滤(information filtering)通过自动识别和过滤那些满足特定条件的文档信息,通常指有害信息的自动过滤和识别,主要用于信息安全和防护、网络内容管理等。
- 信息抽取(information extraction)从文本中抽取特定的事件或事实信息,有时候成为事件抽取(event extraction)
- 文本挖掘(text mining)从文本中获取高质量的信息过程,涉及文本分类、文本聚类、概念或实体抽取、粒度分类、情感分析、自动文摘、实体关系建模等多种技术。
- 舆情分析(public opinion analysis)围绕中介性社会事件的发生、发展和变化、民众对社会管理者产生和持有的社会政治态度。
- 隐喻计算(metaphorical compution) 研究自然语言语句和篇章中隐喻修辞的理解方法
- 文字编辑和自动校对(automatic proofreading)对文字拼写、用词、甚至语法、文档格式进行自动检查、校对和编排。
从数据(NLP中是文本)中学习适合于任务的表示是机器学习的主要任务。机器学习在文本数据中的应用已有三十多年的历史,但最近从2008年到2010年一些机器学习技术,其中一种被为深度学习技术发展迅速,并证明对NLP,语音和计算机视觉中的各种人工智能(AI)任务非常有效。深度学习是我们涵盖的另一个主要课题; 因此,本书主要研究对象是使用深度学习方法处理NLP任务。
简单地说, 深度学习是一种人们能够使用数据的抽象来有效地从数据中学习表示 计算图和数值优化的技术。这就是深度学习和计算图的成功,谷歌,Facebook和亚马逊等主要科技公司已经发布了基于它们的计算图框架和库的实现,以实现研究人员和工程师的思想。在本书中,我们主要使用PyTorch,一种越来越流行的基于Python的计算图框架库,用于实现深度学习算法。在本章中,我们将解释计算图是什么以及为什么我们选择使用PyTorch作为框架。机器学习和深度学习领域是巨大的。在本章中,对于本书的大部分内容,我们主要涉及的内容是监督学习 ; 也就是说,用标记的训练样例学习。我们首先解释监督学习范式,它将成为本书的基础。如果您到目前为止还不熟悉这些术语,那么本书正是要回答这些问题。本章以及未来的章节不仅阐明了这一点,而且深入研究了这些章节。如果您已经熟悉这里提到的一些术语和概念,我们仍然鼓励您看完本章。有两个原因:为本书的其余部分制定通用术语,方便表述;并理解未来章节所需的基础知识。
本章的目标是:
- 理解监督学习基本方法
- 了解学习任务的编码输入
- 了解计算图是什么
- 掌握PyTorch的基础知识
让我们开始吧!
1 监督学习范式
监督在机器学习中,或简单的监督学习,指的是当事实真相的情况 目标(正在预测的是)可用于观察。例如,在文档分类中,目标是分类标签,观察输入是一份文件。例如,在机器翻译中,观察是一种语言的句子,而目标是对应另一种语言的句子。通过对输入数据的这种理解,我们在[图1-1中]说明了监督学习范例。
我们可以将监督学习范式分解为六个主要概念,如图1-1所示:
- 观察(Observations) 观察是我们想要预测的本来事物。我们用x表示观察。*我们有时将观察结果称为“输入”。
- 目标(Targets) 目标是与观察相对应的标签。通常是要预测的事情。遵循机器学习/深度学习中的标准符号,我们使用y来表示。有时,这被称为基本事实。
- 模型(Model) 一个模型是一个数学表达式或函数,它接受观察x,并预测其目标标签的值。参数化模型的参数(Parameters) 有时也称为权重。表示的标准的符号是w(用于权重)或ŵ。
- 预测(Predictions), 也称为估计,是模型猜测的目标值,给出观察结果。我们用“上尖括号”形状的符号表示法表示。因此,目标y的预测表示为ŷ。
- 损失函数(Loss function) 是一种函数,用于比较预测与训练数据中的观察目标的距离。给定目标及其预测,损失函数分配称为损失的标量实数值。损失值越低,模型在预测目标方面越好。我们用L来表示损失函数。
虽然在NLP /深度学习建模或编写本书时,在数学上有正规表述,但我们还是重新声明一下监督学习范例,为那些对该领域不熟悉的读者提供标准术语,以便他们熟悉arXiv研究论文中的符号和写作风格。
考虑一个数据集 D={Xi,yi}i=1n有n个例子。给定该数据集,我们想要学习由权重 w 参数化的函数(模型)f。也就是说,我们对f的结构做出假设,并且给定该结构,权重w的学习值将完全表示模型。对于给定的输入X,模型预测ŷ为目标:
y^=f(X; W)
在监督学习中,对于训练数据,我们已知观察的真实目标y。此实例的损失将为L(y,ŷ)。然后,监督学习就是找到最佳参数/权重w的过程,将使所有n个示例的累积损失最小化。
例子
使用(随机)梯度下降训练
监督学习的目标是选择最小化给定数据集的损失函数的参数值。换句话说,这相当于在等式中找到根。我们知道梯度下降是找到方程根的常用技术。回想一下,在传统的梯度下降中,我们猜测根(参数)的一些初始值并迭代地更新参数,直到目标函数(损失函数)评估为低于可接受阈值的值(aka收敛标准)。对于大型数据集,由于存储器限制,通常不可能在整个数据集上实现传统的梯度下降,并且由于计算开销而非常慢。相反,通常采用称为随机梯度下降(SGD)的梯度下降近似求解。在随机情况下,随机选取数据点或数据点子集,并为该子集计算梯度。当使用单个数据点时,该方法称为纯SGD,当使用(多个)数据点的子集时,我们将其称为minibatch SGD。通常是单词“pure”和“minibatch”在根据上下文变得清晰时被删除。在实践中,很少使用纯SGD,因为它会因噪声更新而导致收敛非常慢。一般SGD算法有不同的变体,都旨在加快收敛速度。在后面的章节中,我们将探讨其中一些变体,以及如何在更新参数时使用渐变。调用迭代更新参数的过程称为反向传播。反向传播的每个步骤(也称为纪元)由a组成向前 传球和向后 传球。正向传递使用参数的当前值评估输入并计算损失函数。向后传递使用损失的梯度更新参数。
观察到目前为止,这里没有任何内容专门针对深度学习或神经网络。[图1-1中]箭头的方向表示训练系统时数据的“流量”。我们对“计算图”中的“流程”概念有更多的说法,但首先,我们来看看我们如何用数字方式表示我们在NLP问题中的输入和目标,以便我们可以训练模型并预测结果。
2 观察和目标编码
我们将需要以数字方式表示观察(文本)以与机器学习算法结合使用。图1-2显示了视觉的描述方法。
一个表示文本的简单方法是作为数字向量。有无数种方法可以执行此映射/表示。实际上,本书的大部分内容都致力于从数据中学习这样的任务表示。但是,我们从一些有启发式的方便计算的简单表示开始。虽然简单,但它们本身就非常强大,或者作为更丰富的表示学习的起点。所有这些基于计数的表示都以固定维度的向量开始。
2.1 独热表示one-hot representation
独热表示, 正如其名,由一个零向量,其中1表示这个单词在文章的这个位置出现,如下面两句话
Time flies like an arrow.
Fruit flies like a banana.
忽略标点符号,忽略大小写,我们得到一个字典{time,fruit,flies,like,a,an,arrow,banana},字典大小是8,因此我们使用个8维向量来表示,例如“like a banana” 表示为: [0, 0, 0, 1, 1, 0, 0, 1].
虽然我们很少会在本书的输入中使用除了独热表示之外的任何内容,但我们现在引入术语 - Term-Frequency(TF)和术语 - Term-Frequency-Inverse-Document-Frequency(TF-IDF)。这些表示在信息检索(IR)中具有悠久的历史,并且在NLP系统中也被积极地使用。
2.2 TF表示
TF 短语、句子或文档的表示仅仅是组成单词的一个频率表示的总和。继续我们简单的例子,使用前面提到的独热编码,句子“Fruit flies like time flies a fruit”有以下TF表示:[1, 2, 2, 1, 1, 0, 0, 0]
。请注意,每个条目都是相应单词出现次数的计数在句子(语料库)。让我们用TF(w)表示w出现的频率。
from sklearn.feature_extraction.text import CountVectorizer
import seaborn as sns
corpus = ['Time flies flies like an arrow.',
'Fruit flies like a banana.']
one_hot_vectorizer = CountVectorizer(binary=True)
one_hot = one_hot_vectorizer.fit_transform(corpus).toarray()
sns.heatmap(one_hot, annot=True,
cbar=False, xticklabels=vocab,
yticklabels=['Sentence 1', 'Sentence 2'])
2.3 TF-IDF
在专利文档的集合中,最常见的单词是 claim, system, method, procedure等,这些单词的重复次数很多,如果使用TF表示,这些单词的频率最高。然而这些单词对于理解一个具体的专利没有太大作用,反而如“tetrafluoroethylene”这些频率特别低的单词更具有代表性,能反应专利。为了给这些单词更高的权值我们引入TF-IDF。公式为:
IDF(w)=log (N/nw)
其中nw是文档中单词word的数量,N是文档个数
TF-IDF = TF(w) * IDF(w).
首先,如果单词在所有文档中经常出现,则nw等于N,IDF等于0,TF-IDF为0
其次,如果单词出现次数比较少,IDF的值将比较大,相应TF-IDF也比较大。
from sklearn.feature_extraction.text import TfidfVectorizer
import seaborn as sns
tfidf_vectorizer = TfidfVectorizer()
tfidf = tfidf_vectorizer.fit_transform(corpus).toarray()
sns.heatmap(tfidf, annot=True, cbar=False, xticklabels=vocab,
yticklabels= ['Sentence 1', 'Sentence 2'])
在深度学习中,很少直接使用TF-IDF。因为我们的目标是学习一个表示,因此常常使用独热编码
2.4 目标编码
如在“监督学习范例”中指出,目标变量如何编码取决于正在解决的NLP任务。例如,在机器翻译,摘要和问题回答的情况下,目标也是文本并且使用诸如先前描述的独热编码的方法来编码。
许多NLP任务实际上使用分类标签,其中模型必须预测一组固定标签。对此进行编码的常用方法是对每个标签使用唯一索引。当输出标签的数量太大时,这种简单的表示可能会成为问题。一个例子是语言建模问题,其中任务是根据过去看到的单词预测下一个单词。标签空间是一种语言的整个词汇表,包括特殊字符,名称等可以很容易达到几十万种。我们将在后面的章节中重新讨论这个问题以及如何解决这个问题。
一些NLP问题涉及从给定文本预测数值。例如,英语论文,我们可能需要指定数字成绩或可读性分数。餐厅评论,我们可能需要预测直到第一个小数的数字星级。根据用户的推文,我们可能需要预测用户的年龄组。存在几种编码数字目标的方法,但是将目标简单地分类为分类“箱” - 例如,“ 0-18
”,“ 19-25
”,“ 25-30
”等等 - 并将其视为一个序数分类问题是一种合理的方法。分箱可以是均匀的或非均匀的,也可以是数据驱动的。虽然对此书的详细讨论超出了本书的范围,但我们会提请您注意这些问题,因为在这种情况下,目标编码会显着影响性能,我们建议您看看Dougherty等人(1995)及其中的参考文献。
图1-1总结监督学习范例作为数据流结构,其中输入由模型(数学表达式)转换以获得预测,并且损失函数(另一表达式)提供反馈信号以调整模型的参数。可以使用计算图数据结构方便地实现该数据流。从技术上讲,计算图是一种模拟数学表达式的抽象。在深度学习的背景下,计算图的实现(例如Theano,TensorFlow和PyTorch)进行额外的标记以实现在监督学习范例的训练期间获得参数梯度所需的导数。我们在“PyTorch Basics”中进一步探讨了这一点。推断(或预测)仅仅是表达式评估(计算图上的前向流)。让我们看看计算图如何模拟表达式。考虑表达式:
ÿ=w ^X+b
这可以写成两个子表达式,z = wx和y = z + b。然后,我们可以使用有向无环图(DAG)表示原始表达式,其中节点是乘法和加法等数学运算。操作的输入是节点的输入边缘,操作的输出是输出边缘。因此,对于表达式y = wx + b,计算图如图1-6所示。在下一节中,我们将看到PyTorch如何允许我们以简单的方式创建计算图形,
3 PyTorch基础知识
在本书中,我们广泛使用PyTorch来实现我们的深度学习模型。PyTorch是一个开源的,社区驱动的深度学习框架。与Theano,Caffe和TensorFlow不同,PyTorch实现了一种“自动求导”方法,允许我们动态定义和执行计算图。这对于调试以及最快构建复杂模型非常有用。
在以下部分中,我们将使用PyTorch学习以下内容:
- 创建张量
- 张量操作
- 索引,切片和与张量连接
- 用张量计算梯度
- 使用带GPU的CUDA张量
在本节的其余部分中,我们将使用PyTorch的首先来熟悉各种PyTorch操作。我们建议您在此时安装Python 3.5+jupyter,并安装PyTorch,并按照本节中的示例进行操作。我们还建议您在本节后面的练习中完成练习。
3.1 安装PyTorch
第一步是在您的机器上安装PyTorch,方法是官方选择系统等pytorch.org
。选择您的操作系统,然后选择包管理器(我们建议conda
/ pip
),然后选择您正在使用的Python版本(我们建议使用3.5+)。这将生成执行以安装PyTorch的命令。在撰写本文时,例如,conda环境的install命令如下:
conda install pytorch torchvision -c pytorch
3.2 创建张量
首先,我们定义辅助函数,它将汇总张量的各种属性,例如张量的类型,张量的维数和张量的内容:describe(*x*)``*x*
def describe(x):
print('Type:{}'.format(x.type()))
print('Shape / size: {}'.format(x.shape))
print('Values: \n{}'.format(x))
PyTorch允许我们使用多种不同的方式创建张量。创建张量的一种方法是通过指定其尺寸来初始化随机张量,如例所示。
import torch
describe(torch.Tensor(2, 3))
Type: torch.FloatTensor
Shape/size: torch.Size([2, 3])
Values:
tensor([[0.0243, 0.0000, 0.9586],
[0.0000, 0.0000, 0.0000]])
我们还可以通过使用interval [ 0, 1
)或者中的均匀分布的值随机初始化来创建张量标准正态分布(随机初始化张量,从均匀分布说,是重要的,因为你将看到在第3章以及第4章,如在示出的实施例1-4。
import torch
describe(torch.rand(2, 3)) # uniform random
describe(torch.randn(2, 3)) # random normal
Type: torch.FloatTensor
Shape/size: torch.Size([2, 3])
Values:
tensor([[ 0.0242, 0.6630, 0.9787],
[ 0.1037, 0.3920, 0.6084]])
Type: torch.FloatTensor
Shape/size: torch.Size([2, 3])
Values:
tensor([[-0.1330, -2.9222, -1.3649],
[ 2.3648, 1.1561, 1.5042]])
我们还可以创建一个填充了相同标量的张量。为了创建一个零或一个的张量,我们有内置函数,并且为了填充特定值,我们可以使用的fill_()
方法。任何PyTorch方法用 下划线(_)指的是 就地操作; 也就是说,它在不创建新对象的情况下修改了内容,如例1-5所示。
import torch
describe(torch.zeros(2, 3))
x = torch.ones(2, 3)
describe(x)
x.fill_(5)
describe(x)
Type: torch.FloatTensor
Shape/size: torch.Size([2, 3])
Values:
tensor([[ 0., 0., 0.],
[ 0., 0., 0.]])
Type: torch.FloatTensor
Shape/size: torch.Size([2, 3])
Values:
tensor([[ 1., 1., 1.],
[ 1., 1., 1.]])
Type: torch.FloatTensor
Shape/size: torch.Size([2, 3])
Values:
tensor([[ 5., 5., 5.],
[ 5., 5., 5.]])
从列表创建和初始化张量
x = torch.Tensor([[1, 2, 3],
[4, 5, 6]])
describe(x)
值可以来自列表,如前面的示例,也可以来自NumPy数组。当然,我们也可以从PyTorch张量到NumPy阵列。请注意,张量的类型是一个DoubleTensor
而不是默认值FloatTensor
。这对应于NumPy随机矩阵a的数据类型float64
,如例1-7所示。
import torch
import numpy as np
npy = np.random.rand(2, 3)
describe(torch.from_numpy(npy))
3.3 张量类型和尺寸
每个张量都有相关的类型和大小。默认值使用torch.Tensor
构造函数时的张量类型torch.FloatTensor
。然而,可以将张量转换成不同的类型(float
,long
,double
通过在初始化任一指定或稍后使用的类型转换方法的一个,等等)。有两种方法可以指定初始化类型,方法是直接调用特定张量类型的构造函数,例如FloatTensor
和LongTensor
,或使用特殊方法torch.tensor
,并提供dtype
,如例1-8所示。
x = torch.FloatTensor([[1, 2, 3],
[4, 5, 6]])
describe(x)
x = x.long()
describe(x)
我们使用张量对象的形状属性和大小方法来表示我们需要值。如果两句话的值相近大多是同义词。检查张量的形状成为调试PyTorch代码不可或缺的工具。
3.4 张量操作
已经创建了的张量,你可以像使用传统的编程语言类型一样操作它们,比如“+”,“ - ”,“*”,“/”。我们也可以使用一些符号例如.add()
,如例1-9所示的函数,对应于符号运算符。
import torch
x = torch.randn(2, 3)
describe(x)
describe(torch.add(x, x))
describe(x + x)
您还可以将操作应用于张量的特定维度。您可能已经注意到,对于2D张量,我们将行表示为维度0
,将列表示为维度1
,如示例1-10中所示。
import torch
x = torch.arange(6)
describe(x)
x = x.view(2, 3)
describe(x)
describe(torch.sum(x, dim=0))
describe(torch.sum(x, dim=1))
describe(torch.transpose(x, 0, 1))
通常,我们需要执行更复杂的操作,这些操作涉及索引,切片,连接和组合。与NumPy和其他数字库一样,PyTorch具有内置函数,可以使这种张量操作变得非常简单。
3.5 索引,切片和连接
如果您是NumPy用户,PyTorch的索引和切片方案可能对您非常熟悉。
import torch
x = torch.arange(6).view(2, 3)
describe(x)
describe(x[:1, :2])
describe(x[0, 1])
例1-12演示了PyTorch还具有复杂索引和切片操作的功能,您可能有兴趣有效地访问张量的非连续位置。
indices = torch.LongTensor([0, 2])
describe(torch.index_select(x, dim=1, index=indices))
row_indices = torch.arange(2).long()
col_indices = torch.LongTensor([0, 1])
describe(x[row_indices, col_indices])
连接
describe(torch.cat([x, x], dim=0))
describe(torch.cat([x, x], dim=1))
PyTorch还在张量上实现了高效的线性代数运算,例如乘法,逆和迹,您可以在例1-14中看到。
import torch
x1 = torch.arange(6).view(2, 3)
describe(x1)
x2 = torch.ones(3, 2)
x2[:, 1] += 1
describe(x2)
到目前为止,我们已经研究了创建和操作常量PyTorch张量对象的方法。PyTorch张量器处理构建计算图形所需的梯度,只需在实例化时启用布尔标志即可使用。
3.6 张量和计算图
PyTorch张量class封装数据(张量本身)和一系列操作,例如代数运算,索引和整形操作。但是,如例1-15所示,当requires_grad
布尔标志设置为True
张量时,启用梯度操作,可以跟踪张量的梯度以及梯度函数,这两者都是求解梯度所需的 - “监督学习范式”中讨论的基础
import torch
x = torch.ones(2, 2, requires_grad=True)
describe(x)
print(x.grad is None)
当您创建张量时标注requires_grad=True
,您需要PyTorch来管理计算渐变的梯度信息。首先,PyTorch将跟踪前向传递的值。然后,在计算结束时,使用单个标量来计算后向传递。通过使用,启动向后传递backward()
由损失函数的评估产生的张量方法。向后传递计算参与正向传递的张量对象的梯度值。
通常,梯度是表示函数输出相对于函数输入的斜率的值。在计算图设置中,模型中的每个参数都存在梯度,可以将其视为参数对误差信号的贡献。在PyTorch中,您可以使用.``grad
成员变量访问计算图中节点的渐变。优化器使用该.``grad
变量来更新参数的值。
到目前为止,我们一直在CPU内存上分配我们的张量。在进行线性代数运算时,如果你有GPU,那么使用GPU可能是有意义的。要利用GPU,您需要首先在GPU的内存上分配张量。通过专用API访问GPU叫做CUDA。CUDA API由NVIDIA创建,仅限于在NVIDIA GPU上使用。PyTorch提供的CUDA张量对象在使用时与常规的CPU绑定张量无法区分,除了它在内部分配的方式。
3.7 CUDA Tensors
PyTorch制作创建这些CUDA张量非常容易(示例1-16),它将张量从CPU传输到GPU,同时保持其基础类型。PyTorch中的首选方法是设备不可知并编写无论是在GPU还是CPU上都能正常工作的代码。在下面的代码片段中,我们首先使用检查GPU是否可用torch.cuda.is_available()
,然后检索设备名称torch.device
。然后,通过使用该.to(device)
方法实例化所有未来的Tensors并将其移动到目标设备。
import torch
print (torch.cuda.is_available())
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print (device)
x = torch.rand(3, 3).to(device)
describe(x)
要对CUDA和非CUDA对象进行操作,我们需要确保它们位于同一设备上。如果我们不这样做,计算将会出错,如下面的代码片段所示。例如,当计算不属于计算图的监视度量时,会出现这种情况。在两个张量对象上操作时,请确保它们都在同一设备上。
请记住,从GPU来回移动数据是很昂贵的。因此,典型的过程涉及在GPU上进行许多可并行化的计算,然后将最终结果传回CPU。这将允许您充分利用GPU。如果您有多个CUDA可见设备(即多个GPU),最佳做法是CUDA_VISIBLE_DEVICES在执行程序时使用环境变量,如下所示:
CUDA_VISIBLE_DEVICES = 0,1,2,3 python main.py
4 练习
掌握一个主题的最好办法就是做题。这里专门设立了一些练习。如果遇到困难可以查阅官方文档。
4.1 创建一个二维张量,然后在0维加上一个1维张量
import torch
x = torch.rand(2, 3)
y = x.unsqueeze(0)
4.2 删除刚才添加的那个维度
xx = y.squeeze(0)
4.3 创建一个值在[5, 8)之间,形状是5x4的随机变量
torch.rand(5, 4) * (8 - 5)+5
4.4 创建一个变量,其分布是(mean=0, std=1)
x = torch.rand(3, 2)
x.normal_()
4.5 返回torch.Tensor([1, 1, 1, 0, 1])所有非零元素的索引
x = torch.tensor([1, 1, 1, 0, 1])
x.nonzero()
4.6 创建一个尺寸是(3, 1)的随机变量,然后水平方向堆叠4个拷贝在一起
x = torch.rand(3, 1)
x.expand(3, 4)
4.7 返回两个矩阵批处理乘积(a=torch.rand(3,4,5), b=torch.rand(3,5,4))
a = torch.rand(3, 4, 5)
b = torch.rand(3, 5, 4)
torch.bmm(a, b)
4.8 返回两个矩阵批处理乘积 (a=torch.rand(3,4,5), b=torch.rand(5,4)).
a = torch.rand(3, 4, 5)
b = torch.rand(5, 4)
torch.bmm(a, b.unsqueeze(0).expand(a.size(0), *b.size()))
摘要
在本章中,我们介绍了本书的目标 - 自然语言处理(NLP)和深度学习 - 并对监督学习范式进行了详细的理解。在本章的最后,您现在应该熟悉或至少知道各种术语,例如观察,目标,模型,参数,预测,损失函数,表示,学习/训练和推理。您还了解了如何使用独热编码对学习任务的输入(观察和目标)进行编码。我们还学习了基于计数的表示,如TF和TF-IDF。我们通过首先了解计算图是什么,静态与动态计算图以及PyTorch张量操作操作之旅来开始我们的PyTorch之旅。在第2章,我们提供传统NLP的概述。第2章和本章应该为您奠定必要的基础。
参考文献
- <Natural Language Processing with PyTorch> by Goku Mohandas, Brian McMahan, Delip Rao
- 统计自然语言处理,宗成庆、清华大学出版社