基於百度理解與交互技術實現機器問答


總目錄地址: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);  //播放指定的字符串,這是異步朗讀
          

        }
    }
}

 

結果展示

 

 

評價

理解和交互需要做大量的對話樣本和語言交互糾錯,才可以實現相對比較精准的回答。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM