title: Bert
BERT模型
BERT (Bidirectional Encoder Representations from Transformers) 是一种突破性的预训练语言模型,通过双向上下文表示和掩码语言建模任务,显著提升了各种自然语言理解任务的性能。
BERT的诞生背景
BERT由Google AI研究团队于2018年提出,发表在论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》中,主要解决了以往语言模型只能单向处理上下文的限制。
发布后,BERT迅速在11项NLP任务上取得了当时的最佳结果,掀起了预训练语言模型的研究热潮。
核心创新
BERT的双向上下文表示能力是其最大的创新,这使得模型可以同时考虑单词左右两侧的上下文信息,大幅增强了语言理解能力。
BERT的主要创新点包括:
- 双向Transformer编码器:同时利用左右上下文信息
- 掩码语言模型(MLM):随机遮蔽15%的词元并预测它们
- 下一句预测(NSP):预测两个句子是否连续出现
- 预训练-微调范式:通用预训练+任务特定微调
以下是BERT预训练任务的简化实现:
import torch
import torch.nn as nn
import random
def create_masked_input(tokens, vocab, mask_token_id, mask_prob=0.15):
masked_tokens = tokens.clone()
labels = torch.ones_like(tokens) * -100 # -100作为忽略的标签
for i in range(len(tokens)):
prob = random.random()
if prob < mask_prob:
labels[i] = tokens[i].clone()
prob /= mask_prob
if prob < 0.8: # 80%概率替换为[MASK]
masked_tokens[i] = mask_token_id
elif prob < 0.9: # 10%概率替换为随机词
masked_tokens[i] = random.randint(0, len(vocab)-1)
# 10%概率保持不变
return masked_tokens, labels
模型架构
BERT基于Transformer的编码器部分构建,有两个主要版本:
版本 | 层数 | 隐藏层维度 | 注意力头数 | 参数量 |
---|---|---|---|---|
BERT-Base | 12 | 768 | 12 | 1.1亿 |
BERT-Large | 24 | 1024 | 16 | 3.4亿 |
输入表示
BERT的输入由三种嵌入共同组成:
- 词元嵌入(Token Embeddings):WordPiece分词后的词元表示
- 段嵌入(Segment Embeddings):区分不同段落/句子
- 位置嵌入(Position Embeddings):提供词元位置信息
这三种嵌入相加后作为模型输入:
预训练过程
BERT的预训练包括两个任务:
掩码语言模型(MLM)
- 随机遮蔽输入中15%的词元
- 80%替换为[MASK]标记
- 10%替换为随机词元
- 10%保持不变
- 训练模型预测被遮蔽的原始词元
下一句预测(NSP)
- 50%选择文档中连续的两个句子
- 50%选择来自不同文档的两个句子
- 训练模型预测第二个句子是否是第一个句子的真实后续
"预训练是通往通用人工智能的重要步骤,BERT的成功表明了无监督学习的强大潜力。" —— Jacob Devlin (BERT第一作者)
微调应用
BERT的通用表示可以通过微调适应多种下游任务:
- 序列分类:添加分类层处理[CLS]标记的表示
- 序列标注:为每个词元的表示添加标注层
- 问答:预测答案的起始和结束位置
- 句对任务:同时输入两个句子进行关系判断
from transformers import BertForSequenceClassification
import torch.nn as nn
class BertClassifier(nn.Module):
def __init__(self, num_classes=2):
super(BertClassifier, self).__init__()
self.bert = BertForSequenceClassification.from_pretrained(
'bert-base-uncased',
num_labels=num_classes
)
def forward(self, input_ids, attention_mask, token_type_ids):
return self.bert(
input_ids=input_ids,
attention_mask=attention_mask,
token_type_ids=token_type_ids
)
BERT的影响
BERT的出现带来了深远影响:
- 研究方向转变:推动了预训练-微调范式的普及
- 技术进步:引发了一系列改进版本的研发
- 应用拓展:促进了NLP技术在各行业的应用
- 商业价值:为企业级NLP解决方案提供了核心技术
BERT家族
BERT的成功催生了大量改进版本和变种:
RoBERTa
- 移除NSP任务
- 使用更大批量和更多数据
- 动态掩码策略
- 取得了比BERT更好的效果
ALBERT
- 参数共享减少模型大小
- 嵌入层因式分解
- 句子顺序预测代替NSP
- 在同等性能下大幅减少参数量
DistilBERT
- 知识蒸馏压缩模型
- 保留BERT 97%的性能
- 参数量减少40%
- 推理速度提升60%
ELECTRA
- 使用替换检测预训练
- 训练效率大幅提升
- 在同等计算资源下性能更好
尽管后来出现了更多强大的模型,BERT作为NLP发展的里程碑,其设计思想和技术创新仍然深刻影响着现代语言模型的发展方向。
局限性
BERT也存在一些局限性:
- 生成能力弱:不适合文本生成任务
- 上下文长度限制:最大处理512个词元
- 预训练-微调差距:预训练任务与某些下游任务差异较大
- 计算资源需求高:训练和部署成本较高
小结
BERT代表了NLP领域的重要变革,通过双向Transformer和创新的预训练任务,为文本表示提供了更强大的基础。它不仅在技术上取得了突破,还改变了整个行业的研究和应用方向。虽然现在已有更先进的模型,但BERT的原理和方法仍然是现代NLP系统的重要组成部分,其学术和工业影响力不可低估。