「PyTorch自然语言处理系列」5. 词嵌入和类型(上)

数据与智能

267篇原创内容
公众号

来源 |  Natural Language Processing with PyTorch

作者 | Rao,McMahan

译者 | Liangchu

校对 | gongyouliu

编辑 | auroral-L

全文共7837字,预计阅读时间40分钟。

上下拉动翻看这个目录

5.1 为什么要学习嵌入?
  5.1.1 嵌入的有效性
  5.1.2 学习词嵌入的方式
  5.1.3 预训练词嵌入的实践
   5.1.3.1 加载嵌入
   5.1.3.2 词嵌入之间的关系
 5.2 示例:学习词嵌入的连续词袋
  5.2.1 Frankenstein数据集
  5.2.2 Vocabulary,Vectorizer和DataLoader
  5.2.3. CBOWClassifier模型
  5.2.4 训练例程
  5.2.5 模型评估和预测

5.3 示例:使用预训练嵌入用于文档分类的迁移学习
  5.3.1 AG News数据集
  5.3.2 Vocabulary,Vectorizer和DataLoader
  5.3.3 NewsClassifier模型
  5.3.4 训练例程
  5.3.5 模型评估和分类
  5.3.5.1 在测试集上评估
  5.3.5.2 预测新的新闻头条的类别
 5.4 总结

在实现自然语言处理任务时,我们需要处理不同类型的离散类型,典型例子是单词(word)。单词来自一个有限的集合(也即词汇表)。其他离散类型的示例包括字符(character)、词性标签(part-of-speech tag)、命名实体(named entity)、命名实体类型(named entity type)、解析特性(parse feature)、产品目录中的条目等等。本质上,当任何输入特征来自一个有限(或可数无限)集合时,它都是离散类型(discrete type)。

将离散类型(如单词)表示为密集向量是NLP中深度学习成功的核心。术语“表示学习(representation learning)”和“嵌入(embedding)”是指学习从一种离散类型到向量空间中的某点的映射。当离散类型是单词时,这个密集向量表示称为词嵌入(word embedding)。我们在第二章中看到了基于计数的嵌入方法的例子,比如TF-IDF。在本章中,我们主要研究基于学习或基于预测(Baroni等人,2014)的嵌入方法,这种嵌入方法通过最大化特定学习任务的目标来学习表征,例如,根据上下文预测一个单词。基于学习的嵌入方法由于其广泛的适用性和性能而得到了承认。事实上,单词嵌入在 NLP 任务中的普遍性为它们赢得了“NLP 的 Sriracha”的称号,因为你可以在所有 NLP 任务中使用词嵌入,并期望任务的性能得到改进。然而,我们认为这种绰号是有误导性的——与 Sriracha 不同,嵌入(embedding)通常不是事后添加到模型中的,而是模型本身的基本组成部分。

在本章中,我们讨论与嵌入词相关的向量表示:嵌入词的方法、优化用于监督和非监督语言任务词嵌入的方法、可视化嵌入词的方法、以及结合句子和文档的词嵌入方法。然而请务必记住一点:我们在这里描述的方法适用于任何离散类型。

5.1 为什么要学习嵌入?

在前几章中,你看到了创建单词向量表示的传统方法。具体来讲,你了解到可以使用独热表示——向量的长度与词汇表的大小相同,除了表示特定单词的值为1的单个位置外,其他位置都有0填充。此外,你还学习了计数表示——向量的长度也与模型中唯一单词的数量相同,但在向量中与句子中单词的频率相对应的位置上有计数。基于计数的表示也称为分布表示(distributional representation),因为它们的重要内容或意义是由向量中的多个维度表示的。分布表示历史悠久(Firth, 1935),并且可以很好地适用于许多机器学习和神经网络模型。这些表示不是从数据中学习的,而是启发式构建的。

分布表示的名称来源于:由于单词现在由维度低得多的密集向量表示(假设d = 100,而不是整个词汇的大小,词汇表的大小大概是到或更高), 并且一个单词的含义和其他属性都分布在这个密集向量的不同维度上。

低维学习到的密集表示与我们在前几章中所学的基于独热和计数的向量相比有几个优点:首先,降低维度使得在计算上变得高效;第二,基于计数的表示会导致高维向量在多个维度上冗余地编码相似的信息,而且不共享统计强度;第三,输入中维数过高会导致机器学习和优化中的问题——一种叫做“维数灾难(curse of dimensionality)”的现象。传统上,为了处理这个维度问题,我们会应用到像奇异值分解(singular value decomposition,SVD)和主成分分析(principal component analysis ,PCA)这样的降维方法,然而有些讽刺的是,当维度以百万计的顺序排列时(NLP的典型情况),这些方法并不能很好地进行缩放;第四,从特定任务的数据中学习(或微调)的表示形式最适合手头的任务。使用 TF-IDF 等启发式方法或 SVD 等低维方法,并不清楚嵌入方法的优化目标是否与任务有关。

5.1.1 嵌入的有效性

为了理解嵌入是如何工作的,下面看一个用独热向量乘以线性层中的权重矩阵的例子,如下图(5-1)所示。在第三章和第四章中,独热向量的大小与词汇表的大小相同,这个向量被称为“独热”,因为它在索引中有一个1,表示存在一个特定的单词。

根据定义,接受这个独热向量作为输入的线性层的权值矩阵必须与这个独热向量的大小具有相同的行数。当执行矩阵乘法时,如上图(5-1)所示,结果向量实际上只是选择了由非零项指示的行。基于该观察结果,我们可以跳过乘法步骤,直接使用整数作为索引来检索所选行。

关于嵌入效率,最后要注意的一点是:尽管上图(5-1)中的示例显示的权重矩阵与传入的独热向量具有相同的维度,但情况并非总是如此。实际上,嵌入通常用于在低维空间中表示单词,而不是使用一个独热向量或基于计数的表示。在研究文献中,嵌入的典型大小从25维到500维不等,维度的准确选择可以节省GPU内存。

5.1.2 学习词嵌入的方式

本章的目标不是学习一些指定的单词嵌入技术,而是要理解什么是嵌入、如何使用它们以及在哪里使用它们、如何在模型中可靠地使用它们、以及理解它们的局限性。之所以如此,是因为实践者一般很少遇到需要编写新的词嵌入训练算法的情况。在本节中,我们会概述目前训练词嵌入的一些方法。所有的词嵌入方法只使用单词(也就是一种无标签数据)来训练,却是以一种有监督的方式进行的,这可以通过构造辅助监督任务来实现。在这些任务中,数据被隐式地标记,直觉告诉我们,为解决辅助任务而优化的表示将捕获文本语料库的许多统计和语言特性,以便普遍使用。下面是一些辅助任务的示例:

· 给定一个单词序列,预测下一个单词。这也称为语言建模任务(language modeling task)。

· 前后给定一系列单词,预测缺失的单词。

· 给定一个单词,预测出现在窗口中的单词,与位置无关。

当然,上面列出的辅助任务并不完整,辅助任务的选择取决于算法设计者的直觉和计算开销。像Glove、连续词袋模型(Continuous Bag-of-Words,CBOW)、Skipgrams 等等都是些典型例子。我们推荐你参考Goldberg, 2017, Chapter 10以获得更多细节,但我们也会简要介绍CBOW模型。然而,对于大多数目的来说,使用预先训练好的单词嵌入并对它们进行微调就足够了。

5.1.3 预训练词嵌入的实践

本章的主体以及本书的后续部分,都涉及到使用预训练词嵌入。在大型语料库(比如Google News、Wikipedia或Common Crawl)上使用前面描述的多种方法之一训练的预训练词嵌入,都是可以免费下载和使用的。本章的剩余部分将展示如何有效地加载和查找这些嵌入、研究词嵌入的一些属性、并演示在NLP任务中使用预训练嵌入的示例。

5.1.3.1 加载嵌入

词嵌入现在已经变得足够流行和普及,因此你可以从最初的Word2Vec到Stanford 的 GLoVE、Facebook 的 FastText 和许多其他来源下载许多不同的版本。通常,嵌入会以这种格式出现:每行以嵌入的单词(word)/类型(type)开始,然后是一系列数字(也即向量表示)。这个序列的长度就是表示的维度(也即嵌入维度(embedding dimension)),嵌入维度通常数以百计。标记(token)类型的数量通常是词汇表的大小,通常数以百万计。例如,下面是来自 GloVe 的狗和猫向量的前七个维度:

为了有效地加载和处理嵌入,我们使用一个叫PreTrainedEmbeddings的实用工具类,如下例(5-1)所示。这个类构建了所有单词向量的内存索引,以便使用近似最近邻包annoy进行快速查找和最近邻查询。

示例 5-1:使用预训练词嵌入

Input[0]import numpy as npfrom annoy import AnnoyIndex
class PreTrainedEmbeddings(object): def __init__(self, word_to_index, word_vectors): ''' Args: word_to_index (dict): mapping from word to integers word_vectors (list of numpy arrays) ''' self.word_to_index = word_to_index self.word_vectors = word_vectors self.index_to_word = \ {v: k for k, v in self.word_to_index.items()} self.index = AnnoyIndex(len(word_vectors[0]), metric='euclidean') for _, i in self.word_to_index.items(): self.index.add_item(i, self.word_vectors[i]) self.index.build(50)
@classmethod def from_embeddings_file(cls, embedding_file): '''Instantiate from pre-trained vector file.
Vector file should be of the format: word0 x0_0 x0_1 x0_2 x0_3 ... x0_N word1 x1_0 x1_1 x1_2 x1_3 ... x1_N
Args: embedding_file (str): location of the file Returns: instance of PretrainedEmbeddings ''' word_to_index = {} word_vectors = [] with open(embedding_file) as fp: for line in fp.readlines(): line = line.split(' ') word = line[0] vec = np.array([float(x) for x in line[1:]])
word_to_index[word] = len(word_to_index) word_vectors.append(vec) return cls(word_to_index, word_vectors) Input[1]embeddings = \ PreTrainedEmbeddings.from_embeddings_file('glove.6B.100d.txt')

在这些例子中,我们使用Glove词嵌入。下载之后,正如上例(5-1)中的第二个输入所示,你可以使用PretrainedEmbeddings类进行实例化。

5.1.3.2 词嵌入之间的关系

词嵌入的核心特征是对句法和语义关系进行编码,这些句法和语义关系表现为词的使用规律。例如,人们谈论猫和狗的方式非常相似(讨论宠物、喂食等),因此它们的嵌入之间彼此的距离比它们与其他动物(如鸭子和大象)相比的距离要近得多。

我们可以从几个方面探讨嵌入词编码的语义关系,最流行的一种方法是类比任务(像SAT 等考试中常见的推理任务):

Word1 : Word2 :: Word3 : ______

在这个任务中提供了前三个单词,我们需要确定第四个单词与前两个单词之间的关系是一致的。使用词嵌入,我们可以对其进行空间编码。首先,我们从Word1中减去Word2,这个差异向量编码了Word1和Word2之间的关系。然后可以将这个差异加入Word3中,从而生成一个接近第四个单词的向量,也就是要填的空。使用这个结果向量对索引执行最近邻查询就可以解决类比问题了。计算上面示例的函数如下例(5-2)所示,它完成了刚刚描述的工作:使用向量算法和近似的最近邻索引来完成类比任务。

示例 5-2:使用词嵌入的类比任务

Input[0]import numpy as npfrom annoy import AnnoyIndex
class PreTrainedEmbeddings(object): ''' implementation continued from previous code box''' def get_embedding(self, word): ''' Args: word (str) Returns an embedding (numpy.ndarray) ''' return self.word_vectors[self.word_to_index[word]]
def get_closest_to_vector(self, vector, n=1): '''Given a vector, return its n nearest neighbors
Args: vector (np.ndarray): should match the size of the vectors in the Annoy index n (int): the number of neighbors to return Returns: [str, str, ...]: words nearest to the given vector. The words are not ordered by distance ''' nn_indices = self.index.get_nns_by_vector(vector, n) return [self.index_to_word[neighbor] for neighbor in nn_indices]
def compute_and_print_analogy(self, word1, word2, word3): '''Prints the solutions to analogies using word embeddings
Analogies are word1 is to word2 as word3 is to __ This method will print: word1 : word2 :: word3 : word4
Args: word1 (str) word2 (str) word3 (str) ''' vec1 = self.get_embedding(word1) vec2 = self.get_embedding(word2) vec3 = self.get_embedding(word3)
# Simple hypothesis: Analogy is a spatial relationship spatial_relationship = vec2 - vec1 vec4 = vec3 + spatial_relationship
closest_words = self.get_closest_to_vector(vec4, n=4) existing_words = set([word1, word2, word3]) closest_words = [word for word in closest_words if word not in existing_words]
if len(closest_words) == 0: print('Could not find nearest neighbors for the vector!') return
for word4 in closest_words: print('{} : {} :: {} : {}'.format(word1, word2, word3, word4))

有趣的是,简单的单词类比任务可以证明单词嵌入捕获了各种语义和语法关系,如下例(5-3)所示:

示例 5-3:单词嵌入编码了许多语言学关系,如SAT类比任务所示

Input[0]# Relationship 1: the relationship between gendered nouns and pronounsembeddings.compute_and_print_analogy('man', 'he', 'woman')Output[0]man : he :: woman : sheInput[1]# Relationship 2: Verb-Noun relationshipsembeddings.compute_and_print_analogy('fly', 'plane', 'sail')Output[1]fly : plane :: sail : shipInput[2]# Relationship 3: Noun-Noun relationshipsembeddings.compute_and_print_analogy('cat', 'kitten', 'dog')Output[2]cat : kitten :: dog : puppyInput[3]# Relationship 4: Hypernymy (broader category)embeddings.compute_and_print_analogy('blue', 'color', 'dog')Output[3]blue : color :: dog : animalInput[4]# Relationship 5: Meronymy (part-to-whole)embeddings.compute_and_print_analogy('toe', 'foot', 'finger')Output[4]toe : foot :: finger : handInput[5]# Relationship 6: Troponymy (difference in manner)embeddings.compute_and_print_analogy('talk', 'communicate', 'read')Output[5]talk : communicate :: read : interpretInput[6]# Relationship 7: Metonymy (convention / figures of speech)embeddings.compute_and_print_analogy('blue', 'democrat', 'red')Output[6]blue : democrat :: red : republicanInput[7]# Relationship 8: Adjectival Scalesembeddings.compute_and_print_analogy('fast', 'fastest', 'young')Output[7]fast : fastest :: young : youngest

虽然语言的功能似乎是系统化的,但事情可能会变得棘手。如下例(5-4)所示,由于单词向量只是基于共现,所以关系可能是错误的:

示例 5-4:一个例子说明了使用共现性来编码语义的危险性,有时它们并没有这种关系!

Input[0]embeddings.compute_and_print_analogy('fast', 'fastest', 'small')
Output[0]fast : fastest :: small : largest

下例(5-5)说明了最常见的类比对之一是如何编码性别角色的:

示例 5-5:注意受保护的属性,例如单词嵌入中编码的性别。这可能会在下游模型中引入不必要的偏差

Input[0]embeddings.compute_and_print_analogy('man', 'king', 'woman')Output[0]man : king :: woman : queen

事实证明,很难区分语言规律和成文的文化偏见。例如,医生实际上并不只有男性,护士实际上也不只有女性,但这些长期存在的文化偏见被视为语言中的规律,并被编入单词向量,如下例(5-6)所示:

示例 5-6:向量类比中的文化性别偏见

Input[0]embeddings.compute_and_print_analogy('man', 'doctor', 'woman')
Output[0]man : doctor :: woman : nurse

考虑到嵌入中的偏差在 NLP 应用中变得越来越多,你需要特别注意这一点。去偏现有词嵌入如今是一个新的令人兴奋的研究领域(Bolukbasi等人, 2016)。此外,我们建议你访问ethicsinnlp.org,以获取伦理学与 NLP 交叉的最新研究结果。

5.2 示例:学习词嵌入的连续词袋

在本例中,我们将介绍构建和学习通用词嵌入最著名的模型之一,即Word2Vec 连续词袋(Continuous Bag-of-Words ,CBOW)模型。在本节中,当我们提到“CBOW 任务”或“CBOW 分类任务”时,隐含的意思是我们构建分类任务的目的是要学习 CBOW 嵌入。CBOW 模型是一个多元分类任务,它表现为对单词文本进行扫描、创建单词的上下文窗口、从上下文窗口中删除中心词、并将上下文窗口分类为丢失的单词。直觉上,你可以把它想成完形填空,有一个句子缺了一个单词,模型的工作就是找出这个缺失的单词应该是什么。

这个例子的目的是介绍nn.Embedding层,它是一个用于封装嵌入矩阵(embedding matrix)的 PyTorch 模块。使用Embedding层,我们可以将token的整数ID映射到用于神经网络计算的向量上。当优化器更新模型权重以最小化损失时,它还更新向量的值。通过这个过程,模型将学习如何以最有效的方式嵌入单词。

下面,我们将遵循标准的示例格式:在第一部分,我们介绍数据集,即Mary Shelley的小说Frankenstein;然后,我们将讨论从token到向量化minibatch的向量化管道;接着,我们会概述 CBOW 分类模型以及如何使用Embedding层;接下来,我们将介绍训练例程(尽管按顺序阅读本书的你已经十分熟悉训练过程了);最后,我们会讨论模型评估、模型推理以及如何检查模型。

5.2.1 Frankenstein数据集

在本例中,我们将从Mary Shelley的小说Frankenstein的电子版(可以通过Gutenberg项目获得)构建一个文本数据集。本节介绍预处理过程、为这个文本数据集构建一个 PyTorch Dataset类、最后将数据集分解为训练集、验证集和测试集。

从Gutenberg项目发布的原始文本文件着手,预处理很简单:我们NLTK的Punkt tokenizer将文本分割成不同的句子。然后,将每个句子转换为小写字母,并完全去掉标点符号。这种预处理允许我们稍后根据空格拆分字符串,以便检索token列表。这一预处理函数是从“示例:分类餐馆评论的情感”一节的示例中重用的。

接下来是将数据集枚举为一系列窗口,以便优化CBOW 模型。为此,我们迭代每个句子中的token列表,并将它们分组到指定窗口大小的窗口中,如下图(5-2)所示:

构建数据集的最后一步是将数据分割为三个集合:训练集、验证集和测试集。回想一下,训练集和验证集都是在模型训练期间使用的:训练集用于更新参数,验证集用于度量模型的性能。测试集顶多使用一次,它用来提供一个较少偏差的测量。在本例(以及本书的大多数示例)中,我们使用70%的训练集、15%的验证集和15%的测试集。

窗口和目标的结果数据集由Pandas DataFrame加载,并在CBOWDataset类中建立索引。下例(5-7)展示了__getitem__()代码片段,它利用Vectorizer将上下文——左右窗口——转换为向量。目标(窗口中心的单词)使用Vocabulary转换为整数。

示例 5-7:为 CBOW 任务构造数据集类

class CBOWDataset(Dataset):    # ... existing implementation from Section 3.5    @classmethod    def load_dataset_and_make_vectorizer(cls, cbow_csv):        '''Load dataset and make a new vectorizer from scratch        Args:            cbow_csv (str): location of the dataset        Returns:            an instance of CBOWDataset        '''        cbow_df = pd.read_csv(cbow_csv)        train_cbow_df = cbow_df[cbow_df.split=='train']        return cls(cbow_df, CBOWVectorizer.from_dataframe(train_cbow_df))    def __getitem__(self, index):        '''the primary entry point method for PyTorch datasets        Args:            index (int): the index to the data point        Returns:            a dict with features (x_data) and label (y_target)        '''        row = self._target_df.iloc[index]        context_vector = \            self._vectorizer.vectorize(row.context, self._max_seq_length)        target_index = self._vectorizer.cbow_vocab.lookup_token(row.target)        return {'x_data': context_vector,                'y_target': target_index}

5.2.2 Vocabulary,Vectorizer和DataLoader

在 CBOW 分类任务中,从文本到向量化minibatch的管道一般是标准的:Vocabulary和DataLoader函数都与“示例:分类餐馆评论的情感”一节中的示例完全一样。然而,与我们在第三章和第四章中看到的Vectorizer不同,这里的Vectorizer不构造独热向量,相反,它构造并返回一个表示上下文索引的整数向量。下例(5-8)给出了vectorize()函数的代码:

示例 5-8:用于 CBOW 数据的Vectorizer

class CBOWVectorizer(object): ''' The Vectorizer which coordinates the Vocabularies and puts them to use'''
def vectorize(self, context, vector_length=-1): ''' Args: context (str): the string of words separated by a space vector_length (int): an argument for forcing the length of index vector '''
indices = \ [self.cbow_vocab.lookup_token(token) for token in context.split(' ')] if vector_length < 0: vector_length = len(indices)
out_vector = np.zeros(vector_length, dtype=np.int64) out_vector[:len(indices)] = indices out_vector[len(indices):] = self.cbow_vocab.mask_index
return out_vector

请注意,如果上下文中的token数量小于最大长度,那么其他项填充为零。实际上,这叫做用零填充(padding with zeros)。

5.2.3. CBOWClassifier模型

下例(5-9)中展示的CBOWClassifier包括三个基本步骤:第一,将表示上下文单词的索引与Embedding层一起使用,为上下文中的每个单词创建向量;第二,目标是以某种方式组合这些向量,使其能够捕获整个上下文。在这个例子中,我们对向量求和,然而还有其他方法可供选择,比如求最大值、平均值,甚至在顶部使用多层感知器(MLP);第三,上下文向量与Linear层一起用来计算预测向量,这个预测向量是整个词汇表的概率分布。预测向量中最大(最可能)的值表示目标词的可能预测——上下文中缺少的中心词。

这里使用的Embedding层主要由两个数字参数化:嵌入的数量(词汇表的大小)和嵌入的大小(嵌入维度)。下例(5-9)的代码里使用了第三个参数:padding_idx。对于像我们这样数据点长度可能不相同的情况,这个参数被用作嵌入层的标记值。该层强制对应于该索引的向量及其梯度均为0。

示例 5-9:CBOWClassifier模型

class CBOWClassifier(nn.Module):    def __init__(self, vocabulary_size, embedding_size, padding_idx=0):        '''        Args:            vocabulary_size (int): number of vocabulary items, controls the                number of embeddings and prediction vector size            embedding_size (int): size of the embeddings            padding_idx (int): default 0; Embedding will not use this index        '''        super(CBOWClassifier, self).__init__()        self.embedding =  nn.Embedding(num_embeddings=vocabulary_size,                                       embedding_dim=embedding_size,                                       padding_idx=padding_idx)        self.fc1 = nn.Linear(in_features=embedding_size,                             out_features=vocabulary_size)    def forward(self, x_in, apply_softmax=False):        '''The forward pass of the classifier        Args:            x_in (torch.Tensor): an input data tensor.                x_in.shape should be (batch, input_dim)            apply_softmax (bool): a flag for the softmax activation                should be false if used with the Cross Entropy losses        Returns:            the resulting tensor. tensor.shape should be (batch, output_dim)        '''        x_embedded_sum = self.embedding(x_in).sum(dim=1)        y_out = self.fc1(x_embedded_sum)        if apply_softmax:            y_out = F.softmax(y_out, dim=1)        return y_out

5.2.4 训练例程

在这个例子中,训练例程遵循我们在整本书中使用的标准:首先初始化数据集、向量化器、模型、损失函数和优化器;然后对数据集的训练和验证部分进行一定次数的迭代,优化训练部分的损失最小化,并衡量验证部分的进度。关于训练例程的更多细节,我们建议你参考“示例:分类餐馆评论的情感”一节获取详细内容。下例(5-10)展示了我们用于训练的参数:

示例 5-10:CBOW 训练脚本的参数

Input[0]args = Namespace( # Data and Path information cbow_csv='data/books/frankenstein_with_splits.csv', vectorizer_file='vectorizer.json', model_state_file='model.pth', save_dir='model_storage/ch5/cbow', # Model hyper parameters embedding_size=300, # Training hyper parameters seed=1337, num_epochs=100, learning_rate=0.001, batch_size=128, early_stopping_criteria=5, # Runtime options omitted for space)

5.2.5 模型评估和预测

本例中的评估基于从测试集中每个目标和上下文对提供的单词上下文预测目标单词,正确分类的单词意味着模型正在学习从上下文预测单词。在本例中,该模型在测试集上达到了 15% 的目标词分类准确率。首先,本例中 CBOW 的构建旨在说明如何构建通用嵌入,因此初始实现的许多特性被忽略了,因为它们增加了学习所不需要的复杂性(但对于优化性能却是必要的);第二,我们使用的数据集是微不足道的——当从头开始训练时,一本大约70000字的书不足以识别出许多规律,相比之下,最先进的嵌入技术通常是在TB规模的文本数据集上训练的。

在这个例子中,我们会展示如何使用 PyTorch nn.Embedding层通过设置一个名为CBOW分类的人工监督任务来从头开始训练嵌入。在下一个示例中,我们将研究如何在一个语料库上预先训练一个嵌入,并将其微调使适用于另一个任务。在机器学习中,使用在一个任务上训练的模型作为另一个任务的初始化器称为迁移学习(transfer learning)。

(0)

相关推荐