《从零开始学习自然语言处理(NLP)》-DeepPavlov框架解析(4)

写在最前面

在这个日新月异的信息时代,海量数据的积累,计算能力的不断提升,机器学习尤其是深度学习的蓬勃发展,使得人工智能技术在不同领域焕发出蓬勃的活力。自己经历了嵌入式开发,移动互联网开发,目前从事自然语言处理算法开发工作。从工程软件开发到自然语言处理算法开发,希望通过这个系列的文章,能够由浅入深,通俗易懂的介绍自然语言处理的领域知识,分享自己的成长,同大家一起进步。

问题描述

在上一篇《从零开始学习自然语言处理(NLP)-NLP Framework开源方案梳理(3)》中梳理了目前流行的NLP开源框架,这里重点介绍下DeepPavlov框架。DeepPavlov框架的模型实用性很强,对实际的生产开发有很大的借鉴意义。

框架组成

DeepPavlov是一个基于TensorFlow和Keras的,专门针对对话系统研究和实验部署的自然语言处理框架。
项目地址:http://docs.deeppavlov.ai/en/master/#
框架主要包括:
常用的NLP模型(包括Pre-train模型)
如词向量训练、分类、命名实体识别(NER)、相似度计算等;
针对对话系统实现和评测的实验框架(Framework)
基于Json文件进行开发流程和数据流pipeline配置;
提供同第三方应用进行集成的工具
如与Amazon Alexa和Microsoft Bot Framework的集成;
为对话模型的评测提供Benchmark环境
DeepPavlov的默认Pre-train模型和测评数据集主要基于英文和俄文,对于中文场景需要做适当的调整。

框架使用对象

新模型开发者
方便同已有Benchmark模型进行对比评测
普通NLP任务处理者
如针对内容审核任务,敏感信息增加掩码等任务,可以直接使用框架提供的分类和序列标注模型,完成业务服务的快速开发和测评;
对话系统开发者
DeepPavlov是为对话系统场景量身定制的。对话系统开发者,可以直接参考使用;
对话系统应用开发者
DeepPavlov框架为应用集成提供了专门的工具,可以直接与Amazon Alexa,Microsoft Bot Framework等平台进行对接。

框架使用

规范开发流程
框架将数据模型服务的开发和验证流程(如数据清洗、模型设计、模型训练、模型选优、模型评测),使用Json配置文件串联成pipeline。能够很好的规范开发流程;
新模型对比评测
为对话模型的评测提供Benchmark环境,方便新模型的对比评测。但环境主要基于英文和俄文,对于中文任务,需要重新训练对比;
常用NLP模型使用
框架内置了很多常用模型(以分类为例,就包含了cnn_model,bilstm_model,bilstm_attention_model,transformer_model等12种模型实现),在项目中可以直接使用;
同时框架提供了Pre-train模型,但主要是基于英文和俄文的,对于中文场景需要自己进行重新训练;
对话系统开发
DeepPavlov是为对话系统场景量身定制的,对话系统开发者,可以直接参考使用;

DeepPavlov框架层次

DeepPavlov从整体到局部,可分为如下三个层次:


DeepPavlov框架层次

下面我们从外层到内层,逐层介绍DeepPavlov的框架设计。

DeepPavlov顶层框架

DeepPavlov框架

Agent
同用户直接交互的代理,直接接收用户输入的纯文本信息(raw text)
Skill
领域技能,如基于意图-词槽的任务型技能,基于Seq2Seq的闲聊技能,基于知识图谱的知识问答技能;
Skill Manager
确定用户query,选择使用哪些skill,并确定将哪一个skill的召回结果作为最终的回复;
Component
Skill实现的组成部分,如针对任务型技能,包括数据预处理component、意图识别component、slotfilling component等;
Chainer
Chainer以Json配置文件的形式,将某个skill相关的所有component串联起来;
Data Storage
框架本身包含的Pre-train模型和Benchmark评测数据集

Skill框架

DeepPavlov内置的skill主要包括:
任务型skill(Goal-Oriented Dialogue Bot)
基于意图/词槽/对话管理等component实现的问答skill。

任务型skill

阅读理解skill(Open-Domain Question Answering)
基于阅读理解实现问答skill。相对于阅读理解component(Context Question Answering),skill还包含在多个召回结果中进行排序的能力。
规则型skill(Pattern Matching)
基于自定义规则实现问答skill。
Seq2Seq skill(Sequence-To-Sequence Dialogue Bot)
基于Seq2Seq实现问答skill。
Seq2Seq skill

常见问题问答skill(Frequently Asked Questions Answering)
先将句子嵌入为向量(使用词向量叠加),然后做分类处理(给每一个answer一个打分),选取打分最高的answer作为最终回复的skill。
商品查询skill(eCommerce Bot)
商品查询回复skill,支持多轮(添加过滤条件)。下面是场景示例,
商品查询skill

基本能力框架

DeepPavlov内置的基本能力主要包括:
数据预处理component(Data processors)
主要提供包括分词、嵌入向量化等预处理能力(主要基于俄文和英文)。
阅读理解component(Context Question Answering)
相对于阅读理解skill(Open-Domain Question Answering),component不包含对多个召回结果进行排序(rank)的能力。具体的处理场景示例如下,

阅读理解component

分类component(Classification)
分类组件,可以用来做场景和意图的分类。
Morphological Tagger component
一种特殊的POS?
命名实体识别component(Named Entity Recognition)
NER能力组件。
相似度计算component(Neural Ranking)
通过基于孪生网络完成相似度计算,实现在标准问答库中标准答复的查找。
词槽填充component(Slot filling)
在NER的基础上,增加了词表限制。
*拼写纠错component(Spelling Correction)
提供了两种纠错方法:

  • levenshtein_corrector :基于编辑距离
  • brillmoore:基于统计模型

TF-IDF排序component(TF-IDF Ranking)
基于TF-IDF的文档召回排序。
流行度排序component(Popularity Ranking)
将TF-IDF打分和流行度打分作为特征,通过逻辑回归计算流行度,最终实现排序。

Json配置文件解析

DeepPavlov通过Json配置文件实现开发流程控制和数据流pipeline的控制。
上面提到DeepPavlov主要分为Agent、Skill和Component三个层次。而Json配置文件主要应用在Skill和Component这两个层面。而对Agent的控制,框架通过直接的代码来实现,例如,

agent

其中,
skills
Agent支持的所有skill列表;
skills_filter
针对用户query,确定Agent使用哪些skill;
skills_filter
通过召回的不同skill结果,确定最后的回复内容给用户;
下面我们具体的介绍下Json配置文件的具体结构。

Json配置文件结构

Json配置文件结构

如上图所示,Json配置文件主要由如下五个部分组成(参考分类component):
dataset_reader
主要负责数据的读取。
dataset_reader

dataset_iterator
数据迭代器,从dataset_reader中获得数据,然后按batch抽取数据,供后面的模型训练使用。
dataset_iterator

chainer
配置文件的核心,将数据预处理、模型选优和模型预测输出,通过pipeline("pipe"字段内进行约束)的形式串联起来。

"chainer": {
"in": [
  "x"
],
"in_y": [
  "y"
],
"pipe": [
  {
    "id": "classes_vocab",
    "class_name": "simple_vocab",
    "fit_on": [
      "y"
    ],
    "save_path": "{MODELS_PATH}/classifiers/{PROJECT_NAME}_{MODEL_NAME}/classes.dict",
    "load_path": "{MODELS_PATH}/classifiers/{PROJECT_NAME}_{MODEL_NAME}/classes.dict",
    "in": "y",
    "out": "y_ids"
  },
  {
    "in": "x",
    "out": "x_tok",
    "id": "my_tokenizer",
    "class_name": "char_tokenizer",
    "tokenizer": "char_tokenizer"
  },
  {
    "in": "x_tok",
    "out": "x_ids",
    "id": "seq_to_emb_ids",
    "class_name": "seq_to_emb_ids",
    "emb_file_path":"{EMBED_PATH}",
    "text_size":250
  },
  {
    "in": "y_ids",
    "out": "y_onehot",
    "class_name": "one_hotter",
    "id": "my_one_hotter",
    "single_vector": true,
    "depth": "#classes_vocab.len"
  },
  {
    "in": [
      "x_ids"
    ],
    "fit_on_batch_preprocess": [
      "x_ids",
      "y_onehot"
    ],
    "out": [
      "y_pred_probas"
    ],
    "main": true,
    "class_name": "keras_classifier_model",
    "graph_metrics": "multilabel_f1",
    "save_path": "{MODELS_PATH}/classifiers/{PROJECT_NAME}_{MODEL_NAME}/model",
    "load_path": "{MODELS_PATH}/classifiers/{PROJECT_NAME}_{MODEL_NAME}/model",
    "n_classes": "#classes_vocab.len",
    "train_emb": false,
    "kernel_sizes_cnn": [
      1,
      2,
      3,
      4,
      5
    ],
    "filters_cnn": 512,
    "optimizer": "Adam",
    "learning_rate": 0.001,
    "learning_rate_decay": 0.9,
    "loss": "categorical_crossentropy",
    "embedding_matrix": "#seq_to_emb_ids.matrix",
    "text_size": 250,
    "last_layer_activation": "softmax",
    "coef_reg_cnn": 0.0,
    "coef_reg_den": 0.0,
    "dropout_rate": 0.5,
    "dense_size": 30,
    "model_name": "cnn_model"
  },
  {
    "in": "y_pred_probas",
    "out": "y_pred_ids",
    "class_name": "proba2labels",
    "max_proba": true
  },
  {
    "in": "y_pred_ids",
    "out": "y_pred_onehot",
    "ref": "my_one_hotter"
  },
  {
    "in": "y_pred_ids",
    "out": "y_pred_labels",
    "ref": "classes_vocab"
  }
],
"out": [
  "y_pred_ids",
  "y_pred_onehot",
  "y_pred_labels",
  "y_pred_probas"
]
},

官方文档中,将“pipe”字段内的每一对花括号({})中的内容成为一个component(注意这里的component和上面提到的框架component是不同的。为了方便区分,我们将"pipe"中的component标识为pipe-component)。
train
模型训练、模型选优和评测配置。

"train": {
"epochs": 10,
"batch_size": 256,
"metrics": [
  {
    "name": "cal_confusion_matrix",
    "inputs": [
      "y",
      "y_pred_labels"
    ]
  },
  {
    "name": "f1_micro",
    "inputs": [
      "y",
      "y_pred_labels"
    ]
  },
  {
    "name": "recall_micro",
    "inputs": [
      "y_ids",
      "y_pred_ids"
    ]
  },
  {
    "name": "precision_micro",
    "inputs": [
      "y_onehot",
      "y_pred_onehot"
    ]
  },
  {
    "name": "f1_macro",
    "inputs": [
      "y_onehot",
      "y_pred_onehot"
    ]
  },
  {
    "name": "precision_macro",
    "inputs": [
      "y",
      "y_pred_labels"
    ]
  },
  {
    "name": "recall_macro",
    "inputs": [
      "y_ids",
      "y_pred_ids"
    ]
  },
  {
    "name": "recall_group",
    "inputs": [
      "y_onehot",
      "y_pred_onehot"
    ]
  },
  {
    "name": "precision_group",
    "inputs": [
      "y",
      "y_pred_labels"
    ]
  },
  {
    "name": "f1_group",
    "inputs": [
      "y_ids",
      "y_pred_ids"
    ]
  }
],
"validation_patience": 5,
"val_every_n_epochs": 1,
"log_every_n_epochs": 1,
"show_examples": true,
"validate_best": true,
"test_best": true,
"report_path": "{MODELS_PATH}/classifiers/{PROJECT_NAME}_{MODEL_NAME}/report.xlsx"
},

其中,
"metric"字段中排在最前面的指标,作为模型选优的标准。
metadata
相关相关的常量配置。

metadata

其中,"imports"是DeepPavlov框架之外自定义实现。

DeepPavlov存在的问题

环境依赖
DeepPavlov是基于TensorFlow和Keras实现的,不能继承其他计算框架的模型实现(如PyTorch)。
语言支持
Pre-train模型和评测数据集主要基于英文和俄文,不支持中文。
生产环境部署
DeepPavlov在运行时需要依赖整个框架源码,开发环境对框架修改后,生产环境需要更新整个框架。同时,也不能直接将功能Component作为服务独立导出,不适合在生产环境的部署和发布。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容