Transformers 4.37 中文文档(十二)(1)https://developer.aliyun.com/article/1564912
计算机视觉
有两种方法可以处理计算机视觉任务:
- 将图像分割成一系列补丁,并使用 Transformer 并行处理它们。
- 使用现代 CNN,比如 ConvNeXT,它依赖卷积层但采用现代网络设计。
第三种方法将 Transformer 与卷积结合(例如卷积视觉 Transformer 或 LeViT)。我们不会讨论这些,因为它们只是将我们在这里研究的两种方法结合起来。
ViT 和 ConvNeXT 通常用于图像分类,但对于其他视觉任务,如目标检测、分割和深度估计,我们将分别查看 DETR、Mask2Former 和 GLPN;这些模型更适合这些任务。
图像分类
ViT 和 ConvNeXT 都可以用于图像分类;主要区别在于 ViT 使用注意机制,而 ConvNeXT 使用卷积。
Transformer
ViT 完全用纯 Transformer 架构替换了卷积。如果你熟悉原始 Transformer,那么你已经基本理解了 ViT。
ViT 引入的主要变化是如何将图像馈送到 Transformer 中:
- 图像被分割成方形不重叠的补丁,每个补丁都被转换为一个向量或补丁嵌入。补丁嵌入是从一个卷积 2D 层生成的,该层创建了适当的输入维度(对于基础 Transformer 来说,每个补丁嵌入有 768 个值)。如果你有一个 224x224 像素的图像,你可以将其分割成 196 个 16x16 的图像补丁。就像文本被标记为单词一样,图像被“标记”为一系列补丁。
- 一个可学习的嵌入 - 一个特殊的
[CLS]
标记 - 被添加到补丁嵌入的开头,就像 BERT 一样。[CLS]
标记的最终隐藏状态被用作附加分类头的输入;其他输出被忽略。这个标记帮助模型学习如何编码图像的表示。 - 将补丁和可学习嵌入的最后一件事是添加位置嵌入,因为模型不知道图像补丁的顺序。位置嵌入也是可学习的,并且与补丁嵌入具有相同的大小。最后,所有嵌入都传递给 Transformer 编码器。
- 输出,特别是只有带有
[CLS]
标记的输出,被传递到一个多层感知器头(MLP)。ViT 的预训练目标只是分类。像其他分类头一样,MLP 头将输出转换为类标签上的 logits,并计算交叉熵损失以找到最可能的类别。
准备尝试图像分类?查看我们完整的 image classification guide 来学习如何微调 ViT 并将其用于推断!
卷积神经网络
本节简要解释了卷积,但了解它们如何改变图像的形状和大小将会很有帮助。如果您对卷积不熟悉,请查看 fastai 书中的Convolution Neural Networks 章节!
ConvNeXT 是一种采用新的现代网络设计来提高性能的 CNN 架构。然而,卷积仍然是模型的核心。从高层次的角度来看,卷积是一种操作,其中一个较小的矩阵(核)与图像像素的一个小窗口相乘。它从中计算一些特征,比如特定的纹理或线条的曲率。然后它滑动到下一个像素窗口;卷积移动的距离被称为步幅。
从A guide to convolution arithmetic for deep learning.中提取的不带填充或步幅的基本卷积。
您可以将此输出馈送到另一个卷积层,随着每个连续层,网络学习更复杂和抽象的事物,如热狗或火箭。在卷积层之间,通常会添加一个池化层来减少维度,并使模型更能够适应特征位置的变化。
ConvNeXT 以五种方式现代化 CNN:
- 改变每个阶段的块数,并使用更大的步幅和相应的核大小对图像进行“patchify”。不重叠的滑动窗口使得这种 patchifying 策略类似于 ViT 如何将图像分成补丁。
- 一个瓶颈层会减少通道数量,然后通过进行 1x1 卷积来恢复,因为这样做更快,而且可以增加深度。一个反向瓶颈则相反,通过扩展通道数量然后再缩小,这样更节省内存。
- 在瓶颈层中用深度卷积替换典型的 3x3 卷积层,深度卷积对每个输入通道分别应用卷积,然后在最后将它们堆叠在一起。这样可以扩大网络宽度,提高性能。
- ViT 具有全局感受野,这意味着它可以一次看到更多图像,这要归功于其注意力机制。ConvNeXT 尝试通过将核大小增加到 7x7 来复制这种效果。
- ConvNeXT 还进行了几个层设计更改,模仿 Transformer 模型。激活和归一化层更少,激活函数从 ReLU 切换为 GELU,并且使用 LayerNorm 代替 BatchNorm。
来自卷积块的输出被传递到一个分类头,将输出转换为 logits,并计算交叉熵损失以找到最可能的标签。
目标检测
DETR, DEtection TRansformer,是一个将 CNN 与 Transformer 编码器-解码器结合起来的端到端目标检测模型。
- 一个预训练的 CNN 骨干 接收一幅图像,由其像素值表示,并创建其低分辨率特征图。对特征图应用 1x1 卷积以降低维度,并创建具有高级图像表示的新特征图。由于 Transformer 是一个顺序模型,特征图被展平成一系列特征向量,这些向量与位置嵌入相结合。
- 特征向量传递给编码器,编码器使用其注意力层学习图像表示。接下来,编码器隐藏状态与解码器中的对象查询相结合。对象查询是学习的嵌入,专注于图像的不同区域,并在通过每个注意力层时更新。解码器隐藏状态传递给一个前馈网络,该网络预测每个对象查询的边界框坐标和类别标签,或者如果没有对象则为
无对象
。
DETR 并行解码每个对象查询以输出N个最终预测,其中N是查询的数量。与典型的自回归模型一次预测一个元素不同,目标检测是一个集合预测任务(边界框
,类别标签
),在一次传递中进行N次预测。 - DETR 在训练过程中使用二部匹配损失来比较固定数量的预测和固定的一组真实标签。如果在N个标签集中有更少的真实标签,则它们将用
无对象
类进行填充。这个损失函数鼓励 DETR 找到预测和真实标签之间的一对一分配。如果边界框或类别标签不正确,则会产生损失。同样,如果 DETR 预测了一个不存在的对象,它将受到惩罚。这鼓励 DETR 在图像中找到其他对象,而不是专注于一个非常突出的对象。
在 DETR 之上添加了一个目标检测头,用于查找类别标签和边界框的坐标。目标检测头有两个组件:一个线性层将解码器隐藏状态转换为类别标签上的 logits,以及一个 MLP 来预测边界框。
准备尝试目标检测?查看我们完整的目标检测指南来学习如何微调 DETR 并将其用于推断!
图像分割
Mask2Former 是一个通用架构,用于解决所有类型的图像分割任务。传统的分割模型通常针对图像分割的特定子任务进行定制,如实例、语义或全景分割。Mask2Former 将这些任务中的每一个都视为一个掩码分类问题。掩码分类将像素分组成N个段,并为给定图像预测N个掩码及其相应的类别标签。我们将在本节中解释 Mask2Former 的工作原理,然后您可以在最后尝试微调 SegFormer。
Mask2Former 有三个主要组件:
- 一个 Swin 骨干接受一幅图像,并从 3 个连续的 3x3 卷积中创建一个低分辨率图像特征图。
- 特征图传递给一个像素解码器,逐渐将低分辨率特征上采样为高分辨率的逐像素嵌入。像素解码器实际上生成多尺度特征(包含低分辨率和高分辨率特征),分辨率为原始图像的 1/32、1/16 和 1/8。
- 这些不同尺度的特征图依次被馈送到一个 Transformer 解码器层,以便从高分辨率特征中捕获小物体。Mask2Former 的关键在于解码器中的掩码注意力机制。与可以关注整个图像的交叉注意力不同,掩码注意力只关注图像的某个区域。这样做更快,性能更好,因为图像的局部特征足以让模型学习。
- 与 DETR 类似,Mask2Former 还使用学习的对象查询,并将它们与像素解码器的图像特征组合以进行一组预测(
类标签
,掩码预测
)。解码器隐藏状态被传递到线性层,并转换为类标签上的逻辑。计算逻辑和类标签之间的交叉熵损失以找到最可能的类标签。
掩码预测是通过将像素嵌入与最终解码器隐藏状态相结合生成的。通过逻辑和地面真实掩码之间计算 sigmoid 交叉熵和 dice 损失以找到最可能的掩码。
准备尝试目标检测?查看我们完整的图像分割指南来学习如何微调 SegFormer 并将其用于推断!
深度估计
GLPN,全局-局部路径网络,是一个用于深度估计的 Transformer,它将 SegFormer 编码器与轻量级解码器结合起来。
- 与 ViT 类似,图像被分割成一个序列的补丁,只是这些图像补丁更小。这对于密集预测任务如分割或深度估计更好。图像补丁被转换为补丁嵌入(有关如何创建补丁嵌入的更多详细信息,请参阅图像分类部分),然后馈送到编码器。
- 编码器接受补丁嵌入,并通过多个编码器块传递它们。每个块由注意力和 Mix-FFN 层组成。后者的目的是提供位置信息。在每个编码器块的末尾是一个补丁合并层,用于创建分层表示。相邻补丁组的特征被串联起来,并且对串联特征应用线性层以减少补丁数量至 1/4 的分辨率。这成为下一个编码器块的输入,整个过程在那里重复,直到您获得分辨率为 1/8、1/16 和 1/32 的图像特征。
- 轻量级解码器从编码器中获取最后的特征图(1/32 比例)并将其上采样至 1/16 比例。然后,该特征被传递到*选择性特征融合(SFF)*模块中,该模块从注意力图中选择和组合每个特征的局部和全局特征,然后将其上采样至 1/8。这个过程重复进行,直到解码特征与原始图像大小相同。输出通过两个卷积层,然后应用 sigmoid 激活以预测每个像素的深度。
自然语言处理
Transformer 最初是为机器翻译而设计的,自那时以来,它实际上已经成为解决所有 NLP 任务的默认架构。一些任务适合 Transformer 的编码器结构,而其他任务更适合解码器。还有一些任务利用 Transformer 的编码器-解码器结构。
文本分类
BERT 是一个仅编码器模型,是第一个有效实现深度双向性以通过同时关注单词两侧来学习文本更丰富表示的模型。
- BERT 使用 WordPiece 标记化来生成文本的标记嵌入。为了区分单个句子和一对句子之间的区别,添加了一个特殊的
[SEP]
标记来区分它们。在每个文本序列的开头添加了一个特殊的[CLS]
标记。带有[CLS]
标记的最终输出用作分类任务的分类头的输入。BERT 还添加了一个段嵌入,用于表示一个标记属于一对句子中的第一句还是第二句。 - BERT 使用两个目标进行预训练:掩码语言建模和下一句预测。在掩码语言建模中,输入标记的一定百分比被随机掩盖,模型需要预测这些标记。这解决了双向性的问题,其中模型可以作弊并看到所有单词并“预测”下一个单词。预测的掩码标记的最终隐藏状态传递给一个具有词汇表上的 softmax 的前馈网络,以预测掩码单词。
第二个预训练目标是下一句预测。模型必须预测句子 B 是否跟在句子 A 后面。一半的时间句子 B 是下一个句子,另一半的时间,句子 B 是一个随机句子。预测,无论是下一个句子还是不是,都传递给一个具有两个类别(IsNext
和NotNext
)的 softmax 的前馈网络。 - 输入嵌入通过多个编码器层传递以输出一些最终隐藏状态。
要使用预训练模型进行文本分类,需要在基本 BERT 模型的顶部添加一个序列分类头。序列分类头是一个线性层,接受最终的隐藏状态,并执行线性变换以将它们转换为对数。在对数和目标之间计算交叉熵损失,以找到最可能的标签。
准备好尝试文本分类了吗?查看我们完整的文本分类指南来学习如何微调 DistilBERT 并将其用于推理!
标记分类
要将 BERT 用于像命名实体识别(NER)这样的标记分类任务,需要在基本 BERT 模型的顶部添加一个标记分类头。标记分类头是一个线性层,接受最终的隐藏状态,并执行线性变换以将它们转换为对数。在对数和每个标记之间计算交叉熵损失,以找到最可能的标签。
准备好尝试标记分类了吗?查看我们完整的 token 分类指南来学习如何微调 DistilBERT 并将其用于推理!
问答
要将 BERT 用于问答,需要在基本 BERT 模型的顶部添加一个跨度分类头。这个线性层接受最终的隐藏状态,并执行线性变换以计算与答案对应的span
起始和结束对数。在对数和标签位置之间计算交叉熵损失,以找到与答案对应的最可能跨度的文本。
准备好尝试问答了吗?查看我们完整的问答指南来学习如何微调 DistilBERT 并将其用于推理!
💡注意一旦 BERT 被预训练后,使用它进行不同任务是多么容易。您只需要向预训练模型添加一个特定的头部,将隐藏状态操纵成您想要的输出!
文本生成
GPT-2 是一个仅解码的模型,预训练了大量文本。它可以生成令人信服的(尽管不总是真实的!)文本,给定一个提示并完成其他 NLP 任务,如问答,尽管没有明确训练。
- GPT-2 使用字节对编码(BPE)对单词进行标记化并生成令牌嵌入。位置编码添加到令牌嵌入中,以指示序列中每个令牌的位置。输入嵌入通过多个解码器块传递以输出一些最终隐藏状态。在每个解码器块内,GPT-2 使用屏蔽自注意力层,这意味着 GPT-2 不能关注未来的令牌。它只允许关注左侧的令牌。这与 BERT 的
mask
令牌不同,因为在屏蔽自注意力中,使用注意力掩码将未来的令牌得分设置为0
。 - 解码器的输出传递给语言建模头部,执行线性转换将隐藏状态转换为 logits。标签是序列中的下一个令牌,通过将 logits 向右移动一个来创建。在移位 logits 和标签之间计算交叉熵损失,以输出下一个最可能的令牌。
GPT-2 的预训练目标完全基于因果语言建模,预测序列中的下一个单词。这使得 GPT-2 在涉及生成文本的任务中表现特别出色。
准备好尝试文本生成了吗?查看我们完整的因果语言建模指南来学习如何微调 DistilGPT-2 并将其用于推理!
有关文本生成的更多信息,请查看文本生成策略指南!
摘要
像 BART 和 T5 这样的编码器-解码器模型是为摘要任务的序列到序列模式而设计的。我们将在本节中解释 BART 的工作原理,然后您可以在最后尝试微调 T5。
- BART 的编码器架构与 BERT 非常相似,接受文本的令牌和位置嵌入。BART 通过破坏输入然后使用解码器重建来进行预训练。与具有特定破坏策略的其他编码器不同,BART 可以应用任何类型的破坏。然而,文本填充破坏策略效果最好。在文本填充中,一些文本段被替换为一个单个
mask
令牌。这很重要,因为模型必须预测被屏蔽的令牌,并且它教会模型预测缺失令牌的数量。输入嵌入和屏蔽的段通过编码器传递以输出一些最终隐藏状态,但与 BERT 不同,BART 不会在最后添加最终的前馈网络来预测一个单词。 - 编码器的输出传递给解码器,解码器必须预测编码器输出中的屏蔽令牌和任何未损坏的令牌。这提供了额外的上下文来帮助解码器恢复原始文本。解码器的输出传递给语言建模头部,执行线性转换将隐藏状态转换为 logits。在 logits 和标签之间计算交叉熵损失,标签只是向右移动的令牌。
准备好尝试摘要了吗?查看我们完整的摘要指南来学习如何微调 T5 并将其用于推理!
有关文本生成的更多信息,请查看文本生成策略指南!
翻译
翻译是另一个序列到序列任务的例子,这意味着您可以使用像 BART 或 T5 这样的编码器-解码器模型来执行。我们将在本节中解释 BART 的工作原理,然后您可以在最后尝试微调 T5。
BART 通过添加一个单独的随机初始化编码器来适应翻译,将源语言映射到一个可以解码为目标语言的输入。这个新编码器的嵌入被传递给预训练编码器,而不是原始词嵌入。源编码器通过使用模型输出的交叉熵损失来更新源编码器、位置嵌入和输入嵌入进行训练。在这一步中,模型参数被冻结,所有模型参数在第二步中一起训练。
BART 之后推出了多语言版本 mBART,旨在用于翻译并在许多不同语言上进行预训练。
准备尝试翻译吗?查看我们的完整翻译指南来学习如何微调 T5 并将其用于推理!
要了解更多关于文本生成的信息,请查看文本生成策略指南!
Transformer 模型家族
原始文本:
huggingface.co/docs/transformers/v4.37.2/en/model_summary
自 2017 年引入原始 Transformer模型以来,它已经激发了许多新颖且令人兴奋的模型,超越了自然语言处理(NLP)任务。有用于预测蛋白质的折叠结构、训练猎豹奔跑和时间序列预测的模型。有这么多 Transformer 变体可用,很容易忽略更大的画面。所有这些模型的共同之处是它们都基于原始 Transformer 架构。一些模型只使用编码器或解码器,而其他一些则同时使用两者。这提供了一个有用的分类法,可以对 Transformer 家族中的模型进行分类和检查高层次的差异,这将帮助您理解以前未遇到的 Transformer。
如果您不熟悉原始 Transformer 模型或需要复习,请查看 Hugging Face 课程中的Transformer 工作原理章节。
www.youtube.com/embed/H39Z_720T5s
计算机视觉
卷积网络
长时间以来,卷积网络(CNNs)一直是计算机视觉任务的主导范式,直到视觉 Transformer展示了其可扩展性和效率。即使如此,CNN 的一些最佳特性,如平移不变性,是如此强大(尤其对于某些任务),以至于一些 Transformer 在其架构中引入了卷积。ConvNeXt 颠倒了这种交换,并从 Transformer 中引入设计选择来现代化 CNN。例如,ConvNeXt 使用非重叠滑动窗口将图像分块化,并使用更大的内核来增加其全局感受野。ConvNeXt 还做出了几个层设计选择,以提高内存效率和性能,因此它与 Transformer 竞争有利!
编码器
视觉 Transformer(ViT)为计算机视觉任务打开了没有卷积的大门。ViT 使用标准 Transformer 编码器,但其主要突破在于它如何处理图像。它将图像分割成固定大小的补丁,并使用它们创建嵌入,就像将句子分割成标记一样。ViT 利用 Transformer 的高效架构展示了与当时的 CNN 竞争力的结果,同时需要更少的资源进行训练。ViT 很快被其他视觉模型跟随,这些模型也可以处理像分割和检测这样的密集视觉任务。
其中一个模型是 Swin Transformer。它从较小的补丁中构建分层特征图(类似于 CNN👀,不同于 ViT),并在更深层中将它们与相邻的补丁合并。注意力仅在局部窗口内计算,并且在注意力层之间移动窗口以创建连接以帮助模型学习更好。由于 Swin Transformer 可以生成分层特征图,因此它是密集预测任务(如分割和检测)的良好候选。SegFormer 也使用 Transformer 编码器构建分层特征图,但它在顶部添加了一个简单的多层感知器(MLP)解码器,以组合所有特征图并进行预测。
其他视觉模型,如 BeIT 和 ViTMAE,从 BERT 的预训练目标中汲取灵感。BeIT 通过masked image modeling (MIM) 进行预训练;图像补丁被随机屏蔽,图像也被标记为视觉标记。BeIT 被训练以预测与被屏蔽补丁对应的视觉标记。ViTMAE 有一个类似的预训练目标,只是它必须预测像素而不是视觉标记。不寻常的是,75%的图像补丁被屏蔽!解码器从被屏蔽的标记和编码的补丁中重建像素。预训练后,解码器被丢弃,编码器准备好用于下游任务。
解码器
仅解码器的视觉模型很少,因为大多数视觉模型依赖编码器来学习图像表示。但对于像图像生成这样的用例,解码器是一个自然的选择,正如我们从 GPT-2 等文本生成模型中看到的那样。ImageGPT 使用与 GPT-2 相同的架构,但它不是预测序列中的下一个标记,而是预测图像中的下一个像素。除了图像生成,ImageGPT 也可以进行微调以用于图像分类。
编码器-解码器
视觉模型通常使用编码器(也称为骨干)来提取重要的图像特征,然后将它们传递给 Transformer 解码器。DETR 有一个预训练的骨干,但它还使用完整的 Transformer 编码器-解码器架构进行目标检测。编码器学习图像表示,并将其与对象查询(每个对象查询是一个专注于图像中的区域或对象的学习嵌入)结合在解码器中。DETR 预测每个对象查询的边界框坐标和类别标签。
自然语言处理
编码器
BERT 是一个仅包含编码器的 Transformer,它会随机屏蔽输入中的某些标记,以避免看到其他标记,这样可以防止其“作弊”。预训练的目标是基于上下文预测被屏蔽的标记。这使得 BERT 能够充分利用左右上下文来帮助学习输入的更深层和更丰富的表示。然而,BERT 的预训练策略仍有改进的空间。RoBERTa 通过引入一个新的预训练配方来改进这一点,该配方包括更长时间和更大批次的训练,在每个时代随机屏蔽标记,而不仅仅是在预处理期间一次,以及移除下一个句子预测目标。
提高性能的主要策略是增加模型大小。但是训练大型模型在计算上是昂贵的。减少计算成本的一种方法是使用像 DistilBERT 这样的较小模型。DistilBERT 使用知识蒸馏 - 一种压缩技术 - 来创建一个较小版本的 BERT,同时保留几乎所有的语言理解能力。
然而,大多数 Transformer 模型继续朝着更多参数的方向发展,导致出现了专注于提高训练效率的新模型。ALBERT 通过两种方式降低参数数量来减少内存消耗:将更大的词汇嵌入分为两个较小的矩阵,并允许层共享参数。DeBERTa 添加了一个解耦的注意机制,其中单词及其位置分别编码在两个向量中。注意力是从这些单独的向量计算而来,而不是从包含单词和位置嵌入的单个向量中计算。Longformer 也专注于使注意力更加高效,特别是用于处理具有更长序列长度的文档。它使用局部窗口注意力(仅计算围绕每个标记的固定窗口大小的注意力)和全局注意力(仅用于特定任务标记,如[CLS]
用于分类)的组合,以创建一个稀疏的注意力矩阵,而不是完整的注意力矩阵。
解码器
GPT-2 是一个仅解码器的 Transformer,用于预测序列中的下一个单词。它会屏蔽右侧的标记,以防模型通过向前查看来“作弊”。通过在大量文本上进行预训练,GPT-2 在生成文本方面表现得非常出色,即使文本有时并不准确或真实。但是 GPT-2 缺乏 BERT 预训练的双向上下文,这使得它不适用于某些任务。XLNET 结合了 BERT 和 GPT-2 的预训练目标的优点,使用排列语言建模目标(PLM)使其能够双向学习。
在 GPT-2 之后,语言模型变得更大,现在被称为大型语言模型(LLMs)。如果在足够大的数据集上进行预训练,LLMs 可以展示少量甚至零-shot 学习。GPT-J 是一个具有 6B 参数并在 400B 标记上训练的 LLM。GPT-J 之后是 OPT,一系列仅解码器模型,其中最大的模型为 175B,并在 180B 标记上训练。BLOOM 也在同一时间发布,该系列中最大的模型有 176B 参数,并在 46 种语言和 13 种编程语言中训练了 366B 标记。
编码器-解码器
BART 保留了原始的 Transformer 架构,但通过文本填充损坏修改了预训练目标,其中一些文本段被替换为单个mask
标记。解码器预测未损坏的标记(未来标记被屏蔽),并使用编码器的隐藏状态来帮助它。Pegasus 类似于 BART,但 Pegasus 屏蔽整个句子而不是文本段。除了遮蔽语言建模,Pegasus 还通过间隙句子生成(GSG)进行预训练。GSG 目标屏蔽了对文档重要的整个句子,并用mask
标记替换它们。解码器必须从剩余的句子中生成输出。T5 是一个更独特的模型,将所有 NLP 任务都转化为使用特定前缀的文本到文本问题。例如,前缀Summarize:
表示一个总结任务。T5 通过监督(GLUE 和 SuperGLUE)训练和自监督训练(随机抽样并丢弃 15%的标记)进行预训练。
音频
编码器
Wav2Vec2 使用 Transformer 编码器直接从原始音频波形中学习语音表示。它通过对比任务进行预训练,以确定一组错误的语音表示中的真实语音表示。HuBERT 类似于 Wav2Vec2,但训练过程不同。目标标签是通过聚类步骤创建的,其中相似音频片段被分配到一个成为隐藏单元的簇中。隐藏单元被映射到一个嵌入以进行预测。
编码器-解码器
Speech2Text 是一个专为自动语音识别(ASR)和语音翻译设计的语音模型。该模型接受从音频波形中提取的对数梅尔滤波器特征,并预训练自回归地生成转录或翻译。Whisper 也是一个 ASR 模型,但与许多其他语音模型不同,它是在大量✨标记的✨音频转录数据上进行预训练,以实现零样本性能。数据集中还包含大量非英语语言,这意味着 Whisper 也可以用于资源稀缺的语言。在结构上,Whisper 类似于 Speech2Text。音频信号被转换为由编码器编码的对数梅尔频谱图。解码器从编码器的隐藏状态和先前的标记中自回归地生成转录。
多模态
编码器
VisualBERT 是一个用于视觉-语言任务的多模态模型,发布于 BERT 之后不久。它结合了 BERT 和一个预训练的目标检测系统,将图像特征提取为视觉嵌入,与文本嵌入一起传递给 BERT。VisualBERT 基于未屏蔽的文本和视觉嵌入预测被屏蔽的文本,并且还必须预测文本是否与图像对齐。当 ViT 发布时,ViLT 采用了 ViT 的架构,因为这样更容易获取图像嵌入。图像嵌入与文本嵌入一起进行处理。从那里,ViLT 通过图像文本匹配、屏蔽语言建模和整词屏蔽进行预训练。
CLIP 采用了不同的方法,对(图像
,文本
)进行一对预测。一个图像编码器(ViT)和一个文本编码器(Transformer)在一个包含 4 亿个(图像
,文本
)对的数据集上进行联合训练,以最大化(图像
,文本
)对的图像和文本嵌入之间的相似性。在预训练之后,您可以使用自然语言指示 CLIP 预测给定图像的文本,反之亦然。OWL-ViT 在 CLIP 的基础上构建,将其作为零样本目标检测的骨干。在预训练之后,添加了一个目标检测头,以对(类别
,边界框
)对进行集合预测。
编码器-解码器
光学字符识别(OCR)是一个长期存在的文本识别任务,通常涉及几个组件来理解图像并生成文本。TrOCR 使用端到端的变换器简化了这个过程。编码器是一种 ViT 风格的模型,用于图像理解,并将图像处理为固定大小的补丁。解码器接受编码器的隐藏状态,并自回归地生成文本。Donut 是一个更通用的视觉文档理解模型,不依赖于基于 OCR 的方法。它使用 Swin 变换器作为编码器,多语言 BART 作为解码器。Donut 经过预训练,通过根据图像和文本注释预测下一个单词来阅读文本。解码器根据提示生成一个令牌序列。提示由每个下游任务的特殊令牌表示。例如,文档解析有一个特殊的parsing
令牌,它与编码器的隐藏状态结合,将文档解析为结构化的输出格式(JSON)。
强化学习
解码器
决策和轨迹转换器将状态、动作和奖励视为序列建模问题。决策变换器生成一系列动作,这些动作基于回报、过去状态和动作,导致未来期望的回报。在最后K个时间步中,这三种模态都被转换为令牌嵌入,并由类似 GPT 的模型处理,以预测未来的动作令牌。轨迹变换器也对状态、动作和奖励进行标记化,并使用 GPT 架构处理它们。与专注于奖励条件的决策变换器不同,轨迹变换器使用波束搜索生成未来的动作。
分词器总结
原文链接:
huggingface.co/docs/transformers/v4.37.2/en/tokenizer_summary
在这个页面上,我们将更仔细地看一下分词。
www.youtube-nocookie.com/embed/VFp38yj8h3A
正如我们在预处理教程中看到的,将文本分词是将其分割成单词或子词,然后通过查找表将其转换为 id。将单词或子词转换为 id 是直接的,因此在本摘要中,我们将专注于将文本分割成单词或子词(即文本分词)。更具体地说,我们将看一下🤗 Transformers 中使用的三种主要分词器类型:Byte-Pair Encoding (BPE)、WordPiece 和 SentencePiece,并展示哪种模型使用了哪种分词器类型的示例。
请注意,在每个模型页面上,您可以查看相关分词器的文档,以了解预训练模型使用了哪种分词器类型。例如,如果我们查看 BertTokenizer,我们可以看到该模型使用了 WordPiece。
介绍
将文本分割成较小的块是一项看起来比较困难的任务,有多种方法可以实现。例如,让我们看一下句子"Don't you love 🤗 Transformers? We sure do."
www.youtube-nocookie.com/embed/nhJxYji1aho
将这段文本简单地按空格分割,会得到:
["Don't", "you", "love", "🤗", "Transformers?", "We", "sure", "do."]
这是一个明智的第一步,但是如果我们看一下标记"Transformers?"
和"do."
,我们会注意到标点符号附加在单词"Transformer"
和"do"
上,这是不够理想的。我们应该考虑标点符号,这样模型就不必学习一个单词的不同表示以及可能跟随它的每个可能的标点符号,这将导致模型需要学习的表示数量激增。考虑标点符号,对我们的示例文本进行分词会得到:
["Don", "'", "t", "you", "love", "🤗", "Transformers", "?", "We", "sure", "do", "."]
更好。然而,分词处理单词"Don't"
的方式是不利的。"Don't"
代表"do not"
,所以最好将其分词为["Do", "n't"]
。这就是事情开始变得复杂的地方,也是每个模型都有自己的分词器类型的原因之一。根据我们应用于文本分词的规则,相同文本会生成不同的分词输出。预训练模型只有在输入与训练数据分词时使用的规则相同的情况下才能正常运行。
spaCy和Moses是两种流行的基于规则的分词器。在我们的示例上应用它们,spaCy和Moses可能会输出类似以下内容:
["Do", "n't", "you", "love", "🤗", "Transformers", "?", "We", "sure", "do", "."]
可以看到,这里使用了空格和标点分词,以及基于规则的分词。空格和标点分词以及基于规则的分词都是单词分词的示例,它们被宽泛地定义为将句子分割成单词。虽然这是将文本分割成较小块的最直观的方法,但这种分词方法可能会导致大规模文本语料库出现问题。在这种情况下,空格和标点分词通常会生成一个非常庞大的词汇表(所有使用的唯一单词和标记的集合)。例如,Transformer XL 使用空格和标点分词,导致词汇量为 267,735!
如此庞大的词汇量迫使模型具有巨大的嵌入矩阵作为输入和输出层,这会导致内存和时间复杂度增加。一般来说,transformers 模型很少有词汇量超过 50,000 的情况,尤其是如果它们只在单一语言上进行了预训练。
因此,如果简单的空格和标点符号分词不尽如人意,为什么不简单地在字符上进行分词呢?
www.youtube-nocookie.com/embed/ssLq_EK2jLE
虽然字符分词非常简单且可以大大减少内存和时间复杂度,但这使得模型更难学习有意义的输入表示。例如,学习字母"t"
的有意义的上下文无关表示要比学习单词"today"
的上下文无关表示困难得多。因此,字符分词通常伴随着性能损失。因此,为了兼顾两者的优势,transformers 模型使用了介于单词级和字符级分词之间的混合称为子词分词的方法。
子词分词
www.youtube-nocookie.com/embed/zHvTiHr506c
子词分词算法依赖于这样一个原则,即经常使用的单词不应该被分割为更小的子词,但罕见的单词应该被分解为有意义的子词。例如,"annoyingly"
可能被认为是一个罕见单词,可以被分解为"annoying"
和"ly"
。"annoying"
和"ly"
作为独立的子词会更频繁地出现,同时"annoyingly"
的含义由"annoying"
和"ly"
的组合含义保留。这在像土耳其这样的聚合语言中特别有用,您可以通过串联子词形成(几乎)任意长的复杂单词。
子词分词使模型能够拥有合理的词汇量,同时能够学习有意义的上下文无关表示。此外,子词分词使模型能够处理它以前从未见过的单词,通过将它们分解为已知的子词。例如,BertTokenizer 将"I have a new GPU!"
分词如下:
>>> from transformers import BertTokenizer >>> tokenizer = BertTokenizer.from_pretrained("bert-base-uncased") >>> tokenizer.tokenize("I have a new GPU!") ["i", "have", "a", "new", "gp", "##u", "!"]
因为我们考虑的是不区分大小写的模型,所以首先将句子转换为小写。我们可以看到单词["i", "have", "a", "new"]
存在于分词器的词汇表中,但单词"gpu"
不在其中。因此,分词器将"gpu"
分割为已知的子词:["gp" 和 "##u"]
。"##"
表示剩余的标记应该附加到前一个标记上,没有空格(用于解码或反向分词)。
作为另一个例子,XLNetTokenizer 将我们之前的示例文本分词如下:
>>> from transformers import XLNetTokenizer >>> tokenizer = XLNetTokenizer.from_pretrained("xlnet-base-cased") >>> tokenizer.tokenize("Don't you love 🤗 Transformers? We sure do.") ["▁Don", "'", "t", "▁you", "▁love", "▁", "🤗", "▁", "Transform", "ers", "?", "▁We", "▁sure", "▁do", "."]
当我们查看 SentencePiece 时,我们将回到那些"▁"
的含义。正如大家所看到的,罕见单词"Transformers"
已被分割为更常见的子词"Transform"
和"ers"
。
现在让我们看看不同的子词分词算法是如何工作的。请注意,所有这些分词算法都依赖于某种形式的训练,通常是在相应模型将被训练的语料库上进行的。
Transformers 4.37 中文文档(十二)(3)https://developer.aliyun.com/article/1564914