基于百度理解与交互技术实现机器问答
一、前言
我們都知道現在聊天對話機器是一個很有意思的東西,比如說蘋果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); ?//播放指定的字符串,這是異步朗讀
? ? ? ? ??
? ? ? ? }
? ? }
}
結果展示
?
?
評價
理解和交互需要做大量的對話樣本和語言交互糾錯,才可以實現相對比較精準的回答。
相關文章:
基于Accord.Audio和百度語言識別
認識微軟Visual Studio Tools for AI
基于Emgu CV+百度人臉識別,實現視頻動態 人臉抓取與識別
百度OCR文字識別-身份證識別
微軟人工智能和對話平臺--知識商城體驗
原文地址:http://www.cnblogs.com/linbin524/p/8136799.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的基于百度理解与交互技术实现机器问答的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git 企业开发者教程
- 下一篇: 利用VSTS跟Kubernetes整合进