🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】 深度学习【DL】
🖍foreword
✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。
如果你对这个系列感兴趣的话,可以关注订阅哟👋
文章目录
本章深入探讨用于句子嵌入的 BERT 算法以及各种训练策略,包括 MLM 和 NSP。我们还将看到使用 BERT 的文本分类系统的实现。
BERT 使用转换器来学习文本中单词之间的上下文关系。Transformer 有两种机制——编码器和解码器——但 BERT 只需要编码器机制。BERT 使用双向方法并按顺序读取文本输入,这使模型可以根据单词周围的单词来学习单词的上下文。编码器的输入是嵌入到向量中的一系列标记。然后将向量传递到神经网络,然后生成对应于输入的向量输出序列。单词的输出向量取决于它出现的上下文。例如,“他喜欢打板球”这句话中“喜欢”这个词的向量与“他的脸像西红柿一样红了”这句话中同一个词的向量是不同的。
此过程甚至在开始模型构建阶段之前就涉及文本处理步骤。下一节将讨论 BERT 中使用的文本处理步骤。
Position embeddings :位置嵌入用于学习嵌入中的顺序信息。由于在变形金刚中丢失了与顺序相关的信息,因此使用位置嵌入来恢复它。对于输入序列中的每个位置,BERT 学习一个独特的位置嵌入。在这些位置嵌入的帮助下,BERT 能够在捕获此序列或顺序信息时表达单词在句子中的位置。
Segment embeddings: BERT 还学习了第一句和第二句的独特嵌入,以帮助模型区分它们。它还可以将句子对作为问答等任务的输入。
Token embeddings :对于 WordPiece 令牌词汇表中的每个令牌,学习令牌嵌入。WordPiece 标记词汇表包含语料库中单词的子词。例如,对于单词“Question”,这个词汇集将包括“Question”的所有可能的子词,例如 [“Questio”、“Questi”…],等等。
给定标记的输入表示是通过对标记、段和位置嵌入求和来构建的。这使它成为一个全面的嵌入方案,其中包含许多对模型有用的信息。
对于任务是预测句子中下一个单词的 NLP 任务,如果我们采用定向方法,它会有一些局限性。然而,BERT 提供了两种学习上下文信息的策略:MLM 和 NSP。在 BERT 训练期间,这两项任务将一起训练。当使用这两种策略时,模型试图达到最小化组合损失函数的目标。
BERT是一种深度双向模型,比从左到右的模型或从左到右和从右到左的模型的浅层级联更强大。BERT 网络可以有效地从令牌的左右上下文中捕获信息。这从第一层本身一直到最后一层。以前,语言模型是在从左到右的上下文中训练的,这使得它们更不容易受到信息的影响。尽管 ELMo 模型使用两个 LSTM 语言模型的浅层级联大大改进了现有技术,但这还不够。BERT 已被证明比 MLM 发挥关键作用的现有技术更重要。
在掩码语言任务中,文本中的某些单词被随机掩码。[MASK] 标记周围的上下文词用于预测 [MASK] 词。当将单词序列输入 BERT 时,每个序列中 15% 的单词将替换为 [MASK] 标记。这 15% 的单词是随机选择的。其中,80% 被屏蔽,10% 被随机词替换,10% 被保留。这样做是因为如果使用了 100% 的屏蔽词,那么模型不一定会为非屏蔽词生成良好的标记表示。模型性能得到改善,因为过多地关注特定位置或令牌已被阻止。基于序列中非掩码词提供的上下文,模型尝试预测掩码词的原始值。
在编码器输出之上添加分类层。
将输出向量乘以嵌入矩阵,从而将它们转换为词汇维度。
用softmax计算词汇表中每个词的概率。
BERT中的损失函数只考虑masked值的预测;忽略未屏蔽词的预测。这使得模型比定向模型收敛得更慢。例如,对于句子“The birds are flying in the clear blue sky”,如果我们正在训练双向模型而不是预测序列中的下一个词,则可以构建一个模型来预测序列中缺失的词本身。现在,考虑一个标记“飞行”并掩盖它,这样它就可以被认为是丢失了。现在需要对模型进行训练,使其能够预测句子“The birds are [MASK] in the clear blue sky”中这个缺失或屏蔽标记的值。这就是 MLM 的本质,它使模型能够理解句子中单词之间的关系 。
国家安全政策 任务类似于句子中的下一个单词预测。NSP 预测文档中的下一个句子,而后者用于预测句子中缺失的单词。BERT 也接受了 NSP 任务的训练。这是必需的,以便我们的模型能够理解文本语料库中的不同句子是如何相互关联的。在 BERT 模型的训练过程中,将句子对作为输入。然后它预测这对中的第二个句子是否是原始文档中的后续句子。为实现这一点,采用 50% 的输入,使得第二句是原始文档中的后续句子,而另外 50% 包含第二句从文档中随机选择的对。假设随机的第二个句子与第一个句子断开连接。
Instance 1
Sentence A – I saw a bird flying in the sky.
Sentence B – It was a blue sparrow.
Label – IsNextSentence
Instance 2
Sentence A – I saw a bird flying in the sky.
Sentence B – The dog is barking.
Label – NotNextSentence
正如我们所看到的,对于实例 1,句子 B 在逻辑上是在句子 A 之后,但对于实例 2 则不同,这分别从标签IsNextSentence和NotNextSentence中可以清楚地看出。
众所周知, BERT 用于各种 NLP 任务,例如文档摘要、问答系统、文档或句子分类等。现在,让我们看看 BERT 如何用于句子分类。
图 4-2 使用 BERT 进行分类的示例
类似类型的任务,例如文档分类、情感分析等,也可以使用 BERT 来实现。
Python
图 4-3 Python控制台
这将在命令提示符下启动 Python 控制台。如果您的系统上未安装 Python,请使用此链接根据您的操作系统下载并安装 Python:https ://www.python.org/downloads/
pip install notebook
pip install tensorflow
我们现在已经安装了本练习的所有先决条件。请按照下面列出的步骤使用 BERT 配置用于文本分类的预训练模型。
git clone https://github.com/google-research/bert.git
2.下载的模型文件包含权重和其他必要的 BERT 文件。根据您的要求,需要从此列表中选择 BERT 预训练模型。
BERT Base, Uncased
BERT Large, Uncased
BERT Base, Cased
BERT Large, Cased
- 1 1 a text example belonging to class 1
-
- 2 1 a text example belonging to class 1
-
- 3 2 a text example belonging to class 2
-
- 4 0 a text example belonging to class 0
- id sentence
-
- 1. first test example
-
- 2. second test example
-
- 3. third test example
- python bert/run_classifier.py \
- --task_name=cola \
- --do_train=true \
- --do_eval=true \
- --data_dir=./data \
- --vocab_file=$BERT_BASE_DIR/vocab.txt \
- --bert_config_file=$BERT_BASE_DIR/bert_config.json \
- --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
- --max_seq_length=128 \
- --train_batch_size=32 \
- --learning_rate=2e-5 \
- --num_train_epochs=3.0 \
- --output_dir=./bert_output/
如果训练数据文本的长度超过 128 个单词,则max_seq_length的值可以增加到 512。如果您在 CPU 系统上训练模型,则可以减少训练大小以避免内存不足错误.
训练完成后,报告将存储在bert_output目录中。
- python bert/run_classifier.py \
- --task_name=cola \
- --do_train=true \
- --do_eval=true \
- --data_dir=./data \
- --vocab_file=$BERT_BASE_DIR/vocab.txt \
- --bert_config_file=$BERT_BASE_DIR/bert_config.json \
- --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
- --max_seq_length=128 \
- --train_batch_size=32 \
- --learning_rate=2e-5 \
- --num_train_epochs=3.0 \
- --output_dir=./bert_output/
请注意,max_seq_length参数的值应与训练过程中使用的值相同。
对于此,我们将演示问题分类数据集的实现,其中问题将被分类到各自的类别中。主要有两种类型的问题,事实性(非描述性)和非事实性问题。例如,“德里的温度是多少?” 是一个事实型问题,因为它正在寻找基于某些事实的答案。“什么是温度?” 是一个非事实型问题,因为它正在寻找有关温度的文本片段。对于此实现,请参阅Learning Question Classifiers上的数据集。
第一列:数据点索引。
第二列:分类标签(即,事实或非事实)。在这个数据集中,factoid 由 0 和 1 代表非 factoid。
第三列:值为 a 的一次性列。
第四列:实际问题文本。
python run_classifier.py --task_name=cola --do_train=true --do_eval=true --data_dir=$BERT_BASE_DIR/data --vocab_file=$BERT_BASE_DIR/bert_output/cased_L-12_H-768_A-12/vocab.txt --bert_config_file=$BERT_BASE_DIR/bert_output/ cased_L-12_H-768_A-12/bert_config.json --init_checkpoint=$BERT_BASE_DIR/bert_output/ model.ckpt-2023 --max_seq_length=128 --train_batch_size=32 --learning_rate=2e-5 --num_train_epochs=3.0 --output_dir=$BERT_BASE_DIR/bert_output/
$BERT_BASE_DIR是您必须从 GitHub 下载代码的目录。
图 4-9 训练 BERT 模型的命令
python bert/run_classifier.py --task_name=cola --do_predict=true --data_dir=$BERT_BASE_DIR/data vocab_file=$BERT_BASE_DIR/bert_output/cased_L-12_H-768_A-12/vocab.txt --bert_config_file=$BERT_BASE_DIR/bert_output/ cased_L-12_H-768_A-12/bert_config.json --init_checkpoint=$TRAINED_CLASSIFIER --max_seq_length=128 --output_dir=$BERT_BASE_DIR/bert_output/
$BERT_BASE_DIR是您必须从 GitHub 下载代码的目录。

图 4-11 预测结果快照
第一列对应于标签 0(事实型),第二列对应于标签 1(非事实型)。从这个生成的.csv文件中,我们可以看到测试数据中的问题是事实性问题还是非事实性问题。
这种问题类型分类系统在会话系统中非常有用,在该系统中,最终用户输入的查询或问题需要分类以检索相关结果。
BERT 嵌入模型的性能和准确性已经针对各种 NLP 任务在不同类型的数据集上进行了持续评估。这样做是为了检查 BERT 是否能够通过其他一些方法达到已经为这些数据集设置的基准值。这些基准是评估模型特定方面工作的数据集。存在许多这样的基准,接下来将讨论其中的一些。
模型需要更改其输入和输出的表示以适应任务。例如,在 BERT 的预训练期间,当输入句子时,很少有单词被屏蔽。由于 BERT 中的输入表示层容纳了所有的 GLUE 任务,因此无需更改该层。但是,必须删除预训练分类层。该层被替换为容纳每个 GLUE 任务输出的层。BERT 模型在 GLUE 基准测试中取得了最先进的结果,得分为 80.5%。
SQuAD 1.1
SQuAD 2.0
除了 SQuAD 1.1 之外,SQuAD2.0 还有 100,000 个问题,其中包含 50,000 个未回答的问题,但与可回答的问题相似。这样做是为了让 SQuAD2.0 在问题段落不支持问题答案的情况下也能表现出色。
BERT 能够通过微小的修改在 SQuAD 数据集上获得最先进的结果。它需要对数据进行半复杂的预处理和后处理,以处理 SQuAD 上下文段落的可变长度特性和用于 SQuAD 训练的字符级答案注释。BERT 模型能够在 SQuAD 1.0 和 SQuAD v2.0 测试数据集上分别获得 93.2 和 83.1 的 F1 分数。
IMDB 数据集是一个广泛的 电影评论数据集,已用于对观众对电影的情绪进行分类。该数据集包含 25,000 条用于训练的极地电影评论和 25,000 条用于测试的评论。除了训练和测试数据之外,还有额外的未标记数据。该数据集还用于在情感分类任务中评估 BERT。
RACE是一个来自考试的大规模阅读理解数据集。RACE 数据集用于评估阅读理解任务的模型。该数据集是从中国学生的英语考试中收集的。它由人类专家生成的近 28,000 篇文章和 100,000 个问题组成。与其他基准数据集相比,RACE 中的问题数量要多得多。BERT 大型模型在 RACE 基准数据集上取得了 73.8% 的分数。
ALBERT
RoBERTa
DistilBERT
StructBERT
BERTjoint for Natural Questions
ALBERT 是 BERT 的更小版本,由 Google Research 和 Toyota Technological Institute 联合推出。它是一种更智能、“精简”的 BERT,也被认为是 BERT 的天然继承者。它还可以用于实现最先进的 NLP 任务。与 BERT 相比,这一切都可以用更少的计算能力实现,但你需要在准确性上做出一点妥协。ALBERT 的创建基本上是为了改进架构和训练方法,以便以更少的计算资源提供更好的结果。
当 H 和 E 结合在一起时,我们最终得到一个包含数十亿参数的模型,这些参数在训练中很少更新。这是因为嵌入矩阵 V*E,其中 V 是大词汇表,必须随 H(隐藏层)缩放。这实际上会导致参数效率低下,因为这两项用于不同的目的。
在 ALBERT 中,为了提高效率,我们解开两个参数并将嵌入参数拆分为两个较小的矩阵。现在 one-hot 向量不直接投影到 H 中;相反,它们被投射到一个更小、维度更低的矩阵 E 中,然后 E 被投射到隐藏层中。因此,参数从 O (V*H) 减少到 Θ(V*E+E*H)。
BERT中使用的NSP loss在后续研究中并没有被发现是一种非常有效的训练机制。因此,由于 NSP 不可靠,它被用来开发 SOP。
在 ALBERT SOP 中,损失用于对句间连贯性建模。SOP 的创建主要是为了关注句间连贯性损失而不是主题预测,而 BERT 将主题预测与连贯性预测相结合。因此,ALBERT 能够通过避免主题预测问题来学习更细粒度的句间衔接。
| Model | Parameters | SQuAD1.1 | SQuAD2.0 | MNLI | SST-2 | RACE | Avg | Speedup |
|---|---|---|---|---|---|---|---|---|
| BERT base | 108M | 90.5/83.3 | 80.3/77.3 | 84.1 | 91.7 | 68.3 | 82.1 | 17.7倍 |
| BERT large | 334M | 92.4/85.8 | 83.9/80.8 | 85.8 | 92.2 | 73.8 | 85.1 | 3.8倍 |
| BERT xlarge | 1270M | 86.3/77.9 | 73.8/70.5 | 80.5 | 87.8 | 39.7 | 76.7 | 1.0 |
| ALBERT base | 12M | 89.3/82.1 | 79.1/76.1 | 81.9 | 89.4 | 63.5 | 80.1 | 21.1倍 |
| ALBERT large | 18M | 90.9/84.1 | 82.1/79.0 | 83.8 | 90.6 | 68.4 | 82.4 | 6.5倍 |
| ALBERT xlarge | 59M | 93.0/86.5 | 85.9/83.1 | 85.4 | 91.9 | 73.9 | 85.5 | 2.4倍 |
| ALBERT xxlarge | 233M | 94.1/88.3 | 88.1/85.1 | 88.0 | 95.2 | 82.3 | 88.7 | 1.2倍 |
RoBERTa 是一种用于预训练 NLP 系统的优化方法。RoBERTa(Robustly optimized BERT)由 Facebook AI 团队开发,基于 Google 的 BERT 模型。RoBERTa 通过额外的预训练改进重新实现了 BERT 的神经网络架构,在多个基准测试中取得了最先进的结果。
Reserved token : BERT 使用 [CLS] 和 [SEP] 分别作为起始标记和分隔符,而 RoBERTa 使用 和 来转换句子。
子词大小 : BERT 有大约 30,000 个子词,而 RoBERTa 有大约 50,000 个子词。
更多训练数据:在 BERT 的重新实现过程中,对 BERT 模型的超参数进行了一些更改,并且使用更高数量级的数据进行了更多迭代的训练。RoBERTa 使用更多的训练数据。它使用 BookCorpus (16G)、CC-NEWS (76G)、OpenWebText (38G) 和 Stories (31G) 数据,而 BERT 仅使用 BookCorpus 作为训练数据。
动态掩码 :在移植 BERT 以创建 RoBERTa 时,创建者修改了单词掩码策略。BERT 主要使用静态掩码,即在预处理过程中将单词从句子中屏蔽掉。RoBERTa 使用动态掩蔽。在这里,每当将一个句子输入训练时,就会生成一个新的掩码模式。RoBERTa 将训练数据复制 10 次并以不同方式屏蔽这些数据。实验观察到动态掩蔽提高了性能并给出了比静态掩蔽更好的结果。
不同的训练目标: BERT 通过在 NSP 上训练来捕捉句子之间的关系。一些没有应用 NSP 的训练方法提供了更好的结果,证明了 NSP 的无效性。进行了实验以比较使用带有 NSP 的段对、带有 NSP 的句子对、没有 NSP 的完整句子和没有 NSP 的文档句子训练的模型。没有使用 NSP 训练的模型在 SQuAD1.1/2.0、MNLI-m、SST-2 和 RACE 上表现更好。
在更长的序列上进行训练:当模型在更长的序列上进行训练时,可以获得更好的结果。BERT base 通过 100 万步以 256 个序列的批次大小进行训练,但对 2,000 个序列和 31,000 步的训练显示性能有所提高。
随着设计变更的实施,RoBERTa 模型在 MNLI、QNLI、RTE 和 RACE 任务上提供了最先进的性能。它还在 GLUE 基准测试中实现了可观的性能提升,得分为 88.5。
RoBERTa 证明,调整 BERT 训练过程可以提高各种 NLP 任务的性能。这凸显了在 BERT 训练中探索设计选择以获得更好的性能输出 的重要性。
DistilBERT被引入用于知识蒸馏。需要这种知识蒸馏来解决计算大量参数的缺点。最近开发的 NLP 模型参数数量增加,现在参数数量高达数百亿。尽管更高的参数数量可确保最佳性能,但它会在计算资源有限时阻止模型训练和服务。
知识蒸馏围绕这样一个想法,即较大的模型充当较小模型的老师,较小模型试图复制其输出和子层激活对于给定的一组输入。这有时也称为师生学习. 这是一种压缩技术,其中较大模型的行为由较小模型再现。教师的输出分布可用于所有可能的目标,这有助于培养具有泛化能力的学生。例如,在“The sky is [mask]”这句话中,老师可能会为“多云”和“晴朗”等词指定高概率。也有可能将高概率分配给“蓝色”一词。这对学生模型很有帮助,因此它能够概括而不是只学习正确的目标。此信息是通过用于训练学生的损失函数捕获的。该损失函数包含三个因素的线性组合。
Distillation Loss
蒸馏损失 考虑了 teacher(t) 和 student (s) 的输出概率的组合,如下式所示。
L ce = ∑ i t i log(s i )
Distillation Loss
t i = exp(z i /T)/ ∑ j exp(z j /T)
Temperature Softmax
teacher 概率是通过 temperature softmax 计算的。这基本上是对 softmax 的修改,以便从教师模型输出分布中获得更多粒度。这给出了更平滑的输出分布,因为较大概率的大小减小而较小概率增加。这有助于最大限度地减少蒸馏损失。
Cosine Embedding Loss
余弦嵌入损失 是教师和学生的隐藏表示之间的距离度量。这有助于创建更好的模型,因为它使学生不仅可以在输出层而且可以在其他层模仿老师。
Masked Language Modeling Loss
这与训练 BERT 模型时使用的损失相同,以预测序列中屏蔽标记的正确标记值。
Architectural Modifications
DistilBERT 网络架构也是一个类似于 BERT base 的 transformer encoder 模型,但是它的层数减少了一半。但是,隐藏的表示保持不变。这会影响参数数量,在 DistilBERT 中有 6600 万个参数,而在教师模型中有 1.1 亿个参数。通过层数减少模型大小有助于实现计算复杂性的大幅降低。向量大小或隐藏状态表示的减少也减少了模型大小。
经过知识蒸馏后,DistilBERT 能够在 GLUE 基准测试中达到 BERT base 分数的 97%。这种知识提炼有助于将较大的模型或模型集合压缩到较小的学生网络中。事实证明,这在计算环境受限的情况下很有用。
StructBERT是一种基于 BERT 的模型,将语言结构融入到 BERT 预训练中。这两种线性化策略有助于将语言结构纳入 BERT。词级排序和句子级排序是 StructBERT 中利用的两个结构信息集。由于结合了这种结构预训练,StructBERT 实现了更好的泛化性和适应性。单词和句子之间的依赖关系被编码在 StructBERT 中。
StructBERT 中的结构预训练
与所有其他基于 BERT 的模型类似,StructBERT 也建立在 BERT 架构之上。原始的 BERT 执行两个无监督的预训练任务,MLM 和 NSP。StructBERT 能够增加 MLM 任务的能力。它在屏蔽单词后打乱一定数量的标记并预测正确的顺序。StructBERT 还能够更好地理解句子之间的关系。这是通过随机交换句子顺序来实现的。这种新的基于 BERT 的模型捕获每个句子中的细粒度单词结构。
在对 StructBERT 进行预训练之后,它可以针对特定任务的数据进行微调,以用于广泛的下游任务,例如文档摘要。
预训练目标
这两个辅助目标与原始 MLM 目标一起进行预训练,以利用固有的语言结构。
BERT联合 是一种基于 BERT 的自然问题模型。BERT联合模型仅在单个模型中预测短答案和长答案,而不是流水线方法。在这个模型中,每个文档在重叠标记窗口的帮助下被分成多个训练实例。这种方法用于创建平衡的训练集,随后是没有答案的下采样实例(空实例)。[CLS] 标记在训练期间用于预测空实例,推理时的跨度根据跨度分数和 [CLS] 分数之间的差异进行排名。
该模型使用 Natural Questions (NQ) 数据集,该数据集是一个包含 307,373 个训练示例、7,830 个开发示例和 7,842 个测试示例的问答数据集。对于每个示例,用户通过 Google 搜索引擎和包含答案的相应维基百科页面输入查询。维基百科页面被注释为问题的答案。
BERT联合模型是从在 SQuAD 1.1 数据集上训练的原始 BERT 模型初始化的。之后,该模型在 Natural Questions 训练实例上进行了微调。它使用 Adam 优化器来最小化损失。自然问题的 BERT联合模型提供了比基线 NQ 系统更好的结果。BERT 的这种变体提供了一种设计问答系统的新方法。
本章深入探讨了 BERT 及其两种算法,MLM 和 NSP。我们还讨论了使用 BERT 开发的示例文本分类模型。我们还检查了 BERT 在不同基准数据集上的行为,以及 BERT 的多种变体。在下一章中,我们将讨论使用 BERT 设计问答系统。