百度网站怎样优化排名小游戏网页在线玩
🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】 深度学习【DL】
🖍foreword
✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。
如果你对这个系列感兴趣的话,可以关注订阅哟👋
文章目录
技术要求
翻译语言建模与跨语言知识共享
XLM 和 mBERT
mBERT
XLM
跨语言相似度任务
跨语言文本相似度
可视化跨语言文本相似性
跨语言分类
跨语言零样本学习
多语言模型的基本限制
微调多语言模型的性能
概括
到目前为止,您已经了解了很多关于基于转换器的架构,从仅编码器模型到仅解码器模型,从高效转换器到长上下文转换器。您还了解了基于连体网络的语义文本表示。但是,我们根据单语问题讨论了所有这些模型。我们假设这些模型只理解一种语言,并且不能对文本有一般的理解,无论语言本身如何。事实上,其中一些模型具有多语言变体;来自转换器的多语言双向编码器表示( mBERT )、多语言文本到文本传输转换器( mT5 ) 和多语言双向和自回归转换器( mBART ),仅举几例。另一方面,一些模型是专门为多语言目的而设计的,训练有跨语言目标。例如,跨语言语言模型(XLM)就是这样一种方法,本章将对此进行详细介绍。
在本章中,将介绍语言之间知识共享的概念,字节对编码(BPE)对标记化部分的影响也是另一个重要的主题,以实现更好的输入。将详细介绍使用跨语言自然语言推理( XNLI ) 语料库的跨语言句子相似度。诸如跨语言分类和利用跨语言句子表示来训练一种语言和测试另一种语言等任务将通过自然语言处理( NLP ) 中现实生活问题的具体示例来呈现,例如多语言意图分类。
简而言之,您将在本章中学习以下主题:
- 翻译语言建模与跨语言知识共享
- XLM 和 mBERT
- 跨语言相似度任务
- 跨语言分类
- 跨语言零样本学习
- 多语言模型的基本限制
技术要求
我们将使用 Jupyter Notebook 运行需要 Python 3.6.0+ 的编码练习,并且需要安装以下软件包:
- tensorflow
- pytorch
- transformers >=4.00
- datasets
- sentence-transformers
- umap-learn
- openpyxl
翻译语言建模与跨语言知识共享
到目前为止,你已经学会了关于掩码语言建模( MLM ) 作为完形填空任务。然而,使用神经网络的语言建模根据方法本身及其实际用途分为三类,如下所示:
- MLM
- 因果语言建模( CLM )
- 翻译语言建模( TLM )
也是需要注意的是,还有其他预训练方法,例如Next Sentence Prediction ( NSP ) 和Sentence Order Prediction ( SOP ),但是我们只考虑了基于标记的语言建模。这三种是文献中使用的主要方法。MLM,描述并在前几章中详细介绍过,是一个非常接近语言学习中的完形填空任务的概念。
CLM是通过预测下一个标记来定义,然后是一些先前的标记。例如,如果您看到以下上下文,您可以轻松预测下一个标记:
<s> 变形金刚改变了自然语言……
如您所见,只有最后一个标记被屏蔽,并且之前的标记被提供给模型以预测最后一个标记。此令牌将被处理,如果再次向您提供带有此令牌的上下文,您可能会以“</s>”令牌结束它。为了对这种方法进行良好的训练,不需要掩盖第一个标记,因为模型将只有一个句子开始标记来从中生成一个句子。这句话可以是任何东西!这是一个例子:
<s> …
你会从中预测什么?它可以是字面上的任何东西。为了得到更好的训练和更好的结果,至少需要给出第一个token,例如:
<s> 变形金刚……
并且需要模型来预测变化;给它变形金刚改变后......它需要预测,等等。这种方法非常类似于 N-gram 和基于长短期记忆( LSTM ) 的方法,因为它是基于概率P(wn|wn-1, wn-2 ,…,w0)其中wn是要预测的标记,其余的是它之前的标记。具有最大概率的令牌是预测的令牌。
这些是用于单语模型的目标。那么,跨语言模型可以做什么呢?答案是TLM,它与 MLM 非常相似,只是有一些变化。不是从单一语言给出一个句子,而是将一个句子对用不同语言的模型给出,由一个特殊的标记分隔。该模型需要预测被屏蔽的标记,这些标记在任何这些语言中都被随机屏蔽。
以下句子对是此类任务的示例:

图 9.1 – 土耳其语和英语之间的跨语言关系示例
给定这两个掩码句子,模型需要预测丢失的标记。在此任务中,在某些情况下,模型可以访问该对中的一种语言中缺少的标记(例如,分别在图 9.1中的句子对中的doğal和language)。
作为另一个示例,您可以从波斯语和土耳其语句子中看到同一对。在第二句中,değiştirdiler标记可以在第一句中出现多个标记(一个被屏蔽)。在以下示例中,单词تغییر缺失,但değiştirdiler的含义是تغییر دادند 。:
图 9.2 – 波斯语和土耳其语之间的跨语言关系示例
因此,模型可以学习这些含义之间的映射。就像翻译模型一样,我们的 TLM 也必须学习语言之间的这些复杂性,因为机器翻译( MT ) 是不仅仅是令牌到令牌的映射。
XLM 和 mBERT
我们选择了两个模型在本节中进行解释:mBERT 和 XLM。我们之所以选择这些模型,是因为它们对应于撰写本文时的两种最佳多语言类型。mBERT是使用 MLM 在不同语言的不同语料库上训练的多语言模型造型。它可以针对多种语言单独运行。另一方面,XLM 使用 MLM、CLM 和 TLM 语言建模在不同的语料库上进行训练,并且可以解决跨语言任务。例如,它可以通过将两种不同语言的句子映射到一个公共向量空间来测量它们的相似性,而这对于 mBERT 是不可能的。
mBERT
与单语预训练的 BERT 相比,这个新版本能够在单个模型中处理多种语言。然而,这种建模的缺点是这种模型不能在语言之间进行映射。这意味着该模型在预训练阶段并没有学习任何关于这些来自不同语言的标记的语义含义之间的映射。为了为该模型提供跨语言映射和理解,有必要在一些跨语言监督任务上对其进行训练,例如XNLI数据集中可用的那些。
使用此模型就像使用您在前几章中使用的模型一样简单(有关更多详细信息,请参阅bert-base-multilingual-uncased · Hugging Face)。这是您需要开始的代码:
from transformers import pipelineunmasker = pipeline('fill-mask', model='bert-base-multilingual-uncased')sentences = [
"Transformers changed the [MASK] language processing",
"Transformerlar [MASK] dil işlemeyi değiştirdiler",
"ترنسفرمرها پردازش زبان [MASK] را تغییر دادند"
]for sentence in sentences:print(sentence)print(unmasker(sentence)[0]["sequence"])print("="*50)
Transformers changed the [MASK] language processing
transformers changed the english language processing
==================================================
Transformerlar [MASK] dil işlemeyi değiştirdiler
transformerlar bu dil islemeyi degistirdiler
==================================================
ترنسفرمرها پردازش زبان [MASK] را تغییر دادند
ترنسفرمرها پردازش زبانی را تغییر دادند
==================================================
如您所见,它可以为各种语言执行填充掩码。
XLM
跨语言预训练语言模型的数量,例如 XLM 方法所示的模型,是基于三个不同的预训练目标。MLM、CLM 和 TLM 用于预训练 XLM 模型。这种预训练的顺序是使用所有语言之间的共享 BPE 标记器执行的。共享标记的原因是共享标记在具有相似标记或子词的语言的情况下提供的标记较少,另一方面,这些标记可以在预训练过程中提供共享语义。例如,一些标记在许多语言中具有非常相似的书写和含义,因此,这些标记由 BPE 为所有人共享。另一方面,一些在不同语言中拼写相同的标记可能有不同的含义——例如,在德语和英语环境中共享。幸运的是,自我注意机制帮助我们消除使用周围上下文的含义。
另一个重大改进跨语言建模的特点是它也在 CLM 上进行了预训练,这使得它对于需要句子预测或完成的推理更加合理。换句话说,这个模型对语言有理解,能够完成句子,预测丢失的token,以及使用其他语言源预测丢失的token。
下图展示了跨语言建模的整体结构。您可以在https://arxiv.org/pdf/1901.07291.pdf内容:

图 9.3 – 跨语言建模的 MLM 和 TLM 预训练
还发布了更新版本的 XLM 模型如XLM-R,它在训练和使用的语料库上有微小的变化。XLM-R 与 XLM 模型相同,但接受了更多语言和更大的训练语料库。聚合 CommonCrawl和Wikipedia语料库,并在其上训练 XLM-R 进行 MLM。但是,也使用了 XNLI 数据集对于 TLM。下图显示了 XLM-R 预训练使用的数据量:

图 9.4 – 以千兆字节 (GB) 为单位的数据量(对数刻度)
为训练数据添加新语言时有很多好处和坏处——例如,添加新语言语言可能并不总能改善自然语言推理( NLI ) 的整体模型。XNLI数据集是通常用于多语言和跨语言 NLI。从前面的章节中,你已经看到英语的Multi-Genre NLI ( MNLI ) 数据集;XNLI 数据集与它几乎相同,但有更多的语言,它也有句子对。但是,仅针对此任务进行训练是不够的,并且不会涵盖 TLM 预训练。对于 TLM 预训练,更广泛的数据集,例如并行使用了OPUS的语料库( Open Source Parallel Corpus的缩写)。该数据集包含来自不同语言的字幕,经过对齐和清理,翻译由许多软件源(如 Ubuntu 等)提供。
以下屏幕截图显示了 OPUS ( OPUS ) 及其用于搜索和获取有关数据集的信息的组件:

图 9.5 – 工作
- 对前面代码的简单更改可以向您展示 XLM-R 如何执行掩码填充。首先,您必须更改模型,如下所示:
unmasker = pipeline('fill-mask', model='xlm-roberta-base')
- 之后,您需要将掩码标记从[MASK]更改为<mask>,这是 XLM-R 的特殊标记(或简单地调用tokenizer.mask_token)。这是完成此操作的代码:
sentences = [ "Transformers changed the <mask> language processing", "Transformerlar <mask> dil işlemeyi değiştirdiler", "ترنسفرمرها پردازش زبان <mask" را تغییر دادند ]
- 然后,您可以运行相同的代码,如下所示:
for sentence in sentences:print(sentence)print(unmasker(sentence)[0]["sequence"])print("="*50)
- 结果将出现,像这样:
Transformers changed the <mask> language processing Transformers changed the human language processing ================================================== Transformerlar <mask> dil işlemeyi değiştirdiler Transformerlar, dil işlemeyi değiştirdiler ================================================== ترنسفرمرها پردازش زبان [MASK] را تغییر دادند ترنسفرمرها پردازش زبانی را تغییر دادند ==================================================
- 但正如你从土耳其语和波斯语的例子中看到的那样,该模型仍然犯了错误。例如,在波斯语文本中,它只是添加了ی,而在土耳其语文本中,它添加了,。对于英文句子,它添加了human,这不是预期的。句子没有错,但不是我们所期望的。但是,这一次,我们有一个使用 TLM 训练的跨语言模型;所以,让我们通过连接两个句子并给模型一些额外的提示来使用它。开始了:
print(unmasker("Transformers changed the natural language processing. </s> Transformerlar <mask> dil işlemeyi değiştirdiler.")[0]["sequence"])
- 结果将显示如下:
Transformers changed the natural language processing. Transformerlar doğal dil işlemeyi değiştirdiler.
- 而已!这模型现在做出了正确的选择。让我们多玩一点,看看它的表现如何,如下:
print(unmasker("Earth is a great place to live in. </s> زمین جای خوبی برای <mask> کردن است.")[0]["sequence"])
结果如下:
Earth is a great place to live in. زمین جای خوبی برای زندگی کردن است
做得好!到目前为止,您已经了解了 mBERT 和 XLM 等多语言和跨语言模型。在下一节中,您将学习如何使用此类模型进行多语言文本相似性。您还将看到一些用例,例如多语言抄袭检测。
跨语言相似度任务
跨语言模型是能够以统一的形式表示文本,其中句子来自不同的语言,但意义相近的句子被映射到向量空间中的相似向量。如上一节所述,XLM-R 是该范围内的成功模型之一。现在,让我们看一下这方面的一些应用。
跨语言文本相似度
在以下示例中,您将了解如何使用在 XNLI 数据集上预训练的跨语言语言模型来查找来自不同语言的相似文本。用例场景是此任务需要剽窃检测系统。我们将使用阿塞拜疆语的句子,看看 XLM-R 是否从英语中找到类似的句子——如果有的话。两种语言的句子是相同的。以下是要采取的步骤:
- 首先,您需要为此任务加载模型,如下所示:
from sentence_transformers import SentenceTransformer, utilmodel = SentenceTransformer("stsb-xlm-r-multilingual")
- 之后,我们假设我们以两个单独的列表的形式准备好了句子,如下面的代码片段所示:
azeri_sentences = ['Pişik çöldə oturur','Bir adam gitara çalır','Mən makaron sevirəm','Yeni film möhtəşəmdir','Pişik bağda oynayır','Bir qadın televizora baxır','Yeni film çox möhtəşəmdir','Pizzanı sevirsən?']english_sentences = ['The cat sits outside','A man is playing guitar','I love pasta','The new movie is awesome','The cat plays in the garden','A woman watches TV','The new movie is so great','Do you like pizza?']
- 下一步是使用 XLM-R 模型在向量空间中表示这些句子。您可以通过简单地使用模型的编码功能来做到这一点,如下所示:
azeri_representation = model.encode(azeri_sentences)english_representation = model.encode(english_sentences)
- 在最后一步,我们将在另一种语言的表示上搜索第一种语言的语义相似的句子,如下所示:
results = []for azeri_sentence, query in zip(azeri_sentences, azeri_representation):id_, score = util.semantic_search(query,english_representation)[0][0].values()results.append({"azeri": azeri_sentence,"english": english_sentences[id_],"score": round(score, 4)})
- 为了看到一个清晰的形式这些结果,可以使用pandas DataFrame,如下:
import pandas as pdpd.DataFrame(results)
您将看到匹配分数的结果,如下所示:

图 9.6 – 抄袭检测结果 (XLM-R)
如果我们接受要解释或翻译的最高得分句子,模型在一种情况下(第4行)会出错,但有一个阈值并接受高于它的值是有用的。我们将在以下部分展示更全面的实验。
另一方面,也有可用的替代双编码器。这种方法提供了一对编码两个句子并对结果进行分类以训练模型。在这种情况下,与语言无关的 BERT 句子嵌入( LaBSE ) 也可能是一个不错的选择,它可以在句子转换器库和在TensorFlow Hub中也是如此。LaBSE 是基于 Transformers 的双编码器,类似于 Sentence-BERT,将两个具有相同参数的编码器与基于两个句子的双重相似性。
使用相同的示例,您可以通过非常简单的方式将模型更改为 LaBSE,然后重新运行之前的代码(步骤 1),如下所示:
model = SentenceTransformer("LaBSE")
结果显示在以下屏幕截图中:

图 9.7 – 抄袭检测结果 (LaBSE)
如您所见,LaBSE 在这种情况下表现更好,这次第4行的结果是正确的。LaBSE 作者声称它在查找句子的翻译方面效果很好,但在查找不完全相同的句子方面并不那么好。为此,在使用翻译窃取知识材料的情况下,它是一种非常有用的工具,可以用来发现抄袭。但是,还有许多其他因素会改变结果同样——例如,每种语言的预训练模型的资源大小和语言对的性质也很重要。为了合理的比较,我们需要更全面的实验,要考虑很多因素。
可视化跨语言文本相似性
现在,我们将测量和可视化两个句子之间的文本相似程度,其中一个是另一个句子的翻译。Tatoeba是免费的这些句子和翻译的集合,它是 XTREME 基准的一部分。社区旨在在众多参与者的支持下获得高质量的句子翻译。我们现在将采取以下步骤:
- 我们将从这个集合中得到俄语和英语句子。在开始工作之前,请确保已安装以下库:
!pip install sentence_transformers datasets transformers umap-learn
- 加载句子对,如下:
from datasets import load_dataset import pandas as pddata=load_dataset("xtreme","tatoeba.rus",split="validation")pd.DataFrame(data)[["source_sentence","target_sentence"]]
我们看一下输出,如下:
图 9.8 – 俄英句子对
- 首先,我们将采取前K=30 个句子对用于可视化,稍后,我们将对整个集合进行实验。现在,我们将使用前面示例中已经使用的句子转换器对它们进行编码。下面是代码的执行:
from sentence_transformers import SentenceTransformermodel = SentenceTransformer("stsb-xlm-r-multilingual") K=30 q=data["source_sentence"][:K] + data["target_sentence"][:K] emb=model.encode(q) len(emb), len(emb[0])
Output: (60, 768)
- 我们现在有 60 个长度为 768 的向量。我们将使用统一流形逼近和投影( UMAP )将维数降低到 2,我们将已经有在前面的章节中遇到过。我们将相互翻译的句子可视化,用相同的颜色和代码标记它们。我们还在它们之间画了一条虚线,以使链接更加明显。代码如以下片段所示:
import matplotlib.pyplot as plt import numpy as np import umap import pylabX= umap.UMAP(n_components=2, random_state=42).fit_transform(emb) idx= np.arange(len(emb)) fig, ax = plt.subplots(figsize=(12, 12)) ax.set_facecolor('whitesmoke') cm = pylab.get_cmap("prism") colors = list(cm(1.0*i/K) for i in range(K)) for i in idx:if i<K:ax.annotate("RUS-"+str(i), # text(X[i,0], X[i,1]), # coordinatesc=colors[i]) # colorax.plot((X[i,0],X[i+K,0]),(X[i,1],X[i+K,1]),"k:")else:ax.annotate("EN-"+str(i%K),(X[i,0], X[i,1]),c=colors[i%K])
图 9.9 – 俄英句子相似度可视化
- 为了进行全面分析,现在让我们测量整个数据集。我们对所有源语句和目标语句(1K 对)进行编码,如下所示:
source_emb=model.encode(data["source_sentence"])target_emb=model.encode(data["target_sentence"])
- 我们计算所有对之间的余弦相似度,将它们保存在sims 变量中,并绘制直方图,如下所示:
from scipy import spatialsims=[ 1 - spatial.distance.cosine(s,t) \for s,t in zip(source_emb, target_emb)] plt.hist(sims, bins=100, range=(0.8,1)) plt.show()
这是输出:
图 9.10 – 英语和俄语句子对的相似度直方图
- 可以看出,分数非常接近 1。这是我们对良好的跨语言模型的期望。所有相似度测量的均值和标准差也支持跨语言模型性能,如下:
np.mean(sims), np.std(sims)
(0.946, 0.082)
- 您可以自己为俄语以外的语言运行相同的代码。当您使用法语( fra )、泰米尔语( tam ) 等运行它时,您将得到以下结果表。该表表明,您将在实验中看到该模型在许多语言中运行良好,但在其他语言中则失败,例如南非荷兰语或泰米尔语:

表 1 – 其他语言的跨语言模型性能
在本节中,我们应用了跨语言模型来衡量不同语言之间的相似性。在下一节中,我们将以监督的方式使用跨语言模型。
跨语言分类
到目前为止,您已经了解到跨语言模型能够理解语义向量空间中的不同语言,其中相似的句子,无论其语言如何,在向量距离方面都很接近。但是,在我们可用的样本很少的用例中,如何使用此功能呢?
例如,您正在尝试为聊天机器人开发意图分类,其中第二语言的样本很少或没有可用的样本;但是对于第一语言——比如说英语——你确实有足够的样本。在这种情况下,可以冻结跨语言模型本身,只为任务训练一个分类器。一个训练有素的分类器可以在第二语言而不是它所训练的语言上进行测试。
在本节中,您将学习如何用英语训练一个跨语言模型进行文本分类,并用其他语言对其进行测试。我们选择了一种资源非常少的语言作为高棉语(https://en.wikipedia.org/wiki/Khmer_language),在柬埔寨、泰国和越南有 1600 万人使用。它在互联网上的资源很少,而且很难找到好的数据集来训练你的模型。但是,我们可以访问一个很好的互联网电影数据库( IMDb ) 电影评论情感数据集以获取情感分析。我们将使用该数据集来了解我们的模型在它没有受过训练的语言。
下图很好地描述了我们将遵循的流程。该模型使用左侧的训练数据进行训练,该模型应用于右侧的测试集。请注意,机器翻译和句子编码器映射在流程中起着重要作用:

图 9.11 – 跨语言分类流程
加载所需的步骤并训练一个用于跨语言测试的模型是此处概述:
- 第一步是加载数据集,如下:
from datasets import load_datasetsms_spam = load_dataset("imdb")
- 在使用样本之前,您需要对数据集进行混洗,如下所示:
imdb = imdb.shuffle()
- 下一步是从这个数据集(使用高棉语)中拆分出一个好的测试。为此,您可以使用谷歌翻译等翻译服务。首先,您应该将此数据集保存为 Excel 格式,如下所示:
imdb_x = [x for x in imdb['train'][:1000]['text']] labels = [x for x in imdb['train'][:1000]['label']] import pandas as pd pd.DataFrame(imdb_x,columns=["text"]).to_excel("imdb.xlsx",index=None)
- 之后,您可以将其上传到谷歌翻译并获取该数据集的高棉语翻译(https://translate.google.com/?sl=en&tl=km&op=docs),如下图所示:
图 9.12 – 谷歌文档翻译器
- 选择后并上传文件,它将为您提供高棉语的翻译版本,您可以将其复制并粘贴到 Excel 文件中。还需要再次以 Excel 格式保存。结果将是一个 Excel 文档,它是原始 spam/ham 英语数据集的翻译。您可以通过运行以下命令使用 pandas 读取它:
pd.read_excel("KHMER.xlsx")
可以看到结果,如下:
图 9.13 – 高棉语 IMDB 数据集。
- 然而,它是只需要获取文本,因此您应该使用以下代码:
imdb_khmer = list(pd.read_excel("KHMER.xlsx").text)
- 现在您已经拥有两种语言和标签的文本,您可以拆分训练和测试验证,如下所示:
from sklearn.model_selection import train_test_splittrain_x, test_x, train_y, test_y, khmer_train, khmer_test = train_test_split(imdb_x, labels, imdb_khmer, test_size = 0.2, random_state = 1)
- 下一步是使用 XLM-R 跨语言模型提供这些句子的表示。首先,您应该加载模型,如下所示:
from sentence_transformers import SentenceTransformermodel = SentenceTransformer("stsb-xlm-r-multilingual")
- 现在,您可以获得这些表示,如下所示:
encoded_train = model.encode(train_x) encoded_test = model.encode(test_x) encoded_khmer_test = model.encode(khmer_test)
- 但是你不要忘记将标签转换为numpy格式因为 TensorFlow 和 Keras 在使用 Keras 模型的fit函数时只处理numpy数组。这是如何做到的:
import numpy as nptrain_y = np.array(train_y) test_y = np.array(test_y)
- 现在一切准备就绪,让我们制作一个非常简单的模型来对表示进行分类,如下所示:
import tensorflow as tfinput_ = tf.keras.layers.Input((768,)) classification = tf.keras.layers.Dense(1,activation="sigmoid")(input_)classification_model = tf.keras.Model(input_, classification)classification_model.compile(loss=tf.keras.losses.BinaryCrossentropy(),optimizer="Adam",metrics=["accuracy", "Precision", "Recall"])
- 你可以适合您的模型使用以下功能:
classification_model.fit(x = encoded_train,y = train_y,validation_data=(encoded_test, test_y),epochs = 10)
- 并且显示了20 个epoch 的训练结果,如下所示:
图 9.14 – IMDb 数据集英文版的训练结果
- 如您所见,我们使用英语测试集来查看跨时期的模型性能,在最终时期报告如下:
val_loss: 0.5226 val_accuracy: 0.7150 val_precision: 0.7600 val_recall: 0.6972
- 现在我们已经训练了我们的模型并在英语上对其进行了测试,让我们在高棉语测试集上对其进行测试,因为我们的模型从未见过任何英语或高棉语样本。这是完成此操作的代码:
classification_model.evaluate(x = encoded_khmer_test, y = test_y)
结果如下:
loss: 0.5949 accuracy: 0.7250 precision: 0.7014 recall: 0.8623
到目前为止,你已经学会了我是如何t 可以利用低资源语言的跨语言模型。当您可以在样本很少或没有样本来训练模型的情况下使用这种功能时,它会产生巨大的影响和差异。在下一节中,您将了解如何在没有可用样本的情况下使用零样本学习,即使是英语等资源丰富的语言也是如此。
跨语言零样本学习
在前面的部分中,您学习了如何使用单语模型执行零样本文本分类。使用 XLM-R 进行多语言和跨语言零样本分类与之前使用的方法和代码相同,因此我们将在这里使用mT5。
mT5 是一种大规模多语言预训练语言模型,基于 Transformers 的编码器-解码器架构,也与T5相同。T5 是预训练英语和 mT5 是对多语言通用爬网( mC4 )中的 101 种语言进行了培训。
XNLI 数据集上的 mT5 微调版本可从 HuggingFace 存储库 ( alan-turing-institute/mt5-large-finetuned-mnli-xtreme-xnli · Hugging Face ) 获得。
T5 模型及其变体 mT5 是一个完全文本到文本的模型,这意味着它将为给定的任何任务生成文本,即使任务是分类或 NLI。因此,在推断此模型的情况下,需要额外的步骤。我们将采取以下步骤:
- 第一步是加载模型和分词器,如下:
from torch.nn.functional import softmax from transformers import MT5ForConditionalGeneration, MT5Tokenizermodel_name = "alan-turing-institute/mt5-large-finetuned-mnli-xtreme-xnli" tokenizer = MT5Tokenizer.from_pretrained(model_name) model = MT5ForConditionalGeneration.from_pretrained(model_name)
- 在下一步中,让我们提供用于零样本分类的样本——一个句子和标签,如下所示:
sequence_to_classify = "Wen werden Sie bei der nächsten Wahl wählen? "candidate_labels = ["spor", "ekonomi", "politika"] hypothesis_template = "Dieses Beispiel ist {}."
如您所见,序列本身是德语(“你将在下次选举中投票给谁?”),但标签是用土耳其语写的(“spor”、“ ekonomi” 、 “politika ”)。假设模板用德语说:“这个例子是……”。
- 下一步是设置蕴涵、CONTRADICTS和NEUTRAL的标签标识符( IDs ) ,稍后将用于推断生成的结果。这是您需要执行此操作的代码:
ENTAILS_LABEL = "_0" NEUTRAL_LABEL = "_1" CONTRADICTS_LABEL = "_2"label_inds = tokenizer.convert_tokens_to_ids([ENTAILS_LABEL,NEUTRAL_LABEL,CONTRADICTS_LABEL])
- 你会记得,T5 模型使用前缀来了解它应该执行的任务。以下函数提供 XNLI 前缀,以及正确格式的前提和假设:
def process_nli(premise, hypothesis):return f'xnli: premise: {premise} hypothesis: {hypothesis}'
- 在下一步中,对于每个标签,都会生成一个句子,如下面的代码片段所示:
pairs =[(sequence_to_classify,\ hypothesis_template.format(label)) for label incandidate_labels]seqs = [process_nli(premise=premise,hypothesis=hypothesis)for premise, hypothesis in pairs]
- 您可以通过打印它们来查看生成的序列,如下所示:
print(seqs)
['xnli: premise: Wen werden Sie bei der nächsten Wahl wählen? hypothesis: Dieses Beispiel ist spor.',
'xnli: premise: Wen werden Sie bei der nächsten Wahl wählen? hypothesis: Dieses Beispiel ist ekonomi.',
'xnli: premise: Wen werden Sie bei der nächsten Wahl wählen? hypothesis: Dieses Beispiel ist politika.']
这些序列简单地说,任务是由 xnli 编码的XNLI: ; 前提句是“你将在下次选举中投票给谁?” (德语),假设是“这个例子是政治”、“这个例子是运动”或“这个例子是经济”。
- 在下一步中,您可以对序列进行标记,并将它们交给模型以根据它生成文本,如下所示:
inputs = tokenizer.batch_encode_plus(seqs, return_tensors="pt", padding=True)out = model.generate(**inputs, output_scores=True,return_dict_in_generate=True,num_beams=1)
- 生成的文本实际上对词汇表中的每个标记都给出了分数,而我们要寻找的是蕴含、矛盾和中性分数。您可以使用他们的令牌 ID 获得他们的分数,如下所示:
scores = out.scores[0] scores = scores[:, label_inds]
- 您可以通过打印这些分数来查看它们,如下所示:
print(scores)
tensor([[-0.9851, 2.2550, -0.0783],
[-5.1690, -0.7202, -2.5855],
[ 2.7442, 3.6727, 0.7169]])
- 中性分数不是为我们的目的所必需,与蕴涵相比,我们只需要矛盾。因此,您可以使用以下代码仅获取这些分数:
entailment_ind = 0 contradiction_ind = 2 entail_vs_contra_scores = scores[:, [entailment_ind, contradiction_ind]]
- 现在您已经为每个样本序列获得了这些分数,您可以在其上应用一个softmax层来获得概率,如下所示:
entail_vs_contra_probas = softmax(entail_vs_contra_scores, dim=1)
- 要查看这些概率,您可以使用print,如下所示:
print(entail_vs_contra_probas)
tensor([[0.2877, 0.7123],
[0.0702, 0.9298],
[0.8836, 0.1164]])
- 现在,您可以通过选择它们并在它们上应用softmax层来比较这三个样本的蕴含概率,如下所示:
entail_scores = scores[:, entailment_ind]
entail_probas = softmax(entail_scores, dim=0)
- 要查看值,请使用print,如下所示:
print(entail_probas)
tensor([2.3438e-02, 3.5716e-04, 9.7620e-01])
- 结果意味着最高概率属于第三个序列。为了更好地看到它形状,使用以下代码:
print(dict(zip(candidate_labels, entail_probas.tolist())))
{'ekonomi': 0.0003571564157027751,
'politika': 0.9762046933174133,
'spor': 0.023438096046447754}
整个过程可以概括为:每个标签都赋予给模型有前提,模型为词汇表中的每个token生成分数。我们使用这些分数来找出蕴含令牌对矛盾的分数。
多语言模型的基本限制
虽然多语种和跨语言模型很有前途,会影响 NLP 工作的方向,但它们仍然存在一些局限性。最近的许多作品解决了这些限制。目前,与单语模型相比,mBERT 模型在许多任务中的表现略逊一筹,并且可能无法替代经过良好训练的单语模型,这就是为什么单语模型仍然被广泛使用的原因。
该领域的研究表明,多语言模型受到所谓的多语言诅咒,因为它们试图适当地代表所有语言。将新语言添加到多语言模型可以提高其性能,达到一定程度。但是,也可以看出,在这一点之后添加它会降低性能,这可能是由于共享词汇表造成的。与单语模型相比,多语言模型在参数预算方面明显受限。他们需要将词汇分配到 100 多种语言中的每一种。
单语言模型和多语言模型之间现有的性能差异可归因于指定标记器的能力。研究你的标记器有多好?Rust 等人的关于多语言模型的单语性能(2021 年)。( https://arxiv.org/abs/2012.15613 ) 表明,当将专用的特定语言标记器而不是通用标记器(共享的多语言标记器)附加到多语言模型时,它会提高该语言的性能。
其他一些发现表明由于不同语言的资源分布不平衡,目前不可能在一个模型中代表世界上所有的语言。作为一种解决方案,可以对低资源语言进行过采样,而对高资源语言进行欠采样。另一个观察结果是,如果两种语言相近,两种语言之间的知识转移会更有效。如果它们是遥远的语言,这种转移可能影响不大。这一观察结果可以解释为什么我们在之前的跨语言句子对实验部分中对南非荷兰语和泰米尔语的结果更差。
然而,在这个主题上有很多工作,这些限制可能随时被克服。在撰写本文时,XML-R 团队最近提出了两个新模型,即 XLM-R XL 和 XLM-R XXL,它们在 XNLI 上的平均准确度分别比原始 XLM-R 模型高 1.8% 和 2.4%。
微调多语言模型的性能
现在,让我们检查一下多语言模型的微调性能实际上是否比单语模型差型号与否。作为一个例子,让我们回顾一下第 5 章“文本分类的微调语言模型”中的土耳其语文本分类的例子,它有 7 个类。在那个实验中,我们微调了一个土耳其语特有的单语模型并取得了很好的效果。我们将重复相同的实验,保持一切不变,但分别用 mBERT 和 XLM-R 模型替换土耳其单语模型。我们将这样做:
- 让我们再次回忆一下该示例中的代码。我们对“dbmdz/bert-base-turkish-uncased”模型进行了微调,如下所示:
from transformers import BertTokenizerFasttokenizer = BertTokenizerFast.from_pretrained("dbmdz/bert-base-turkish-uncased")from transformers import BertForSequenceClassification model = BertForSequenceClassification.from_pretrained("dbmdz/bert-base-turkish-uncased",num_labels=NUM_LABELS,id2label=id2label,label2id=label2id)
图 9.15 – 单语文本分类性能(来自第 5 章,文本分类的微调语言模型)
- 要使用 mBERT 进行微调,我们只需要替换前面的模型实例化行。现在,我们将使用“bert-base-multilingual-uncased”多语言模型。我们像这样实例化它:
从变压器进口\ BertForSequenceClassification,AutoTokenizer
from transformers import BertForSequenceClassification, AutoTokenizertokenizer = AutoTokenizer.from_pretrained("bert-base-multilingual-uncased") model = BertForSequenceClassification.from_pretrained("bert-base-multilingual-uncased",num_labels=NUM_LABELS,id2label=id2label,label2id=label2id)
- 有编码差别不大。当我们在保持所有其他参数和设置相同的情况下运行实验时,我们得到以下性能值:
图 9.16 – mBERT 微调性能
唔!与单语模型相比,多语言模型在所有指标上的表现都差了大约 2.2%。
- 让我们针对相同的问题微调“xlm-roberta-base” XLM-R 模型。我们将执行 XLM-R 模型初始化代码,如下所示:
from transformers import AutoTokenizer, XLMRobertaForSequenceClassificationtokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base")model = XLMRobertaForSequenceClassification.from_pretrained("xlm-roberta-base",num_labels=NUM_LABELS,id2label=id2label,label2id=label2id)
- 同样,我们保持所有其他设置完全相同。我们使用 XML-R 模型获得以下性能值:
图 9.17 – XLM-R 微调性能
不错!这XLM 模型确实给出了可比较的结果。得到的结果与单语模型非常接近,相差约 1.0%。因此,尽管在某些任务中单语结果可能优于多语言模型,但我们可以使用多语言模型取得有希望的结果。可以这样想:我们可能不想训练一个完整的单语模型来获得持续 10 天或更长时间的 1% 性能。如此小的性能差异对我们来说可能可以忽略不计。
概括
在本章中,您了解了多语言和跨语言语言模型预训练以及单语言和多语言预训练之间的区别。还涵盖了 CLM 和 TLM,并且您获得了有关它们的知识。您了解了如何在各种用例中使用跨语言模型,例如语义搜索、抄袭和零样本文本分类。您还了解了如何使用跨语言模型对来自一种语言的数据集进行训练并在完全不同的语言上进行测试。对多语言模型的性能微调进行了评估,我们得出的结论是,一些多语言模型可以替代单语言模型,显着地将性能损失降至最低。