1 意图分类任务简介
对话系统里, 首先要对用户的输入进行领域, 意图识别和槽抽取. 深度学习发展以后, 意图识别的方法多使用深度学习的算法, 使用 CNN 对意图进行多分类, 领域分类和意图分类较为类似. 而槽的预测可以看成是标签序列预测问题. 例如句子 "我想听周杰伦的菊花台", 标签可以定义为 "O O O B-singer M-singer E-singer O B-song M-song E-song". 标签序列预测多使用 CRF,RNN,LSTM,LSTM+crf 的模型. 链接:
2 槽位填充
槽位填充可以理解为一个序列标注的问题, 我们训练范例{(x^((n)),y^((n)) ):n=1,......,N}, 然后我们想要识别学到一个函数 f∶x→y, 这个函数能够匹配输入序列 x 和相应的标签序列 y. 在槽位填充中, 输入序列和标签序列长度相同, 因此排列是准确的.
3 数据集 ATIS
ATIS https://www.kaggle.com/siddhadev/atis-dataset/data 数据集包含 4978 训练数据和 893 个测试数据, 文本内容为客服对话, 意图一共有 26 类. 查询话语中的每个标记与填充 IOB 标签的插槽对齐, 也就是上面图片中 Sentence 和 Slots 都是一一对齐的.
4 Pytext 实战
本部分内容主要参考官方的文档 Train Intent-Slot model on ATIS Dataset, 有些地方稍微出入.
4.1 安装
目前 Pytext 只支持 Linux 和 Mac 系统, 在命令行输入下面语句安装:
pip install pytext-nlp
4.2 文件准备
pytext https://github.com/facebookresearch/pytext 数据集 https://www.kaggle.com/siddhadev/atis-dataset/data
4.3 数据预处理
python3 demo/atis_joint_model/data_processor.py --download-folder atis/ --output-directory demo/atis_joint_model/
4.4 模型训练
pytext train < demo/atis_joint_model/atis_joint_config.JSON
在没有使用 GPU 的情况下, 训练需要 30 分钟左右
模型训练完毕时, 我们通过 atis_joint_config.JSON 看到, 结果文件和模型保存到 tmp 目录下
4.6 模型导出
保存 PyTorch 模型时, 简单的使用 pickle 进行序列化. 这意味着简单的代码更改 (例如, 单词嵌入更新) 可能导致与已部署模型的向后不兼容. 为了解决此问题, 可以使用内置的 ONNX 集成将模型导出为 Caffe2 格式. 无论 PyText 或开发代码中的更改如何, 导出的 Caffe2 模型都具有相同的行为.
在命令行中分别输入下面两行语句
CONFIG=demo/atis_joint_model/atis_joint_config.JSON
pytext export --output-path exported_model.c2 < "$CONFIG"
4.5 模型评估
我们可以使用 pytext test 来测试模型在测试集上的表现
pytext test < "$CONFIG"
4.6 模型应用
我们可以将训练的模型部署成一个 web 应用, 新建文件 flask_app.py
- import sys
- import flask
- import pytext
- config_file = sys.argv[1]
- model_file = sys.argv[2]
- config = pytext.load_config(config_file)
- predictor = pytext.create_predictor(config, model_file)
- App = flask.Flask(__name__)
- @App.route('/get_flight_info', methods=['GET', 'POST'])
- def get_flight_info():
- text = flask.request.data.decode()
- # Pass the inputs to PyText's prediction API
- result = predictor({"raw_text": text})
- # Results is a list of output blob names and their scores.
- # The blob names are different for joint models vs doc models
- # Since this tutorial is for both, let's check which one we should look at.
- doc_label_scores_prefix = (
- 'scores:' if any(r.startswith('scores:') for r in result)
- else 'doc_scores:'
- )
- # For now let's just output the top document label!
- best_doc_label = max(
- (label for label in result if label.startswith(doc_label_scores_prefix)),
- key=lambda label: result[label][0],
- # Strip the doc label prefix here
- )[len(doc_label_scores_prefix):]
- return flask.jsonify({"question": f"Are you asking about {best_doc_label}?"})
- App.run(host='0.0.0.0', port='8080', debug=True)
执行
python flask_app.py "$CONFIG" exported_model.c2
然后打开另一个 Terminal, 我们测试下服务: 测试 1
- curl http://localhost:8080/get_flight_info -H "Content-Type: text/plain" -d "I am looking for flights from San Francisco to Minneapolis"
- {
- "question": "Are you asking about flight?"
- }
测试 2
- curl http://localhost:8080/get_flight_info -H "Content-Type: text/plain" -d "How much does a trip to NY cost?"
- {
- "question": "Are you asking about airfare?"
- }
测试 3
- curl http://localhost:8080/get_flight_info -H "Content-Type: text/plain" -d "Which airport should I go to?"
- {
- "question": "Are you asking about airport?"
- }
我们可以看到, 模型将 3 次的意图都识别到了.
5 总结
其实, pytext 核心部分是针对不同任务的 config.JSON 文件, 里面定义了模型的结构, 输入, 输出等等, 另外也有网友反映, 现在文档对这一部分解释少, 对怎么添加模型的介绍也很少, 所以只能先摸索下. 本篇文章, 只是安装官方文档将训练一个模型的流程打通, 但是自己希望接下来研究下怎么添加自定义模型和训练中文语料.
我的简书 致 Great https://www.jianshu.com/u/261e23a40f71
来源: https://juejin.im/post/5c1a001df265da61263819ba