首页
/ 深入理解BERT:双向Transformer编码器在自然语言处理中的应用

深入理解BERT:双向Transformer编码器在自然语言处理中的应用

2025-06-04 05:37:48作者:宣聪麟

引言

BERT(Bidirectional Encoder Representations from Transformers)是自然语言处理领域具有里程碑意义的模型。本文将深入探讨BERT的核心概念、架构设计及其预训练任务,帮助读者全面理解这一革命性模型的工作原理。

从上下文无关到上下文相关的演进

传统词嵌入的局限性

早期的词嵌入模型如Word2Vec和GloVe采用上下文无关的表示方式,即无论单词出现在什么上下文中,其向量表示都是固定的。这种表示方式存在明显缺陷,无法处理自然语言中的多义性问题。

例如,"bank"一词在以下两个句子中含义完全不同:

  1. "I deposited money at the bank"
  2. "I sat by the river bank"

上下文敏感模型的发展

为解决这一问题,研究者开发了多种上下文敏感的词表示方法,包括:

  1. ELMo:使用双向LSTM,结合所有中间层表示
  2. CoVE:基于上下文向量
  3. TagLM:语言模型增强的序列标注器

这些模型虽然改进了词表示,但仍依赖于特定任务的架构设计。

BERT的创新设计

统一架构的优势

BERT的创新之处在于:

  1. 双向上下文编码:使用Transformer编码器同时考虑左右两侧的上下文
  2. 任务无关性:通过微调即可适应多种NLP任务,无需特定架构
  3. 高效预训练:设计了两个新颖的预训练任务

模型架构详解

BERT的核心是Transformer编码器堆栈,其输入表示由三部分组成:

  1. 词嵌入:将每个token映射为向量
  2. 段嵌入:区分句子对中的不同句子
  3. 位置嵌入:捕捉序列中的位置信息
# BERT输入表示示例
def get_tokens_and_segments(tokens_a, tokens_b=None):
    tokens = ['<cls>'] + tokens_a + ['<sep>']
    segments = [0] * (len(tokens_a) + 2)
    if tokens_b:
        tokens += tokens_b + ['<sep>']
        segments += [1] * (len(tokens_b) + 1)
    return tokens, segments

BERT的预训练任务

掩码语言模型(MLM)

MLM任务随机掩盖15%的输入token,要求模型预测被掩盖的词。具体掩盖策略为:

  1. 80%概率替换为[MASK]
  2. 10%概率替换为随机词
  3. 10%概率保持不变

这种策略避免了预训练与微调阶段的不一致性。

# MLM实现示例
class MaskLM(nn.Module):
    def __init__(self, vocab_size, num_hiddens):
        super().__init__()
        self.mlp = nn.Sequential(
            nn.Linear(num_hiddens, num_hiddens),
            nn.ReLU(),
            nn.LayerNorm(num_hiddens),
            nn.Linear(num_hiddens, vocab_size))
    
    def forward(self, X, pred_positions):
        # 获取被掩盖位置的表示
        batch_size = X.shape[0]
        batch_idx = torch.arange(batch_size)
        masked_X = X[batch_idx, pred_positions]
        return self.mlp(masked_X)

下一句预测(NSP)

NSP任务判断两个句子是否是连续的,帮助模型理解句子间关系。具体实现:

  1. 50%正例(实际连续的句子)
  2. 50%负例(随机组合的句子)
# NSP实现示例
class NextSentencePred(nn.Module):
    def __init__(self, num_inputs):
        super().__init__()
        self.output = nn.Linear(num_inputs, 2)
    
    def forward(self, X):
        # 使用[CLS]标记的表示进行预测
        return self.output(X[:, 0, :])

完整BERT模型

将编码器和预训练任务组合成完整模型:

class BERTModel(nn.Module):
    def __init__(self, vocab_size, num_hiddens, num_layers=12, heads=12):
        super().__init__()
        self.encoder = BERTEncoder(vocab_size, num_hiddens, num_layers, heads)
        self.mlm = MaskLM(vocab_size, num_hiddens)
        self.nsp = NextSentencePred(num_hiddens)
    
    def forward(self, tokens, segments, valid_lens=None, pred_positions=None):
        encoded_X = self.encoder(tokens, segments, valid_lens)
        mlm_Y_hat = self.mlm(encoded_X, pred_positions) if pred_positions else None
        nsp_Y_hat = self.nsp(encoded_X)
        return encoded_X, mlm_Y_hat, nsp_Y_hat

总结

BERT通过创新的预训练任务和双向Transformer架构,实现了上下文敏感的深度语言表示。其关键优势在于:

  1. 双向上下文编码能力
  2. 统一的架构适应多种任务
  3. 高效的预训练策略

这些特性使BERT在11项NLP任务上取得了state-of-the-art的结果,推动了自然语言处理领域的重大进步。理解BERT的工作原理对于掌握现代NLP技术至关重要。

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
178
262
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
867
513
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
129
183
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
265
305
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
398
371
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
83
4
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
598
57
GitNextGitNext
基于可以运行在OpenHarmony的git,提供git客户端操作能力
ArkTS
10
3