总目录地址:AI 系列 总目录 html
须要最新源码,或技术提问,请加QQ群:538327407android
个人各类github 开源项目和代码:https://github.com/linbin524git
1、前言github
咱们都知道如今聊天对话机器是一个颇有意思的东西,好比说苹果siri,好比说微软的小冰。json
聊天对话机器的应用场景也很普遍,好比说:银行的自助办卡机器人、展会讲解解说等等。服务器
咱们对机器人说句话,机器人从听取,到语义识别,认知转换,到最后调出咱们所想要的东西,这个过程看似简单,其实内藏许多黑科技,让咱们来一一解析一下。session
一、咱们对机器人说句话:我想看一下今天的天气?app
技术实现:不管是语音、文字,机器首先要采集到咱们的问题,语音还须要语音转换的一个过程,且内容转换结果必须准确,不然就有点像不一样语言体系的人在对话,有种鸡同鸭讲的感受,结果确定也是一个大坑了。异步
二、语义识别ide
技术实现:一般这个阶段,已经将内容转换为一段文字,程序会对文字进行分词,结合关键字截取拼接语义(这里须要AI的训练)
三、认知转换
技术实现:上述的那就话中,今天是个关键词,天气是个关键词, 在训练库中须要提炼词槽,将可能语句尽量提供给机器人
四、调用结果
当认知转换完成后,须要对关键词进行规则判断,好比说, 想看 + 今天+ 天气,组成时候,自动调用查询天气接口
上述的结果,更多须要咱们对机器人进行训练,让它学习,要否则结果确定不是那么友好的。
2、技术需求
经过文字输入问题,动态理解转化,识别内容,进行机器解答和语音提示。
PS:上述的需求基本能够理解为你叫机器人作一件事,机器人领悟,按照你的要求执行。
进阶:能够采用语音输入,转换为文字,以后的序列同样。(须要阵列麦克风)
3、技术选型
一、采用C# winform 做为程序主题
二、采用win7 TTS 做为语音朗读功能
三、采用百度理解交互技术 UNIT 做为识别基础
本篇的重点在于如何对机器UNIT 进行配置与训练(机器识别会理解错误,须要进行纠错),最后的winform 只是调用结果显示,不做为重点关注。
4、实现
一、新建winform 窗体
二、添加TTS,引用System.Speech
三、进行 语音朗读测试
SpeechSynthesizer voice = new SpeechSynthesizer(); //建立语音实例
voice.Rate = 2; //设置语速,[-10,10]
voice.Volume = 100; //设置音量,[0,100]
voice.SpeakAsync(“您好!”); //播放指定的字符串,这是异步朗读
PS:有些win7 系统TTS 有问题,须要本身百度查找,下载TTS 进行安装。目前上述支持中文,输入英文,只会念字母,由于须要朗读类别作转换,详细请百度speech 操做。
四、结合百度理解与交互技术
百度提供的sdk 目前只支持android 和IOS,但有提供http API,因此笔者采用C#实现了。
先去官网注册成为百度开发者。
(1) 建立应用
(2) 建立场景,场景编号是后面须要用到的
(3)新建单元,官方提供对话单元和问答单元,咱们选择建立对话单元
(4)、对对话单元进行配置,新建词藻
新建词藻
词藻词典有自定义的,也有系统的,本文中选择系统通用的。也能够下载自定义模板,写入本身的自定义词典
这个对话单元中,有文本回复和执行函数,咱们这里选文本回复
触发的规则:会话规则中,上述的词藻已填充,那么文本内容才会出现
保存完成,后再次新建对话单元,主要说明介绍咱们的公司
跳转到数据中心,进行新建对话样本
添加
依法将公司介绍关键词添加
来的训练与验证板块
输入打开菜单,一开始输入,可能获得错误答案,你要 @UNIT 纠正意图与词槽,手动将关键词和意图、取词、词藻匹配上
完成后的结果:
(1)、
配置基本参数
/// <summary> /// 理解与交互技术UNIT /// </summary> public class ConfigUnit { /// <summary> /// Api key /// </summary> public static String clientId = ""; // 百度云中开通对应服务应用的 Secret Key public static String clientSecret = ""; //场景Id public static string clientSceneId = ""; }
部分解析实体model
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BaiduAIAPI.Model.UnitModel { public class UnitModel { public long log_id { get; set; } public string error_code { get; set; } public string error_msg { get; set; } public UnitResult result { get; set; } public bool IsSuccess { get; set; } public string returnSay { get; set; } } public class UnitResult { public string session_id { get; set; } public List<UnitAction_list> action_list { get; set; } public object schema { get; set; } public object qu_res { get; set; } } public class UnitAction_list { public string action_id { get; set; } public object action_type { get; set; } public object arg_list { get; set; } public object code_actions { get; set; } public float confidence { get; set; } public object exe_status { get; set; } public string main_exe { get; set; } public string say { get; set; } public object hint_list { get; set; } } /// <summary> /// 其他的model 还没补充完整 /// </summary> public class UnitSchema { } }
错误信息定义
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BaiduAIAPI.Type { public class BaiduUnitType { public static string GetErrorCodeToDescription(string errorCode) { string errorDecrition = ""; switch (errorCode) { case "1": errorDecrition = "服务器内部错误,请再次请求, 若是持续出现此类错误,请经过QQ群(224994340)联系技术支持团队。"; break; case "2": errorDecrition = "服务暂不可用,请再次请求, 若是持续出现此类错误,请经过QQ群(224994340)或工单联系技术支持团队。"; break; case "3": errorDecrition = "调用的API不存在,请检查后从新尝试。"; break; case "4": errorDecrition = "集群超限额。"; break; case "6": errorDecrition = "无权限访问该用户数据。"; break; case "14": errorDecrition = "IAM鉴权失败,建议用户参照文档自查生成sign的方式是否正确,或换用控制台中ak sk的方式调用。"; break; case "17": errorDecrition = "天天请求量超限额。"; break; case "18": errorDecrition = "QPS超限额。"; break; case "19": errorDecrition = "请求总量超限额。"; break; case "100": errorDecrition = "无效的access_token参数,请检查后从新尝试。"; break; case "110": errorDecrition = "access token无效。"; break; case "111": errorDecrition = "access token过时。"; break; case "282004": errorDecrition = "请求参数格式不正确。"; break; case "282900": errorDecrition = "必传字段为空。"; break; case "282901": errorDecrition = "场景ID校验失败,请确认console中app和场景是否关联了:https://console.bce.baidu.com/ai/#/ai/unit/app/list。"; break; case "282902": errorDecrition = "UNIT环境启动中,请稍后再试;若是持续出现此类错误,请经过QQ群(224994340)联系技术支持团队。"; break; case "282903": errorDecrition = "UNIT系统异常;若是持续出现此类错误,请经过QQ群(224994340)联系技术支持团队。"; break; case "282000": errorDecrition = "服务器内部错误,若是您使用的是高精度接口,报这个错误码的缘由多是您上传的图片中文字过多,识别超时致使的,建议您对图片进行切割后再识别,其余状况请再次请求, 若是持续出现此类错误,请经过QQ群(631977213)或工单联系技术支持团队。"; break; default: errorDecrition = "未知的错误!"; break; } return errorDecrition; } } }
封装的接口方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.UI.WebControls; using AOP.Common; using BaiduAIAPI.Model.UnitModel; using BaiduAIAPI.Type; namespace BaiduAIAPI.UNIT { public class UnderstandingAndInteractiveTechnology { // unit对话接口 public static UnitModel Unit_Utterance(string token, string sceneId, string query) { UnitModel result = new UnitModel(); #region 基础校验 string error = ""; if (string.IsNullOrWhiteSpace(token)) { error += "token不能为空!"; } if (string.IsNullOrWhiteSpace(sceneId)) { error += "场景编号不能为空!"; } if (string.IsNullOrWhiteSpace(query)) { error += "询问问题不能为空!"; } if (!string.IsNullOrWhiteSpace(error)) { result.error_msg = error; return result; } #endregion string host = "https://aip.baidubce.com/rpc/2.0/solution/v1/unit_utterance?access_token=" + token; string str = "{\"scene_id\":" + sceneId + ",\"query\":\"" + query + "\", \"session_id\":\"\"}"; // json格式 var tempResult = HttpRequestHelper.Post(host, str); result=Json.ToObject<UnitModel>(tempResult); if (!string.IsNullOrWhiteSpace(result.error_code)) { result.error_msg = BaiduUnitType.GetErrorCodeToDescription(result.error_code); result.IsSuccess = false; } else { result.IsSuccess = true; result.returnSay = result.result.action_list[0].say; } return result; } } }
首先用单元测试结果:
using System; using BaiduAIAPI; using BaiduAIAPI.UNIT; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace AIAPIUnitTestProject.BaiduAIAPI { [TestClass] public class BaiduUnitTest { [TestMethod] public void TestChat() { var accessTokenModel = Access_Token.GetAccessToken(ConfigUnit.clientId, ConfigUnit.clientSecret); if (accessTokenModel.IsSuccess) { string queryString = "今每天气怎么样?"; var tempUnitResult = UnderstandingAndInteractiveTechnology.Unit_Utterance(accessTokenModel.SuccessModel.access_token, ConfigUnit.clientSceneId, queryString); } } } }
肯定接口没有问题,结合到咱们的Demo程序中,界面代码以下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Speech.Synthesis; using BaiduAIAPI; using BaiduAIAPI.UNIT; using BaiduAIAPI.Model.UnitModel; namespace SpeechDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (tb_YourSay.Text.Trim() == "") { MessageBox.Show("请你输入你要说的话!"); return; } UnitModel result = new UnitModel(); var accessTokenModel = Access_Token.GetAccessToken(ConfigUnit.clientId, ConfigUnit.clientSecret); if (accessTokenModel.IsSuccess) { string queryString = tb_YourSay.Text.Trim(); result = UnderstandingAndInteractiveTechnology.Unit_Utterance(accessTokenModel.SuccessModel.access_token, ConfigUnit.clientSceneId, queryString); } else { result.returnSay = result.error_msg; } tb_RobotSay.Text = result.returnSay; SpeechSynthesizer voice = new SpeechSynthesizer(); //建立语音实例 voice.Rate = 2; //设置语速,[-10,10] voice.Volume = 100; //设置音量,[0,100] voice.SpeakAsync(result.returnSay); //播放指定的字符串,这是异步朗读 } } }
结果展现
评价
理解和交互须要作大量的对话样本和语言交互纠错,才能够实现相对比较精准的回答。