69 BERT预训练_BERT代码_by《李沐:动手学深度学习v2》pytorch版

系列文章目录


文章目录

  • 系列文章目录
  • Bidirectional Encoder Representations fromTransformers(BERT)
    • 输入表示
    • 预训练任务
      • 掩蔽语言模型(Masked Language Modeling)
      • 下一句预测(Next Sentence Prediction)
    • 整合代码
    • 小结
    • 练习


Bidirectional Encoder Representations fromTransformers(BERT)

import torch
from torch import nn
from d2l import torch as d2l

输入表示

subsec_bert_input_rep

在自然语言处理中,有些任务(如情感分析)以单个文本作为输入,而有些任务(如自然语言推断)以一对文本序列作为输入。BERT输入序列明确地表示单个文本和文本对。当输入为单个文本时,BERT输入序列是特殊类别词元“”、文本序列的标记、以及特殊分隔词元“”的连结。当输入为文本对时,BERT输入序列是“”、第一个文本序列的标记、“”、第二个文本序列标记、以及“”的连结。我们将始终如一地将术语“BERT输入序列”与其他类型的“序列”区分开来。例如,一个BERT输入序列可以包括一个文本序列或两个文本序列

为了区分文本对,根据输入序列学到的片段嵌入 e A \mathbf{e}_A eA e B \mathbf{e}_B eB分别被添加到第一序列和第二序列的词元嵌入中。对于单文本输入,仅使用 e A \mathbf{e}_A eA

下面的get_tokens_and_segments将一个句子或两个句子作为输入,然后返回BERT输入序列的标记及其相应的片段索引,也就是个我一两个句子使其变成bert的输入。

#@save
def get_tokens_and_segments(tokens_a, tokens_b=None):
    """获取输入序列的词元及其片段索引"""
    tokens = [''] + tokens_a + ['']
    # 0和1分别标记片段A和B
    segments = [0] * (len(tokens_a) + 2)
    if tokens_b is not None:
        tokens += tokens_b + ['']
        segments += [1] * (len(tokens_b) + 1)
    return tokens, segments

BERT选择Transformer编码器作为其双向架构。在Transformer编码器中常见是,位置嵌入被加入到输入序列的每个位置。然而,与原始的Transformer编码器不同,BERT使用可学习的位置嵌入。总之,
:numref:fig_bert-input表明BERT输入序列的嵌入是词元嵌入、片段嵌入和位置嵌入的和。

69 BERT预训练_BERT代码_by《李沐:动手学深度学习v2》pytorch版_第1张图片
fig_bert-input

下面的BERTEncoder类类似于 :numref:sec_transformer中实现的TransformerEncoder类。与TransformerEncoder不同,BERTEncoder使用片段嵌入和可学习的位置嵌入。

#@save
class BERTEncoder(nn.Module):
    """BERT编码器"""
    def __init__(self, vocab_size, num_hiddens, norm_shape, ffn_num_input,
                 ffn_num_hiddens, num_heads, num_layers, dropout,
                 max_len=1000, key_size

你可能感兴趣的:(李沐动手学深度学习,深度学习,bert,pytorch)