手动搭建Bert模型并实现与训练参数加载和微调

文章介绍了如何手动构建BERT模型,包括BertEmbeddings、Transformer和BertPooler等子模块的实现,以及如何基于HuggingFace的预训练模型加载参数。此外,还详细阐述了在IMDB数据集上进行文本情感分类的微调过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间学习了NLP相关的一些内容,这一篇主要记录NLP中的一个重要模型——Bert模型的手动实现、如何通过自定义接口实现预训练参数的加载以及在IMDB数据集上微调模型实现文本情感分类任务。

参考《动手学深度学习》搭建BERT语言模型,并加载huggingface上的预训练参数。主要包括如下内容:

  1. 编写BertEmbeddings、Transformer、BerPooler等Bert模型所需子模块代码。
  2. 在子模块基础上定义Bert模型结构。
  3. 定义Bert模型的参数配置接口。
  4. 定义自己搭建的Bert模型和huggingface上预训练的Bert模型的参数映射关系。
  5. 定义加载huggingface上预训练的Bert模型的参数到本地Bert模型的方法。

相关源代码链接:

https://download.youkuaiyun.com/download/m0_61142248/87360575

https://download.youkuaiyun.com/download/m0_61142248/87360585

https://download.youkuaiyun.com/download/m0_61142248/87364714

 

https://download.youkuaiyun.com/download/m0_61142248/87360565 

1.编写子模块 

Bert模型所需子模块主要包括BertEmbeddings、Transformer、BerPooler,其中Transformer由多头自注意力模块MultiHeadSelfAttention()和前馈模块FeedForward()FeedForward()中的激活函数为GELU()

定义BerEmbeddings模块

定义Transformer模块

Transformer模块包含多头自注意力模块MultiHeadSelfAttention()和前馈模块FeedForward(),其中FeedForward()中的激活函数为GELU()

Transformer模块实现:

自注意力模块MultiHeadSelfAttention()实现:

FeedForward()模块实现:

定义BertPooler模块

2.搭建Bert模型 

 在各子模块的基础上搭建Bert模型,Bert模型的结构参考HuggingFace的BERT结构。主要包括BertEmbedding、BertEncoder和BertPooler三部分。其中BertEncoder是由多个Transformer层堆叠而成,实验中参考了HuggingFace的bert_base_uncased预训练模型的结构参数,总共包含了12层Transformer。模型的其他参数也参考了HuggingFace的bert_base_uncased预训练模型的结构参数。vocab_size为bert_base_uncased预训练模型的字典大小,hidden_size为768,attention_head_num为12,intermediate_size为3072,hidden_act与论文中保持一致使用gelu。

3.Bert模型参数配置接口

Bert模型的参数配置接口和初始化参数

 4.定义参数映射关系

由于自己搭建的Bert模型和huggingface上预训练的Bert模型的参数名字不一致,因此需要定义两者间的映射关系,从而实现从预训练模型自动加载对应参数。定义自己搭建的Bert模型和huggingface上预训练的Bert模型的参数映射关系如下:

5.定义加载huggingface上预训练的Bert模型参数的方法

定义加载huggingface上预训练的Bert模型的参数到本地Bert模型的方法。

 至此,完成了Bert模型的手动实现、通过自定义接口实现预训练参数的加载,至于如何在IMDB数据集上实现模型的微调训练可以参考本博客的另一篇文章——文本情感分类模型之BERT。

### BERT-CRF 模型介绍 BERT-CRF 结合了双向编码器表示(Bidirectional Encoder Representations from Transformers, BERT条件随机场(Conditional Random Fields, CRF),形成了一种强大的序列标注工具,在命名实体识别(Named Entity Recognition, NER)、词性标注等任务上表现出色[^1]。 #### BERT 的作用 作为深度学习领域的重要进展之一,BERT 提供了一个预训练的语言模型框架。该模型能够捕捉到上下文中词语之间的复杂关系,通过大规模语料库上的无监督学习获得丰富的语言特征表达能力。当应用于具体任务时,只需在顶部添加适当的任务层使用少量标记样本进行微调即可达到很好的效果[^2]。 #### CRF 层的作用 CRF 是一种概率图模型,特别适合用于解决具有依赖性的分类问题。它考虑到了整个句子内部各位置之间可能存在的关联性,从而提高了预测准确性。特别是在处理像中文这样缺乏明显边界标志的语言时更为有效[^3]。 --- ### 实现方式 为了构建一个完整的 BERT-CRF 流水线,通常需要以下几个步骤: - **数据准备**:收集清理目标领域的文本资料;对于 NER 任务来说,则要准备好带有标注的信息片段。 - **预处理阶段**:这一步骤涉及将原始文档转换成可以输入给神经网络的形式。例如,对汉字做分字操作、映射至对应的 token ID 编码以及加入特殊符号 `[CLS]` `[SEP]` 来指示每条记录的开头结尾[^4]。 ```python from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') text = "你好世界" tokens = tokenizer.tokenize(text) ids = tokenizer.convert_tokens_to_ids(tokens) print(f"Tokens: {tokens}") print(f"IDs: {ids}") ``` - **模型搭建训练**:加载预训练好的 BERT 模型权重文件之后,在其之上附加一层或多层全连接层再加上最终负责解码输出标签序列的 CRF 组件。接着就可以用已有的带标签的数据集来进行参数调整工作了。 ```python import torch.nn as nn from transformers import BertModel class BertCrfForNer(nn.Module): def __init__(self, num_labels): super().__init__() self.bert = BertModel.from_pretrained('bert-base-chinese') self.dropout = nn.Dropout(0.1) self.classifier = nn.Linear(self.bert.config.hidden_size, num_labels) self.crf = Crf(num_tags=num_labels, batch_first=True) # ... (forward method and others) ``` --- ### 应用实例 在一个实际的应用场景中,比如医疗健康行业内的病历信息抽取,可以通过如下流程来部署 BERT-CRF 解决方案: 1. 收集大量经过脱敏处理的真实病例描述; 2. 使用医学术语表辅助完成高质量的手动或半自动化的实体标注过程; 3. 基于上述资源建立专门针对此领域的精调版 BERT-CRF 系统; 4. 部署上线后持续监控系统表现通过反馈机制进一步改进算法性能。 这种组合不仅继承了 BERT 对未知模式的强大泛化能力高效迁移特性,同时也借助 CRF 达成了更精准的结果产出,非常适合那些要求高精度且存在较强顺序相关性的自然语言处理应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

动力澎湃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值