中医名词看不懂?用PaddleNLP做一个中医“百科全书”
我是一个深度学习爱好者,目前对自然语言处理感兴趣,热衷于了解一些人工智能中的数学推导和经典论文复现,正在成长的“小趴菜”一枚,在PPDE指导计划中,创作了中医文献阅读理解项目,下面将由我介绍在项目创作过程中的一些思考
方案介绍
项目简介
中医文献阅读理解是一个将自然语言处理技术应用于中医药领域的任务,其目标是使用能够读取、理解和回答中医药知识的模型普及和传播中医药知识。该任务需要建立一个大规模的中医药语料库,并使用自然语言处理技术对语料库进行处理,提取关键信息并建立模型。
模型的输入可以是一个中医药相关的问题,模型的输出则是问题的答案。例如,如果输入的问题是“什么是中医证候学?”,则模型的输出可能是“中医证候学是中医药的一个重要理论,它旨在通过观察患者的症状和体征,推断患者所患疾病的特点和发展趋势,为临床治疗提供理论指导。”
此外,基于该任务还可以开发更多关于中医药知识的小应用,如中医药问诊系统、中医药辨证论治辅助工具等,以帮助更多人了解和应用中医药知识。
项目链接
https://aistudio.baidu.com/aistudio/projectdetail/5166465
数据集介绍
本项目标注数据源来自四个中医药领域文本,包括《黄帝内经翻译版》《名医百科中医篇》《中成药用药卷》《慢性病养生保健科普知识》。共计5000篇文档,每篇文档人工标注产生 1~4对(问题, 答案),共标注13000对(文档、问题、答案)。
{
2 "id": 98,
3 "text": "黄帝道:什麽叫重实?岐伯说:所谓重实,如大热病人,邪气甚热,而脉象又盛满,内外俱实,便叫重实",
4 "annotations": [
5 {
6 "Q": "重实是指什么?",
7 "A": "所谓重实,如大热病人,邪气甚热,而脉象又盛满,内外俱实,便叫重实"
8 },
9 {
10 "Q": "重实之人的脉象是什么样?",
11 "A": "脉象又盛满"
12 }
13 ],
14 "source": "黄帝内经翻译版"
15 }
技术点介绍
随着中医文献资源的不断增加, 如何高效地阅读和理解中医文献已经成为了一个重要课题。为了解决这个问题,我们需要利用一些自然语言处理、机器学习、可视化等相关技术。本项目的主要技术点包括:
构建中医MRC数据集,使用PaddleNLP搭建、训练并调优阅读理解模型;
采用多种内置模型进行实验,最终确定使用Roberta阅读理解模型;
动转静,完成静态图的推理,并用Gradio实现可交互的部署。
PaddleNLP
PaddleNLP是飞桨自然语言处理模型库,具备易用的文本领域API、丰富的预训练模型、多场景的应用示例和高性能分布式训练与部署能力,旨在提升开发者在文本领域的开发效率。
RoBERTa阅读理解模型
阅读理解本质是一个答案抽取任务,PaddleNLP对于各种预训练模型已经内置了对于下游任务-答案抽取的Fine-tune网络。以PaddleNLP中的RoBERTa模型为例,将模型Fine-tune完成答案抽取任务。
答案抽取任务的本质就是根据输入的问题和文章,预测答案在文章中的起始位置和结束位置。RoBERTa模型主要是在BERT基础上做了几点调整:
训练时间更长,batch size更大,训练数据更多;
移除了next predict loss;
训练序列更长;
动态调整Masking机制。
在BERT中,mask是在数据预处理过程中完成,这意味着,在每个epoch中,训练的每个句子的mask是固定的、静态的。RoBERTa提出一种动态mask的方法,将训练数据每个句子复制10次,采用不同的mask方法,这样在epoch为40的时候,平均每条mask的序列会出现4次。
对中文数据的处理中,预训练模型RoBERTa使用BPE (Byte-Pair Encoding,字节对编码)处理文本顺序。官方词表包含5万多的byte级别的token。其中,merges.txt文件存储了所有的token,vocab.json文件是一个byte到索引的映射,通常频率越高的byte索引越小。BPE编码转换的过程是,先将输入的所有tokens转化为merges.txt中对应的byte,再通过vocab.json中的字典进行byte到索引的映射。Tokenizer的作用是将原始输入文本转化成模型可以接受的输入数据形式。
基于Gradio实现AI算法可视化部署
如何将你的AI算法迅速分享给别人让对方体验,一直是一件麻烦事儿。Gradio算法可视化部署可以自动生成页面,形成交互,改动几行代码就能完成项目,支持自定义多种输入输出,支持生成可外部访问的链接,从而实现分享。
最终效果呈现
设计流程展示
环境配置
本项目基于PaddlePaddle2.0.2与PaddleNLP2.0.7版本。关于如何下载此版本可以点击飞桨官网,查看下载方式。更加推荐在AI Studio上一键运行哦。
项目链接
https://aistudio.baidu.com/aistudio/projectdetail/5166465
方案设计
阅读理解的方案如上图,query表示问句,一般是用户的提问,passage表示文章,query的答案要从passage里面抽取出来。query和passage经过数据预处理,生成其id形式的输入,然后经过RoBERTa模型,得到答案的位置,从而得到相应的answer。
数据处理
具体的任务定义为:给定问题q和一个篇章p,根据篇章内容,给出该问题的答案a。数据集中的每个样本,是一个三元组<q, p, a>,例如:
问题 q: 草菇有什么功效?
篇章 p: 草菇荠菜汤鲜嫩清香、色味搭配,具有清热和脾、益气平肝、降糖降压等功效,是夏季解暑祛热的良食佳品…….
参考答案 a: 草菇荠菜汤鲜嫩清香、色味搭配,具有清热和脾、益气平肝、降糖降压等功效。
本项目的数据集是json格式,包括:
lid: 段落id
ltext: 段落文本
lannotations: 每个段落拥有一个annotations,其中包含1~4对(问题、答案)
lQ:问题
lA:答案
将上述数据进行简单地数据清洗以及格式(sqaud格式)转换操作。为了方便读取,具体格式如下:
{'id': 'xx', 'title': 'xxx', 'context': 'xxxx', 'question': 'xxxxx', 'answers': ['xxxx'], 'answer_starts': [xxx]
}
模型训练与策略选择
设置Fine-tune优化策略
# 参数配置# 训练过程中的最大学习率
learning_rate = 3e-5
# 训练轮次
epochs = 2
# 学习率预热比例
warmup_proportion = 0.1
# 权重衰减系数,类似模型正则项策略,避免模型过拟合
weight_decay = 0.01num_training_steps = len(train_data_loader) * epochs
lr_scheduler = ppnlp.transformers.LinearDecayWithWarmup(learning_rate, num_training_steps, warmup_proportion)# Generate parameter names needed to perform weight decay.
# All bias and LayerNorm parameters are excluded.
decay_params = [p.name for n, p in model.named_parameters()if not any(nd in n for nd in ["bias", "norm"])
]
optimizer = paddle.optimizer.AdamW(learning_rate=lr_scheduler,parameters=model.parameters(),weight_decay=weight_decay,apply_decay_param_fun=lambda x: x in decay_params)
设计损失函数
由于BertForQuestionAnswering模型将BERT模型的sequence_output拆成start_logits和end_logits,所以阅读理解任务的loss也由start_loss和end_loss组成。答案起始位置和结束位置的预测可以分成两个分类任务,我们需要自己定义损失函数。
设计的损失函数如下:
class CrossEntropyLossForSQuAD(paddle.nn.Layer):
def init (self):
super(CrossEntropyLossForSQuAD, self). init ()
def forward(self, y, label):
start_logits, end_logits = y # both shape are [batch_size, seq_len]
start_position, end_position = label
start_position = paddle.unsqueeze(start_position, axis=-1) end_position = paddle.unsqueeze(end_position, axis=-1)
start_loss = paddle.nn.functional.softmax_with_cross_entropy(
logits=start_logits, label=start_position, soft_label=False) start_loss = paddle.mean(start_loss)
end_loss = paddle.nn.functional.softmax_with_cross_entropy( logits=end_logits, label=end_position, soft_label=False)
end_loss = paddle.mean(end_loss)loss = (start_loss + end_loss) / 2 return loss
模型训练
模型训练的过程通常有以下步骤:
从dataloader中取出一个batch data;
将batch data喂给model,做前向计算;
将前向计算结果传给损失函数,计算loss;
loss反向回传,更新梯度。重复以上步骤。
每训练一个epoch时,程序通过evaluate()调用paddlenlp.metric.squad中的squad_evaluate()返回评价指标,compute_predictions() 评估当前模型训练的效果,用于生成可提交的答案。
预测部署
模型训练完成之后,我们实现模型的预测部署。虽然训练阶段使用的动态图模式有诸多优点,包括Python风格的编程体验(使用RNN等包含控制流的网络时尤为明显)、友好的debug交互机制等。但Python动态图模式无法更好地满足预测部署阶段的性能要求,同时也限制了部署环境。
高性能预测部署需要静态图模型导出和预测引擎两方面的支持。
动转静导出模型
基于静态图的预测部署要求将动态图的模型转换为静态图形式的模型(网络结构和参数权重)。飞桨静态图形式的模型(由变量和算子构成的网络结构)使用Program来存放,Program的构造可以通过飞桨的静态图模式说明,静态图模式下网络构建执行的各API会将输入输出变量和使用的算子添加到Program中。
使用推理库预测
获得静态图模型之后,我们使用Paddle Inference进行预测部署。Paddle Inference是飞桨的原生推理库,作用于服务器端和云端,提供高性能的推理能力。使用 Paddle Inference 开发 Python 预测程序仅需以下步骤:
Gradio进行交互项部署
Gradio部署有以下步骤:
将模型拷贝到本地,并按照接口要求封装好方法;
import Gradio as gr
def question_answer(context, question):
pass # Implement your question-answering model here...
gr.Interface(fn=question_answer, inputs=["text", "text"], outputs=["textbox", "text"]).launch(share=True)
加载用户输入的context和question,并利用模型返回answer;
返回到Gradio部署的框内, 进行页面展示;
生成公开链接。
总结与展望
模型效果对比
本项目尝试了12L768H的bert-base-chinese、bert-wwm-ext-chinese和24L1024H的roberta-wwm-ext-large模型,效果如下,可以看到roberta-wwm-ext-large模型能够取得较好的效果,随之付出的代价就是模型的体积变大,并且训练速度变迟缓。除此之外,如果epoch过大,极易发生过拟合,可以调整学习率等参数避免过拟合。
与roberta-wwm-ext-large相比,同规模的ERNIE 1.0-Large-cw、ERNIE 2.0-Large-zh在CLUE各项任务上平均精度更高,后续计划尝试ERNIE系列模型。
模型Benchmark地址
https://github.com/PaddlePaddle/PaddleNLP/tree/develop/model_zoo/ernie-3.0
使用方法参考
https://aistudio.baidu.com/aistudio/projectdetail/2017189
项目展望
数据
寻找更多优质中医语料数据集,进行简单增强,采用回译等数据增强方法,从无到有的构建文本相似数据集。
项目部署
利用AI Studio部署趣味项目或将模型打包后使用flask框架,配合前端页面制作体验更好的小应用。
模型优化
将模型微调的几步epoch结果保存,进行模型平均操作。采用模型Bagging策略,将训练质量好的模型融合处理,探寻更多优质模型。针对任务,使用更多医疗数据集训练好的预训练模型。
更多
学习RocketQA等端到端问答模型,加上检索条件,在机器阅读理解基础上制作完整的基于检索的问答系统,并可为后续学习基于生成的问答模型打下基础。(PS:励志做个类似ChatGPT的通用问答模型)
开源项目地址
https://github.com/PaddlePaddle/PaddleNLP
参考文献
[1]https://aistudio.baidu.com/aistudio/projectdetail/2017189
[2]https://aistudio.baidu.com/aistudio/projectdetail/4113678
中医名词看不懂?用PaddleNLP做一个中医“百科全书”相关推荐
- sas 检测到开型代码语句的递归_对于标准答案的递归很多人都看不懂,其实就是一个深度优先的遍历。我写了段伪代码,将递归步骤还原并注释了一下,供大家参考,希望大家有所收获。...
源自:7-5 Python之递归函数 对于标准答案的递归很多人都看不懂,其实就是一个深度优先的遍历.我写了段伪代码,将递归步骤还原并注释了一下,供大家参考,希望大家有所收获. #if条件不成立的省略 ...
- 计算机学渣娃,学渣表示看不懂!WIN10中一个小小计算器都如此牛逼
Windows 10手机版的第一个预览版本已经发放.虽然前期工作主要是底层平台开发,软件.功能.界面都还很粗糙,但至少咋计算器这个小家伙上,微软已经做得相当完美了. Windows Phone 8.1 ...
- 程序猿炫起富来你们根本看不懂!
一直以来我们对程序猿都有误解,认为他们只会写代码.穿格子衬衫.背双肩包.还秃顶,认为他们工作枯燥,生活低调,从不炫富. 不是程序猿不炫富,是炫起富来你们根本看不懂!!! 比如程序猿的三大信仰之一 -- ...
- python做一个登录注册界面_python做一个登录注册界面的方法
python做一个登录注册界面的方法 发布时间:2020-08-21 10:37:05 来源:亿速云 阅读:111 作者:小新 这篇文章主要介绍python做一个登录注册界面的方法,文中介绍的非常详细 ...
- 谷歌大脑科学家亲解 LSTM:一个关于“遗忘”与“记忆”的故事 本文作者:奕欣 2017-01-14 09:46 导语:AI科技评论保证这是相对通俗易懂的一篇入门介绍了,看不懂的话欢迎关注「AI 科技
谷歌大脑科学家亲解 LSTM:一个关于"遗忘"与"记忆"的故事 本文作者:奕欣 2017-01-14 09:46 导语:AI科技评论保证这是相对通俗易懂的一篇入 ...
- 如何在完全不懂服务器开发的情况下做一个实时联网对战的微信小游戏
微信小游戏即将开放?有我们在,你还赶得上! 根据微信官方对外公开的消息,微信小游戏的脚步越来越接近了.它的开发者资格门槛和使用者门槛都很低,以后必将引爆一波"全民开发小游戏"浪潮. ...
- Apple 一个我越发看不懂的公司
以下内容就事论事,本着对事不对人的原则. 本人也算是个果粉了,至于是否脑残粉,有待判断,用过apple的东西,不敢说全部,大部分,都接触过,从早期的ipod ipodc(V) 到iPhone1-6,笔 ...
- 物联网名词和MQTT解释,阿里云的教程:用51单片机做一个物联网温度计+远程开关
https://mvp.aliyun.com/zhidao/1915 本章主要介绍物联网平台中相关的产品名词.明白名词说的是啥.两眼不慌慌.看看官方文档吧 concent 报文连接服务器 ...
- 愿做一个淡看花落的闲人
愿做一个淡看花落的闲人,缘来相迎,缘去相送,去留随意,悲喜随心. 浅夏的午后,一帘绵绵的细雨,温柔的敲打着窗户,也叩响我的心门.泥土的清香,混合着花儿的的芬芳,扑鼻而来.一阵莫名的欢愉,流淌在心间,激 ...
最新文章
- Eclipse连接数据库MySQL以及一些有关数据库的知识
- mysql 递归查找父节点_MYSQL递归查询,根据子类ID查询所有父类(最全)
- [css] 如何解决IE6浮动时产生双倍边距的BUG?
- python 编辑距离_最小编辑距离python
- python接口自动化(十六)--参数关联接口后传(详解)
- vue2 自定义事件 v-model .sync
- Json 入门例子【3】
- AutoCAD2020修改 图层名称
- MapGIS云认证失败
- Procdump+Mimikatz获取Windows明文密码
- 无线网络dns服务器是多少,中国移动宽带dns是多少?
- matlab堆积式玫瑰图,[转帖]堆积式南丁格尔玫瑰图模板
- python网课 知乎_如何看待风变编程的 Python 网课
- shopex PHP Notice,shopex官网用PHP为SHOPEX增加日志功能代码
- 【houdini hom】弹砖块
- 生鲜电商的“7年之谎”
- 仿最新BiliBili客户端(已开源)
- 【渗透测试】VulnHub-Lord Of The Root: 1.0.1
- 当系统logoff或shutdown时,让应用程序正常关闭
- Ubuntu16.04安装graph-tool采坑指南