本专栏暂未更新完,特惠59.90元,更新完以后将恢复原价
专栏目录
- (一)项目概述
- (二)什么是自然语言理解
- (三)意图识别:规则模式
- (四)意图识别:神经网络-问题分析篇
- (五)意图识别:神经网络-代码实现篇
- (六)关键信息抽取:规则模式
- (七)关键信息抽取:jieba提取
- (八)关键信息抽取:神经网络
- (九)自然语言理解模块实现
- (十)服务调用分发
- (十一)MQTT服务搭建
- 更新中
上一篇智能家居助手(三)-意图识别:规则模式中,讲述了基于规则的意图识别,以案例入手,实现开灯、关灯和查新闻的意图识别,本章节将通过神经网络的方式进行意图识别,为了快速入手,本章节只进行开灯和关灯的意图识别,毕竟一个精简的案例,才更容易理解(其实是本人懒,标注不完那么多的数据)
想象你要开发一个机器人,它有两个功能,开灯和关灯,这个时候你们之间的对话可能是这样的:
开始如你期待,结局却不尽人意!
为什么会这样呢?
是因为我们在设计的时候就只给他定义了两个意图,当有其他意图输入的时候,机器只能从设计好的意图中选择一个进行输出,这种缺陷和模型训练无关,仅仅只是因为问题的梳理不够透彻,在此也想说明的是:一个能用的产品(都不敢说好的产品)的设计和需求梳理,重要到就好像一个人的基因,先天的不足需要花费千万倍的努力去弥补,而这个成本对于项目来说可以亏到连裤衩都不剩,遗憾的是好多人好像没明白这个问题,一上来就是开干,最后就是没有结局的加班改需求以及Bug!
回到本文中,我们的功能简单到只需要开灯和关灯两个意图,为了能应对如上问题,可以考虑加一个意图:其他,当识别到非开灯和关灯的意图时,让机器人有一个其他意图,避免机器人胡乱开关灯,至于识别到这个意图时,机器人该回答什么呢,可以选择不回答,或者闲聊或者其他的
到此确定了本文要识别的意图有三个:
为了能让神经网络能识别开灯、关灯和其他,首先得告诉它什么叫开灯,什么叫关灯吧!
这个时候就需要我们构建数据集,让神经网络从数据集中学习(至于神经网络为什么能学习,本文不做介绍,感兴趣的童鞋可以先看看相关资料,后期本人也会出一篇为什么能学习的博客)
1、开灯的数据集
打开灯==>home_turnon_light
开灯==>home_turnon_light
开下灯==>home_turnon_light
开一下灯==>home_turnon_light
帮我开一下灯==>home_turnon_light
麻烦帮我开一下灯==>home_turnon_light
麻烦帮我开一下灯,好吗==>home_turnon_light
可以帮我开一下灯,好吗==>home_turnon_light
可以帮我开一下灯吗==>home_turnon_light
...等等
/*标注的格式不重要,反正也是自己解析,自己随意*/
2、关灯的数据集
可以关灯吗==>home_turnoff_light
可以关灯吗==>home_turnoff_light
关闭客厅的灯==>home_turnoff_light
关闭客厅的开关==>home_turnoff_light
关闭卧室的灯==>home_turnoff_light
关闭卧室的开关==>home_turnoff_light
关闭厨房的灯==>home_turnoff_light
关闭厨房的开关==>home_turnoff_light
...等等
3、其他的数据集
谢谢==>others
不客气==>others
你好吗==>others
我还不错,你呢==>others
我也不错==>others
那太好了==>others
你听到新闻了吗==>others
什么新闻==>others
你最喜欢什么书==>others
我看不懂==>others
你最喜欢什么颜色==>others
...等等
需要注意的是,现实中说话并没有标准,比如我可能会说:
那个啥,额…打开客厅的灯
这种情况下,我们准备的数据集会显得过于规范,也就会造成模型很可能只认识标准话术,而无法识别现实中的口语,所以我们可以考虑给模型加一些噪声,提高模型的泛化能力,比如:
麻烦w帮我开一下灯,好吗==>home_turnon_light
可以帮,u我开一下灯,好吗==>home_turnon_light
可87以帮我开一下q灯吗==>home_turnon_light
有了数据集以后就是神经网络的搭建和学习过程了,包括
设计好流程以后先把需要实现接口方法写出来,一个模块一个模块拆解实现
class IntentModelContainer:
def __init__(self):
'''
参数初始化
'''
def load_data(self,basePath):
'''
载入数据
:param basePath: 数据集路径
:return:
'''
pass
def build_model(self):
'''
搭建网络
:return:
'''
pass
def print_f1(self,model,x_test=None,y_test=None):
'''
f1评估
:param model:
:param x_test:
:param y_test:
:return:
'''
pass
def print_acc_curve(self, history):
'''
输出训练集和验证集准确率曲线
:param history:
:return:
'''
pass
def print_loss_curve(self,history):
'''
输出训练集和验证集loss曲线
:param history:
:return:
'''
pass
if __name__=='__main__':
trainPath = r'data\train.txt'
testPath = r'data\test.txt'
# 创建模型训练实例
intent_model_container = IntentModelContainer()
# 加载数据
x,y = intent_model_container.load_data(trainPath)
x_test,y_test = intent_model_container.load_data(testPath)
# 创建模型
intent_model = intent_model_container.build_model()
# 训练
history = intent_model.fit(x,y,epochs=N,batch_size=Batch,validation_data=(x_test,y_test))
# f1评估
intent_model_container.print_f1(intent_model,x_test,y_test)
# 保存模型
tf.saved_model.save(intent_model, "intent-rec.h5")
# 损失曲线
intent_model_container.print_loss_curve(history)
# 准确率曲线
intent_model_container.print_acc_curve(history)
分析篇到这里结束,下一章开始具体实现过程