当前位置:   article > 正文

“马踏飞”AI机器人实现方案介绍

马踏飞燕ai展示

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

当今互联网随处可见各种语音助手,从手机到智能音响,从机器人到手机App语音助手。随着公司业务的发展,今年我们也决定搭建自己的智能客服系统,同时结合公司自身业务,马踏飞燕App 旅游比价业务场景,同时参考了国外的一些Task Bot,我们觉得预订机票、火车票、酒店这类任务型的AI机器人可以落地,而且符合我们自身的业务特点,再结合推荐系统,以期给用户全新的使用体验。经过前期的调研,我们确定了技术类型和实现目标。

市面上的文章很多 我们主要是通过自身产品场景 介绍一些里面的工作,大家自己完成类似产品的时候,希望可以有一些借鉴的地方。‍

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

点击观看马踏飞燕818年度产品发布会

对话系统简介

640?wx_fmt=png

目前市面上对话系统大概分为三类。

第一类问答型,类似阿里小蜜、美团、去哪儿等的业务问答型助手。他们主要用来解答用户特定业务类型知识需求,比如住店须知,退款事项,活动规则解读等等。

第二种任务对话型机器人,这类的机器人能在单轮或者多轮对话之后满足用户需求或完成特定的任务。这类的对话机器人也已经很广泛了。比如各种语音助手和智能音响。马踏飞就是这种任务型的对话机器人。

第三类就是我们常说的闲聊机器人,这类机器人的回答没有标准的答案,回答方式、回复内容也可以丰富多样。大名鼎鼎的微软小冰就属于这类的。当然号称美少女的小冰可不止有这些功能,据悉第七代的小冰已经发布,大家可以使用体验一下当今最强对话机器人。

对话系统完整的交互流程

640?wx_fmt=jpeg

如图,语音对话机器人的一般流程就是这样:

首先是用户的语音被识别成文字,通过语言模型对对话进行理解,实际上这里是做了一些意图识别、实体标注、情感分类等工作。对话管理作为整个机器人动作控制核心部分,控制着机器人如何应答,它是直接影响着用户的使用体验的。

语言生成部分目前分为两种方式:

一种是生成式,它是直接通过模型生成机器人回复的语句。

另一种则是通过模板的形式直接生成,各自都有自己的优缺点,最后的语音合成就是将生成的文字播报出来。

技术选型

好了扯了那么多,我就来说说我们是如何实现自己的智能客服助手吧。

我们AI机器人组只有三个人, 在短时间内完成这样的一个系统并且商用化,确实有些困难。因此我们商量之后,决定聚焦在NLP方面.ASR TTS还是调用现成的云服务,在百度和科大讯飞之间,我们还是选择了科大讯飞,相关的云服务还是更加的成熟技术上,我们做了如下选择。科大讯飞的云服务在语音识别,语音播报,关键词唤醒、人物选择等功能上都做得非常好。它很好的满足了我们的产品需求。对话管理系统作为控制机器人应答的核心。我们做了如下选择,语言理解(NLU)这块,最开始的时候 我们使用的是Rasa NLU模块。即使是开源的项目,修改源代码也是一件很麻烦的事情,而且不够灵活,模型修改都不是很方便。因此我们修改了Rasa Core Interpreter,切换成了自己实现的NLU。自己实现NLU模块的时候,最开始使用的PyText框架,PyText实现涵盖了NLP工作流声明周期中的基本环节,能快速的为我们处理原始数据、指标统计、训练和部署模型,里面有现成的Multi-task Intent Classification(意图识别) and Slot Filling(槽填充), 但是还是面临着要修改PyText的麻烦, 动不动就要读源代码, 不便于模型修改。最后采用了PyTorch框架自己实现模型, 网上有很多现成的地方可以参考。

在后面优化模型的时候,加入了BERT。BERT作为2018年大力出奇迹的模型,一经推出就名声大噪,其在10项语言任务当中获得SOTA效果,实际的使用当中也是确实比其他模型的效果要好。对话管理我们选择了Rasa Core这套框架,其为我们提供比较完备的组件功能,详尽的使用文档上手也很快。不过rasa-core更新是挺快的,要用的还要做好准备。

下面详细说下DM和NLU这两个模块的细节

DM(Dialogue Management)

对话管理 我们使用的是开源的Rasa Core

640?wx_fmt=png

在rasa_core中我们有如下几个关键概念:

stories:官方在文档中称一个训练例子作为一个故事,实际就是将一个例子作为一种可能对话方式。一问一答的写出来。

domain:其对应一个domain.yml文件,文件定义了intent, slot, forms, templates, actions,entities等关键组件。

actions:官方将其定义为是对输入做出响应输出的动作,rasa提供了三种方式,第一类以utter_开头的动作,rasa会将其下的text文本发送给用户,这里可以根据自己的实际情况决定是发送文本还是发送其他内容比如操作指令。第二类是自定义的动作继承FormAction等类。第三类就是系统默认动作,有action_listen, action_restart, action_default_fallback这三个,当然我们也可以直接在stories中显式的使用该动作。

policies:顾名思义他才是决定对话的每一步里面到底执行什么操作的部分。rasa提供了很多的策略给我们使用。每种策略都有自己的优先级。我们并不需要做很多事,只需要在配置文件中指定一些参数即可。

slots:rasa将slot定义为机器人的记忆。实际就可以理解成完成一项任务需要准备的关键信息。比如当我们外卖机器人。你要点餐,那么bot需要知道你吃什么菜,你住哪,联系方式是什么,几点送,口味要求等、这些都可以是槽(slot),整个对话bot就会去询问这些信息。同时rasa也给出了丰富的slot 类型,我们可以根据情实际况将slot定义成想要的类型。

下面附上一些实现的细节

domain中

自定义的utter开头的动作

640?wx_fmt=png

继承自FormAction的action和自定义的意图

640?wx_fmt=png

640?wx_fmt=png

thankyou作为一个意图,其下的triggers指定了当用户的意图是thankyou时,bot只需要回复:不客气,小马很高兴能为您服务!

定义的slot槽,槽的类型根据情况自行定义,这些只需要参考官方doc即可明白。

640?wx_fmt=png

stories中标题自定义正文是一问一答形式,带*开头表示用户给出的信息,可以是意图和槽值,”-"开头的是bot需要做的操作,如下截图所示,inform给出了arrival_location(槽)目的地是武汉(槽值),flight_form是我们自定义action,其继承于FormAction类,这个很简单,大家只要照着官方的例子写就可以明白到底如何工作的,slot表示保存槽值的操作。这样每一轮的对话就通过我们之前定义的意图、槽值、action表示出来了。对话可长可短。笔者使用一般都是7轮左右,当然各位读者使用时还是按照自己的情况编写。rasa-core训练的时候有一个缩放因子,它使得rasa-core不需要写太多个(我实际使用20个左右即可)story也可以表现出比较好的使用效果,这个参数默认值是20倍。大家可以根据需要调整。

640?wx_fmt=png

不过需要吐槽的是当涉及多个业务时,story的例子太多之后调试起来真的挺麻烦,常常为了实现一个对话要做很多尝试,这里建议如果是指令型的对话大家还是用rasa-core提供的mapping-policy,只要在domain文件中对应的意图下指定utter开头的动作即可。

NLU(Natural Language Understanding)

NLU(自然语言理解)中我们主要做了两件事,一是识别用户意图比如订票、查询、闲聊、赞美、批评等     二是识别槽值比如购买机票需要用到的出发地、目的地、出发时间等。

NLU 采用深度学习模型,由 pytorch 实现,并针对业务进行了优化。

第一阶段采用 LSTM 模型

首先用 pkuseg 进行分词,选择更符合业务的旅游数据集模型,同时使用自定义的词典保证能正确处理一些不常用地名等。

然后用 fasttext 词向量,同时针对 OOV(Out of Vocabulary) 单词进行优化,使得能正确处理不常用地名、时间等。

然后用双向 LSTM 提取特征,双向 LSTM 能够自动提取上下文特征,不需要人工特征提取。

最后使用 max pool 和简单的神经网络来预测意图。

以及使用 CRF(Conditional Random Field) 预测槽值,CRF 能正确处理相邻单词标注之间的关系。

其它优化,利用 POS(Part of Speech) 标注,给模型更多的信息。

第二阶段将 LSTM 替换为 BERT

最开始的时候 我们使用的是常用的word vectors 自从Bert出现之后 由于其良好的性能表现,我们尝试了一下Bert, 效果确实很好。

BERT 针对英文采用 word pieces 分词,中文直接处理单字。

BERT 之后仍然使用 max pool 和简单的神经网络来预测意图,使用 CRF 预测槽值。

BERT 为当前最好的语言模型之一,BERT 在预训练时用到大量语料。使得模型可以在少量训练数据时表现良好的效果。

其它优化,减少 BERT 模型的层数,在不影响精确度的同时减少计算量。

对比使用发现预训练词向量也有不足,词向量文件通常几个 GB,内存占用过大。模型过浅,不能充分利用预训练语料信息。需要分词,如果分词错误将导致后续任务错误。

BERT 模型有效地解决了这些问题,不过 BERT 需要更大的计算量。

640?wx_fmt=gif

神经网络结构图

NLU 数据集

深度学习模型需要大量的数据及标注,NLU 模型需要标注每个句子的意图和槽(城市名、公司名、时间等)。

我们训练所用的数据来自几个方面。

1. 翻译 Atis 数据集

Atis 数据集是广为使用的意图和槽数据集,内容为机票预订等,和我们的业务相同。

不过对话为英文,所以我们首先采用现有的 API 将其翻译为中文,再花大量人工重新标注,满足我们的业务需要。

2. 模板自动生成

人工编写大量的模板,同时整理城市名、航空公司名等列表。

再将城市名、航空公司名等填入模板,得到一个完整句子,同时计算出槽的位置。

采用此方法可以生成大量数据,同时能覆盖主要的城市、航空公司等命名实体。

3. 爬虫

从问答网站爬取大量问题,筛选出和我们业务相关的问题,再人工标注,使得我们的数据集更丰富。

NLG(自然语言生成)

我们目前采用的是Rasa Core里面默认的方式,采用的是构建好的模板。通过模型生成的话,还需要尝试。

总结

系统上线有一段时间了,使用情况还算良好,不过我们也发现了一些问题,比如预设定的意图范围有限,回复单一性让人觉得并不那么智能,语音识别不完整有偏差等等。下个版本我们计划使用深度强化学习做一个任务型的对话机器人系统,引入拼写纠错功能

后续的工作

我们还是希望结合我们自身旅游 比价业务场景继续完善马踏飞:

1.给我们的马踏飞加上人物形象,通过结合计算机视觉模型,呈现出与人互动,跟一个真人客服订票一样的体验。                                                                                               

2.结合旅游知识图谱 和马踏飞聊一下景点,例如:这个季节最适合去的地方?马尔代夫现在是什么温度?

3.添加技能包等针对旅游业务:询问天气,汇率,时间。

之前我们整理过Rasa Core 部分源代码解析 希望下次可以和大家分享‍。

640?wx_fmt=png

640?wx_fmt=gif

马踏飞燕AI机器人组

640?wx_fmt=png

袁厚军

640?wx_fmt=png

刘俊

640?wx_fmt=png

殷际峰

开源技术栈

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

扫一扫,有惊喜

640?wx_fmt=png

640?wx_fmt=png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/640626
推荐阅读
相关标签
  

闽ICP备14008679号