用BERT进行机器阅读理解


  磐创AI分享  

作者 | Edward Qian
编译 | VK
来源 | Towards Data Science

这里可以找到带有代码的Github存储库:https://github.com/edwardcqian/bert_QA。本文将讨论如何设置此项功能.


机器(阅读)理解是NLP的领域,我们使用非结构化文本教机器理解和回答问题。

https://www.coursera.org/specializations/deep-learning?ranMID=40328&ranEAID=J2RDoRlzkk&ranSiteID=J2RDo.Rlzkk-XtffRH2JEnDifWa3VrZJ1A&siteID=J2RDo.Rlzkk-XtffRH2JEnDifWa3VrZJ1A&utm_content=2&utm_medium=partners&utm_source=linkshare&utm_campaign=J2RDoRlzkk

2016年,斯坦福德NLP将由超过100000对问答对组成的SQuAD (斯坦福问答数据集)集合在一起,这些数据集由维基百科文章编制。挑战是训练一个机器学习模型,以基于上下文文档回答问题。

当提供上下文(自由文本)和问题时,模型将返回最有可能回答问题的文本子集。

世界上顶尖的人工智能从业人员解决了这个问题,但两年后,没有一个模型能超越人类的标准。然而,2018年底,谷歌大脑引入了通用语言理解模型BERT(Transforms的双向编码器表示)。经过一些微调,与小组测试集相比,该模型能够超越人类的基准。

来自论文:https://arxiv.org/pdf/1606.05250.pdf,这些是用于评估的指标:

完全匹配。这个度量标准衡量的是精确匹配任何一个真实答案的百分比。

(宏平均)F1得分。这个度量了预测和真实答案之间的平均重叠。我们把预测和真实标签当作token列表,并计算它们的F1。我们对给定问题的所有真实答案取最大F1,然后对所有问题取平均值。

基于初始的团队数据集:

  • 人类注释者的精确匹配得分为82.304%,F1得分91.221%

  • 原BERT模型获得85.083%的精确匹配分数,F1得分91.835%


今天,我将向你演示如何使用BERT建立自己的阅读理解系统。这里可以找到带有代码的Github存储库。

https://github.com/edwardcqian/bert_QA

先设置Docker。????

设置Docker

Docker对于容器化应用程序很有用。我们将使用Docker使这项工作更为有用,结果更可重复。按照以下说明在系统上安装Docker。

你还需要docker compose,它是在macos和windows上与docker一起提供的。如果你使用Linux,可以在此处安装它:https://runnable.com/docker/introduction-to-docker-compose

从Github仓库保存代码

除了训练过的数据和预训练的权重之外,所有代码和必要的依赖项都在repo中。注意:只有当你想自己训练模型时,才需要数据。如果没有,你可以使用我预训练过的权重。另一个注意:除非你有一个强大的GPU或大量的时间,否则我不建议训练这个模型。

如果你想亲自训练模型…

在这里下载Team2.0数据集:https://rajpurkar.github.io/SQuAD-explorer/。将“Training Set v2.0”和“Dev Set v2.0”保存到bert_uqa/data。

如果你想使用预训练的权重…

我已经针对SQuAD 2.0训练了模型。你可以在这里下载。解压缩文件并保存内容asbert_uqa/weights。

创建Docker容器

Docker容器是使用Docker映像中提供的指令构建的工作环境。我们需要一个docker-compose.yaml配置文件来定义容器的外观。

version: '3'
services:
    pytorch:
        image: 'edwardcqian/huggingface_transformers_pytorch:2.5.1'
        tty: true
        restart: always
        volumes:
            - ./:/workspace

我为huggingface的Pytorch Transformer制作了一个定制的docker镜像,你可以在dockerhub上找到。为了本教程的目的,你不需要像配置文件那样拉取任何镜像。配置文件还将本地bert_QA文件夹作为容器中的/workspace。

  • 通过在terminal/shell根目录中运行docker compose up-d来启动容器。第一次将需要几分钟。

  • 检查我们的包含是否已启动,并使用Docker ps运行。

  • 将bash shell附加到正在运行的容器:

docker exec -it <your_container_name> bash

训练模型

如果你使用我的预训练的权重,请跳过此步骤。我们将使用huggingface提供的默认训练脚本来训练模型。

在bash shell中运行此命令:

python run_squad.py \
  --model_type bert \
  --model_name_or_path bert-base-uncased \
  --do_train \
  --do_eval \
  --do_lower_case \
  --train_file data/train-v2.0.json \
  --predict_file data/dev-v2.0.json \
  --per_gpu_train_batch_size 12 \
  --learning_rate 3e-5 \
  --num_train_epochs 2.0 \
  --max_seq_length 384 \
  --doc_stride 128 \
  --output_dir weights/

注意:如果没有GPU,则per_gpu_train_batch_size将不会做任何操作

这将训练模型权重并将其保存到权重目录。

用模型进行推断

现在让我们用这个模型来做一些酷的事情。

在shell中启动ipython会话,并导入ModelInference模块以从weights/加载权重。将上下文文档作为参数传递给mi.add_target_text()。

摄入语料库后,使用mi.evaluate()提问。只有当模型确信答案存在于文本中时,模块才会返回答案。否则,模型将输出“找不到有效答案”。

from model_inference import ModelInference

mi = ModelInference('weights/')

mi.add_target_text((
  'The Normans (Norman: Nourmands; French: Normands; Latin: Normanni) '
  'were the people who in the 10th and 11th centuries gave their name to '
  'Normandy, a region in France. They were descended from Norse '
  '(\"Norman\" comes from \"Norseman\") raiders and pirates from Denmark, '
  'Iceland and Norway who, under their leader Rollo, '
  'agreed to swear fealty to King Charles III of West Francia. '
  'Through generations of assimilation and mixing with the native '
  'Frankish and Roman-Gaulish populations, their descendants would gradually '
  'merge with the Carolingian-based cultures of West Francia. '
  'The distinct cultural and ethnic identity of the Normans emerged initially '
  'in the first half of the 10th century, '
  'and it continued to evolve over the succeeding centuries.'
))

mi.evaluate('Where is Normandy')
# france

mi.evaluate('What are Normans called in latin?')
# normanni

mi.evaluate('When was normandy named?')
# in the 10th and 11th centuries

mi.evaluate('What kind of songs did the Normans sing?')
# No valid answers found.

mi.evaluate('What is you quest?')
# No valid answers found.

结论

NLP在过去几年里已经走了很长的路。预训练的BERT权值对NLP的影响与AlexNet对图像识别的影响相似。它为自然语言理解提供了许多新的应用。

觉得还不错就给我一个小小的鼓励吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BERT模型在自然语言处理领域中有着广泛的应用,其中之一就是抽取式阅读理解。本文将介绍如何使用BERT模型实现抽取式阅读理解任务。 抽取式阅读理解任务是指给定一篇文章和相关问题,需要从文章中找出与问题相关的答案。这种任务在问答系统、机器翻译等领域中有着广泛的应用。 下面是使用BERT模型实现抽取式阅读理解的步骤: 1. 数据预处理 首先需要对数据进行预处理,将文章和问题转换成BERT模型的输入格式。BERT模型的输入是一组token序列,其中每个token都对应一个编号。因此需要将文章和问题中的每个词转换成对应的编号。同时,还需要加入一些特殊的token,如[CLS]表示序列的开始,[SEP]表示序列的结束。 2. BERT模型 接下来需要使用BERT模型对输入序列进行编码。BERT模型使用Transformer结构对输入序列进行编码,得到一个表示序列的向量。可以使用预训练好的BERT模型,也可以使用自己的数据进行微调。 3. 输出层 得到编码后的序列向量后,需要使用输出层将其转换成答案的开始和结束位置。输出层通常由两个全连接层组成,其中第一个全连接层将编码后的序列向量转换成一个表示开始位置的向量,第二个全连接层将其转换成一个表示结束位置的向量。 4. 训练和预测 最后需要对模型进行训练和预测。在训练时,可以使用交叉熵损失函数来计算模型的损失,然后使用反向传播算法更新模型的参数。在预测时,需要使用模型预测出答案的开始和结束位置,并从原始输入序列中抽取出答案。 下面是使用PyTorch实现BERT抽取式阅读理解代码示例: ```python import torch from transformers import BertTokenizer, BertForQuestionAnswering # 加载预训练的BERT模型和tokenizer model = BertForQuestionAnswering.from_pretrained('bert-base-chinese') tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') # 文章和问题 context = '自然语言处理是人工智能和语言学领域的交叉学科,旨在研究计算机如何处理和理解自然语言。' question = '自然语言处理属于哪个学科?' # 将文章和问题转换成token序列 tokens = tokenizer.encode_plus(question, context, add_special_tokens=True, return_tensors='pt') # 使用BERT模型得到编码后的序列向量 outputs = model(**tokens) # 将序列向量转换成答案的开始和结束位置 start_logits, end_logits = outputs.start_logits, outputs.end_logits # 从原始输入序列中抽取出答案 start_index = torch.argmax(start_logits) end_index = torch.argmax(end_logits) answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(tokens['input_ids'][0][start_index:end_index+1])) print(answer) ``` 在上面的代码中,首先加载了预训练的BERT模型和tokenizer。然后将文章和问题转换成token序列,并使用BERT模型得到编码后的序列向量。最后将序列向量转换成答案的开始和结束位置,并从原始输入序列中抽取出答案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值