【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解

时间:2022-10-18 18:03:29

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


作者简介:在校大学生一枚,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践资源建设专家委员会(TIPCC)志愿者,以及编程爱好者,期待和大家一起学习,一起进步~ . 博客主页ぃ灵彧が的学习日志 . 本文专栏人工智能 . 专栏寄语:若你决定灿烂,山无遮,海无拦 . 【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解

(文章目录)


前言

(一)、任务描述

在机器阅读理解(MRC)任务中,我们会给定一个问题(Q)以及一个或多个段落(P)/文档(D),然后利用机器在给定的段落中寻找正确答案(A),即Q + P or D => A. 机器阅读理解(MRC)是自然语言处理(NLP)中的关键任务之一,需要机器对语言有深刻的理解才能找到正确的答案。本项目基于paddlepaddle,针对DuReader阅读理解数据集数据集实现并升级了一个经典的阅读理解模型——BiDAF模型,该模型的结构图如下所示:

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解

在DuReader数据集上的效果如下表所示:

Model Dev ROUGE-L Test ROUGE-L
BiDAF (原始论文基线) 39.29 45.90
本基线系统 47.68 54.66

(二)、环境配置

本示例基于飞桨开源框架2.0版本。

import paddle
import paddle.nn.functional as F
import re
import numpy as np

print(paddle.__version__)

# cpu/gpu环境选择,在 paddle.set_device() 输入对应运行设备。
# device = paddle.set_device('gpu')

输出结果如下图1所示: 【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


一、数据准备


DuReader数据集

DuReader是一个大规模、面向真实应用、由人类生成的中文阅读理解数据集。DuReader聚焦于真实世界中的不限定领域的问答任务。相较于其他阅读理解数据集,DuReader的优势包括:

  • 问题来自于真实的搜索日志
  • 文章内容来自于真实网页
  • 答案由人类生成
  • 面向真实应用场景
  • 标注更加丰富细致

更多关于DuReader数据集的详细信息可在DuReader官网找到


二、进阶使用

(一)、任务定义与建模

阅读理解任务的输入包括:

  • 一个问题Q (已分词),例如:["明天", "的", "天气", "怎么样", "?"];
  • 一个或多个段落P (已分词),例如:[["今天", "的", "天气", "是", "多云", "转", "晴", ",", "温度", "适中", "。"], ["明天", "气温", "较为", "寒冷", ",", "请", "注意", "添加", "衣物", "。"]]。

模型输出包括:

  • 段落P中每个词是答案起始位置的概率以及答案结束位置的概率 (boundary model),例如:起始概率=[[0.01, 0.02, ...], [0.80, 0.10, ...]],结束概率=[[0.01, 0.02, ...], [0.01, 0.01, ...]],其中概率数组的维度和输入分词后的段落维度相同。

模型结构包括:

  • 嵌入层 (embedding layer):输入采用one-hot方式表示的词,得到词向量;
  • 编码层 (encoding layer):对词向量进行编码,融入上下文信息;
  • 匹配层 (matching layer):对问题Q和段落P之间进行匹配;
  • 融合层 (fusion layer):融合匹配后的结果;
  • 预测层 (output layer):预测得到起始、结束概率。

(二)、模型原理介绍

下图显示了原始的模型结构(如BiDAF模型结构图)。在本基线系统中,我们去掉了char级别的embedding,在预测层中使用了pointer network,并且参考了R-NET中的一些网络结构。


(三)、数据格式说明

DuReader数据集中每个样本都包含若干文档(documents),每个文档又包含若干段落(paragraphs)。有关数据的详细介绍可见官网论文以及数据集中包含的说明文件,下面是一个来自训练集的样本示例

{
    "documents": [
        {
            "is_selected": true,
            "title": "板兰根冲剂_百度百科",
            "most_related_para": 11,
            "segmented_title": ["板兰根", "冲剂", "_", "百度百科"],
            "segmented_paragraphs": [
                    ["板兰根", "冲剂", ",", "药", "名", ":", ... ],
                    ["【", "功效", "与", "主治", "】", ...],
                    ...
            ],
            "paragraphs": [
                "板兰根冲剂,药名...",
                "【功效与主治】...",
                ...
            ],
            "bs_rank_pos": 0
        },
        {
            "is_selected": true,
            "title": "长期喝板蓝根颗粒有哪些好处和坏处",
            "most_related_para": 0,
            "segmented_title": ["长期", "喝", "板蓝根", "颗粒", "有", "哪些", "好处", "和", "坏处"],
            "segmented_paragraphs": [
                ["板蓝根", "对", "感冒", "、", "流感","、", ...],
                ...
            ],
            "paragraphs": [
                "板蓝根对感冒、流感、流脑、...",
                ...
            ],
            "bs_rank_pos": 1
        },
        ...
    ],
    "answer_spans": [[5, 28]],
    "fake_answers": ["清热解毒、凉血;用于温热发热、发斑、风热感冒、咽喉肿烂、流行性乙型脑炎、肝炎、腮腺炎。"],
    "question": "板蓝根颗粒的功效与作用",
    "segmented_answers": [
        ["清热解毒", "、", "凉血", ";", "用于", "温", "热", "发热", ...],
        ["板蓝根", "的", "用途", "不仅", "是", "治疗", "感冒", ...],
        ...
    ],
    "answers": [
        "清热解毒、凉血;用于温热发热、发斑、风热感冒、咽喉肿烂、流行性乙型脑炎、肝炎、 腮腺炎 。",
        "板蓝根的用途不仅是治疗感冒,板蓝根的功效与作用多,对多种细菌性疾病都有较好的预防与治疗作用。",
        ...
    ],
    "answer_docs": [0],
    "segmented_question": ["板蓝根颗粒", "的", "功效", "与", "作用"],
    "question_type": "DESCRIPTION",
    "question_id": 91161,
    "fact_or_opinion": "FACT",
    "match_scores": [
        0.9583333333333334
    ]
}

三、相关代码


(一)、解压数据集


# 从work中把代码解压出来,解压数据集
!unzip -qo data/data9722/demo.zip
!mv home/aistudio/data/demo data
!rm -r home
# !tar -zxf data/data9722/dureader_machine_reading-dataset-2.0.0.tar.gz -C data

(二)、提升模型表现

为了提升模型在DuReader2.0数据集上的表现,采用了一种新的段落抽取策略。该段落抽取策略可通过运行以下命令执行:


# 使用demo的话 这里不用执行
!cd src && sh run.sh --para_extraction
!mv extracted/* data/extracted

输出结果如下图1所示:

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


(三)、生成词表

在模型训练开始之前,需要先运行以下命令来生成词表以及创建一些必要的文件夹,用于存放模型参数等:


!cd src && sh run.sh --prepare

输出结果如下图2所示:

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


三、模型训练

运行下面的命令,即可开始训练。更多的参数配置可在src/args.py中修改,默认使用data/demo中的数据进行训练


!cd src && sh run.sh --train --pass_num 50

部分输出结果如下图3所示:

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


四、模型评估

通过运行以下命令,可以利用训练好的模型在验证集进行评估,评估结束后程序会自动计算ROUGE-L指标并显示最终结果。默认使用data/demo中的数据进行评估。


!cd src && sh run.sh --evaluate  --load_dir ../data/models/50

输出结果如下图4所示:

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


五、模型预测

通过运行以下命令,可以利用训练好的模型进行预测,预测结果会保存在data/result/目录下,可以使用文本编辑的模型打开json文件查看预测结果,默认使用data/demo中的数据进行预测

同时predict脚本在预测完成后还会将模型的参数进行固化,如果需要将功能拆分,可以修改run.py文件,将freeze 和predict拆分开


!cd src && sh run.sh --predict  --load_dir  ../data/models/50

(一)、结果保存

预测的结果以这样的形式保存在文件中,根据question_type 和question_id给出对应的question

{"yesno_answers": [], "entity_answers": [[]], "answers": ["在使用路由器上网时,我们会发现在路由器上,标注得有WAN口(有的路由器是Internet口)和LAN口(有的路由器标注的是1、2、3、4)。很多用户一看就晕了,根本就不知道WAN口与LAN口的区别,自然不知道应该怎么连接了。"], "question_type": "DESCRIPTION", "question_id": 221576}

(二)、模型推断

# 使用固化后的模型参数进行推断
!cd src && python infer.py --predict --result_dir ../data/infer_results/

输出结果如下图5所示:

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解


总结

本系列文章内容为根据清华社出版的《自然语言处理实践》所作的相关笔记和感悟,其中代码均为基于百度飞桨开发,若有任何侵权和不妥之处,请私信于我,定积极配合处理,看到必回!!!

最后,引用本次活动的一句话,来作为文章的结语~( ̄▽ ̄~)~:

【**学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。**】

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解