Bert模型
一、定义只用做 Transformer 架构的编码器Encoder堆叠多层训练出一个懂文本语言的通用特征提取器二、BERT 机制1.双向注意力Bidirectional Attention①定义普通 RNN/LSTM 只能从左到右看一句BERT 可以同时看一句话的左右两边双向 每个位置可以关注左边所有词 右边所有词。一句话内也就是上下文 full context无任何未来遮挡。例如句子“我喜欢吃苹果因为它很甜。”BERT 看 “苹果” 时左边喜欢吃右边很甜同时理解真正双向注意力②标准自注意力公式也即双向注意力公式Q查询当前词K键所有词V值所有词无 mask2.多头注意力Multi-HeadBERT 注意力是多头并行。每一头都是完整双向注意力每头学习不同语义关系主谓、指代、上下文关联…最后拼接输出三、BERT 预训练任务任务模型的任务 看【最后一层输出 损失函数】怎么定义同一个模型结构只要改最后输出层和损失任务完全变掉。1.Bert模型Bert 模型主体完全不动只改最后一层① 输出每个 token 预测原词 交叉熵损失→MLM 任务掩码语言模型② 输出CLS 向量二分类IsNext/NotNext 交叉熵→NSP 任务下一句预测③ 输出CLS 向量二分类积极 / 消极→情感分析任务④ 输出每个 token 分类B/I/O→NER 命名实体识别⑤ 输出每个 token 做分类起止位置→阅读理解问答任务2. 再看 GPTGPT 结构Decoder本身也不是生成模型只是因为它最后输出 “下一个词概率” 自回归损失才变成生成模型。1. MLMMasked Language Model掩码语言模型随机遮住 15% 的词让模型去猜。例子“我喜欢吃 [MASK]因为它很甜。”模型要猜是苹果香蕉还是橘子目的让模型学会双向上下文推理。2. NSPNext Sentence Prediction下句预测给模型两句话判断是不是同一段文章的连续两句输出是 / 不是二分类。目的让模型学会段落级别的逻辑关系。四、BERT 的输入Token Embedding词向量Segment Embedding句子编号向量A 或 BPositional Encoding位置向量BERT 的输入向量是由三种 Embedding 直接相加得到的[CLS] 和 [SEP] 作用[CLS]分类专用 token.最后一层 [CLS] 代表整个句子的语义向量[SEP]句子分隔符 注意力边界句间隔离不让两句词互相看见五、Bert预训练流程以下列图片为例1.分词将 “商将务大床房”拆成单个汉字商 务 大 床 房。这是 BERT 的中文分词方式按单个字 / 词切分也可以是词粒度但中文 BERT 通常用字粒度。注意实际 BERT 分词器还会加上特殊符号商 务 大 床 房→商 务 大 床 房最终序列是[CLS] 商 务 大 床 房 [SEP]2.生成标准输入向量1.input_ids词表索引(101, 2112, 555, 2315, 13145, 32141, 102)每个数字代表该 token 在词表中的索引101是[CLS]的 ID102是[SEP]的 ID后续模型会通过这些 ID在嵌入层查表得到词向量2.mask注意力掩码(1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,......)1代表真实 token模型需要处理0代表 padding填充的无效 token模型会忽略作用让所有输入序列长度一致不影响注意力计算3.seq_idssegment_ids句子标记(0,0,0,0,0,0,0,0 ........................)标记每个 token 属于哪个句子0代表第一句1代表第二句这张图是单句输入所以全是0如果是句子对任务如问答第一句标0第二句标13.Embedding 嵌入根据标准输入向量得到3种EmbeddingToken Embedding词嵌入———— input_idsSegment Embedding句子嵌入———— seq_idsPosition Embedding位置嵌入————pos_idsBERT 把这三种向量直接相加得到每个 token 的最终输入向量嵌入的实际操作input_idsseq_idspos_ids 各自通过一次全连接输出维度为768的向量4.多头自注意力Multi-Head Attention1.输入向量 Embeedding 经过3个分别的全连接线性变换得到Query(Q)、Key(K)、Value(V)2.计算多头注意力把 Q/K/V 分成多个头每个头独立计算注意力再拼接起来3.输出的向量维度和输入保持一致还是7685.Add Norm残差连接与层归一化第1次1.Add残差连接把「多头注意力的输出」和「原始输入向量」直接相加2.Norm层归一化对相加后的结果做层归一化稳定分布结果输出的向量维度和输入保持一致还是768作为下一层前馈网络的输入6.前馈神经网络Feed Forward这是一个两层的全连接网络 LinearBERT 里的标准结构是第一层Linear(768 → 3072)然后加激活函数GELU第二层Linear(3072 → 768)恢复维度作用对每个位置的向量做非线性变换提取更复杂的语义特征7.Add Norm残差连接与层归一化第2次Add把「前馈网络的输出」和「前馈网络的输入」直接相加Norm对相加后的结果做层归一化稳定分布输出的向量维度和输入保持一致还是768传给 BERT 的下一层或者传给Pooler output层8.Pooler output1.取最后一层[CLS]token 的 hidden state也就是从 BERT 输出的最终向量里只拿出每句话的第 0 个位置 [CLS]。即每句话开头的[CLS] 768维向量【以BERT-base 的 768 为例】为什么要拿[CLS] 768 维向量因为[CLS] 经过了全部 12 层双向注意力它融合了整句话所有词的信息所以可以当作句子的总代表向量2.拿到 [CLS] 768 维向量后通过一个全连接层Linear Tanh 激活公式pooler_outputtanh(W⋅CLS_hiddenb)输入维度hidden_sizeBERT-base 是 768输出维度和输入一样也是 768作用把[CLS]的向量映射成一个 “句子级的向量表示”9.输出给解码器