zoukankan      html  css  js  c++  java
  • 基于百度理解与交互技术实现机器问答

    总目录地址:AI 系列 总目录 

    需要最新源码,或技术提问,请加QQ群:538327407

    我的各种github 开源项目和代码:https://github.com/linbin524

    一、前言

    我们都知道现在聊天对话机器是一个很有意思的东西,比如说苹果siri,比如说微软的小冰。

    聊天对话机器的应用场景也很广泛,比如说:银行的自助办卡机器人、展会讲解解说等等。

    我们对机器人说句话,机器人从听取,到语义识别,认知转换,到最后调出我们所想要的东西,这个过程看似简单,其实内藏许多黑科技,让我们来一一解析一下。

    1、我们对机器人说句话:我想看一下今天的天气?

    技术实现:不论是语音、文字,机器首先要采集到我们的问题,语音还需要语音转换的一个过程,且内容转换结果必须准确,否则就有点像不同语言体系的人在对话,有种鸡同鸭讲的感觉,结果肯定也是一个大坑了。

    2、语义识别

    技术实现:通常这个阶段,已经将内容转换为一段文字,程序会对文字进行分词,结合关键字截取拼接语义(这里需要AI的训练)

    3、认知转换

    技术实现:上述的那就话中,今天是个关键词,天气是个关键词,  在训练库中需要提炼词槽,将可能语句尽可能提供给机器人

    4、调用结果

    当认知转换完成后,需要对关键词进行规则判断,比如说, 想看 + 今天+ 天气,组成时候,自动调用查询天气接口

    上述的结果,更多需要我们对机器人进行训练,让它学习,要不然结果肯定不是那么友好的。

    二、技术需求

    通过文字输入问题,动态理解转化,识别内容,进行机器解答和语音提示。

    PS:上述的需求基本可以理解为你叫机器人做一件事,机器人领悟,按照你的要求执行。

    进阶:可以采用语音输入,转换为文字,之后的序列一样。(需要阵列麦克风)

    三、技术选型

    1、采用C# winform 作为程序主题

    2、采用win7 TTS 作为语音朗读功能

    3、采用百度理解交互技术 UNIT 作为识别基础

     本篇的重点在于如何对机器UNIT 进行配置与训练(机器识别会理解错误,需要进行纠错),最后的winform 只是调用结果显示,不作为重点关注。

    四、实现

    1、新建winform 窗体

    2、添加TTS,引用System.Speech

    3、进行 语音朗读测试

    SpeechSynthesizer voice = new SpeechSynthesizer(); //创建语音实例
    voice.Rate = 2; //设置语速,[-10,10]
    voice.Volume = 100; //设置音量,[0,100]
    voice.SpeakAsync(“您好!”); //播放指定的字符串,这是异步朗读

    PS:有些win7 系统TTS 有问题,需要自己百度查找,下载TTS 进行安装。目前上述支持中文,输入英文,只会念字母,因为需要朗读类别做转换,详细请百度speech 操作。

     4、结合百度理解与交互技术

    百度提供的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);  //播放指定的字符串,这是异步朗读
              
    
            }
        }
    }

    结果展示

    评价

    理解和交互需要做大量的对话样本和语言交互纠错,才可以实现相对比较精准的回答。

  • 相关阅读:
    Hermite插值是牛顿插值的极限情形
    An introduction to numerical analysis theorem 6.3 :Hermite Interpolation Theorem
    matrix theory_basic results and techniques_exercise_1.2.10
    Hermite插值是牛顿插值的极限情形
    用带余除法可以解决一切部分分式的题目
    matrix theory_basic results and techniques_exercise_1.2.10
    详解物联网Modbus通讯协议
    手把手带你做LiteOS的树莓派移植
    在Vue中使用JSX,很easy的
    解读鸿蒙轻内核的监控器:异常钩子函数
  • 原文地址:https://www.cnblogs.com/linbin524/p/8136799.html
Copyright © 2011-2022 走看看