使用预训练模型的Bert
这个项目是基于PyTorch框架实现的BERT模型及其相关的下游任务。项目详细解释了BERT模型和每个底层任务的原则。
BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
在学习使用这个项目之前,您需要通过这三个例子了解Transformer的相关原则:翻译、分类、对联生成。
实现
- 1. 从零开始实现BERT模型
- 2. 基于BERT预训练模型的中文文本分类任务
- 3. 基于BERT预训练模型的英文文本蕴涵(MNLI)任务
- 4. 基于BERT预训练模型的英文多项选择(SWAG)任务
- 5. 基于BERT预训练模型的英文问答(SQuAD)任务
- 6. 基于NSL和MLM任务从零开始训练BERT任务
- 7. 基于BERT预训练模型的命名实体识别任务
项目结构
-
bert_base_chinese
包含 bert_base_chinese 预训练模型和配置文件 -
bert_base_uncased_english
包含 bert_base_uncased_english 预训练模型和配置文件 -
data
包含所有下游任务使用的数据集。SingleSentenceClassification
是头条新闻的15类中文分类数据集。PairSentenceClassification
是MNLI(多体裁自然语言推理语料库)数据集。MultipleChoice
是SWAG数据集。SQuAD
是SQuAD-V1.1数据集。WikiText
是用于预训练的英文维基百科语料库。SongCi
是用于中文模型预训练的宋词数据。ChineseNER
是用于训练中文命名实体识别的数据集。
-
model
是对各个模块的实现BasicBert
包含基本的BERT实现MyTransformer.py
自注意力机制的实现。BertEmbedding.py
输入嵌入的实现。BertConfig.py
用于导入config.json
的配置。Bert.py
BERT的实现。
DownstreamTasks
包含所有下游任务的实现BertForSentenceClassification.py
句子(们)分类的实现。BertForMultipleChoice.py
多项选择的实现。BertForQuestionAnswering.py
问答(文本片段)的实现。BertForNSPAndMLM.py
NSP和MLM任务的实现。BertForTokenClassification.py
标记分类的实现。
-
Task
下游任务的训练和推理的实现TaskForSingleSentenceClassification.py
单句分类任务的实现,如句子分类。TaskForPairSentence.py
成对句子分类任务的实现,如MNLI。TaskForMultipleChoice.py
多项选择任务的实现,如SWAG。TaskForSQuADQuestionAnswering.py
问答(文本片段)任务的实现,如SQuAD。TaskForPretraining.py
NSP和MLM任务的实现。TaskForChineseNER.py
中文命名实体识别任务的实现。
-
test
下游任务的测试用例。 -
utils
data_helpers.py
是每个下游任务的数据预处理和数据集构建模块;log_helper.py
是日志打印模块。creat_pretraining_data.py
用于构建BERT预训练任务的数据集。
Python环境
Python 3.6及包版本
torch==1.5.0
torchtext==0.6.0
torchvision==0.6.0
transformers==4.5.1
numpy==1.19.5
pandas==1.1.5
scikit-learn==0.24.0
tqdm==4.61.0
使用方法
步骤 1. 下载数据集
下载各个数据集和相应的BERT预训练模型(若为空),将其放在相应目录中。详情请参阅各数据目录(data
)中的README.md
文件。
步骤 2. 运行
进入Tasks
目录并运行模型。
2.1 中文文本分类任务
模型结构和数据处理:
python TaskForSingleSentenceClassification.py
结果:
-- INFO: Epoch: 0, Batch[0/4186], Train loss :2.862, Train acc: 0.125
-- INFO: Epoch: 0, Batch[10/4186], Train loss :2.084, Train acc: 0.562
-- INFO: Epoch: 0, Batch[20/4186], Train loss :1.136, Train acc: 0.812
-- INFO: Epoch: 0, Batch[30/4186], Train loss :1.000, Train acc: 0.734
...
-- INFO: Epoch: 0, Batch[4180/4186], Train loss :0.418, Train acc: 0.875
-- INFO: Epoch: 0, Train loss: 0.481, Epoch time = 1123.244s
...
-- INFO: Epoch: 9, Batch[4180/4186], Train loss :0.102, Train acc: 0.984
-- INFO: Epoch: 9, Train loss: 0.100, Epoch time = 1130.071s
-- INFO: Accurcay on val 0.884
-- INFO: Accurcay on val 0.888
2.2 文本蕴涵
模型结构和数据处理:
python TaskForPairSentenceClassification.py
结果:
-- INFO: Epoch: 0, Batch[0/17181], Train loss :1.082, Train acc: 0.438
-- INFO: Epoch: 0, Batch[10/17181], Train loss :1.104, Train acc: 0.438
-- INFO: Epoch: 0, Batch[20/17181], Train loss :1.129, Train acc: 0.250
-- INFO: Epoch: 0, Batch[30/17181], Train loss :1.063, Train acc: 0.375
...
-- INFO: Epoch: 0, Batch[17180/17181], Train loss :0.367, Train acc: 0.909
-- INFO: Epoch: 0, Train loss: 0.589, Epoch time = 2610.604s
...
-- INFO: Epoch: 9, Batch[0/17181], Train loss :0.064, Train acc: 1.000
-- INFO: Epoch: 9, Train loss: 0.142, Epoch time = 2542.781s
-- INFO: Accurcay on val 0.827
-- INFO: Accurcay on val 0.830
2.3 多项选择(SWAG)任务
模型结构和数据处理:
python TaskForMultipleChoice.py
结果:
[2021-11-11 21:32:50] - INFO: Epoch: 0, Batch[0/4597], Train loss :1.433, Train acc: 0.250
[2021-11-11 21:32:58] - INFO: Epoch: 0, Batch[10/4597], Train loss :1.277, Train acc: 0.438
[2021-11-11 21:33:01] - INFO: Epoch: 0, Batch[20/4597], Train loss :1.249, Train acc: 0.438
......
[2021-11-11 21:58:34] - INFO: Epoch: 0, Batch[4590/4597], Train loss :0.489, Train acc: 0.875
[2021-11-11 21:58:36] - INFO: Epoch: 0, Batch loss :0.786, Epoch time = 1546.173s
[2021-11-11 21:28:55] - INFO: Epoch: 0, Batch[0/4597], Train loss :1.433, Train acc: 0.250
[2021-11-11 21:30:52] - INFO: 他正向墙上投掷飞镖。一名女子蹲在旁边,手持枪在左右移动。 ## 错误
[2021-11-11 21:30:52] - INFO: 他正向墙上投掷飞镖。一名女子向飞镖盘掷出飞镖。 ## 错误
[2021-11-11 21:30:52] - INFO: 他正向墙上投掷飞镖。一名女子倒下摔在地上。 ## 错误
[2021-11-11 21:30:52] - INFO: 他正向墙上投掷飞镖。一名女子站在他旁边。## 正确
[2021-11-11 21:30:52] - INFO: 验证集上的准确率 0.794
2.4 问答(SQuAD)任务
模型结构和数据处理:
"exact_match" : 80.879848628193, "f1": 88.338575234135
### 2.5 NSL and MLM tasks
Model structure and data processing:
<img src="https://yellow-cdn.veclightyear.com/2b54e442/8ef08b8a-94c5-46c6-8f7d-78d11f810810.jpg" width="50%">
<img src="https://yellow-cdn.veclightyear.com/2b54e442/4eb958f4-cda1-4afe-bf61-87cbcffb024f.jpg" width="50%">
```python
if __name__ == '__main__':
config = ModelConfig()
train(config)
sentences_1 = ["I no longer love her, true, but perhaps I love her.",
"Love is so short and oblivion so long."]
sentences_2 = ["我住长江头,君住长江尾。",
"日日思君不见君,共饮长江水。",
"此水几时休,此恨何时已。",
"只愿君心似我心,定不负相思意。"]
inference(config, sentences_2, masked=False, language='zh')
Result:
- INFO: ## 成功载入已有模型进行推理……
- INFO: ### 原始:我住长江头,君住长江尾。
- INFO: ## 掩盖:我住长江头,[MASK]住长[MASK]尾。
- INFO: ## 预测:我住长江头,君住长河尾。
- INFO: ====================
- INFO: ### 原始:日日思君不见君,共饮长江水。
- INFO: ## 掩盖:日日思君不[MASK]君,共[MASK]长江水。
- INFO: ## 预测:日日思君不见君,共饮长江水。
# ......
2.6 Named Entity Recognition task
Model structure and data processing:
if __name__ == '__main__':
config = ModelConfig()
train(config)
sentences = ['智光拿出石壁拓文为乔峰详述事情始末,乔峰方知自己原本姓萧,乃契丹后族。',
'当乔峰问及带头大哥时,却发现智光大师已圆寂。',
'乔峰、阿朱相约找最后知情人康敏问完此事后,就到塞外骑马牧羊,再不回来。']
inference(config, sentences)
Result of training:
- INFO: Epoch: [1/10], Batch[620/1739], Train Loss: 0.115, Train acc: 0.96386
- INFO: Epoch: [1/10], Batch[240/1739], Train Loss: 0.098, Train acc: 0.96466
- INFO: Epoch: [1/10], Batch[660/1739], Train Loss: 0.087, Train acc: 0.96435
......
- INFO:句子:在澳大利亚等西方国家改变反倾销政策中对中国的划分后,不少欧盟人士也认识到,此种划分已背离中国经济迅速发展的现实。
- INFO: 澳大利亚: LOC
- INFO: 中国: LOC
- INFO: 欧盟: LOC
- INFO: 中国: LOC
......
precision recall f1-score support
O 1.00 0.99 1.00 97640
B-ORG 0.86 0.93 0.89 984
B-LOC 0.94 0.93 0.94 1934
B-PER 0.97 0.97 0.97 884
I-ORG 0.90 0.96 0.93 3945
I-LOC 0.91 0.95 0.93 2556
I-PER 0.99 0.98 0.98 1714
accuracy 0.99 109657
macro avg 0.94 0.96 0.95 109657
weighted avg 0.99 0.99 0.99 109657
Result of inference:
- INFO: 句子:智光拿出石壁拓文为乔峰详述事情始末,乔峰方知自己原本姓萧,乃契丹后族。
- INFO: 智光: PER
- INFO: 乔峰: PER
- INFO: 乔峰: PER
- INFO: 萧: PER
- INFO: 丹: PER
......
</SOURCE_TEXT>