基于百度理解与交互技术实现机器问答
一、前言
我們都知道現(xiàn)在聊天對(duì)話機(jī)器是一個(gè)很有意思的東西,比如說(shuō)蘋果siri,比如說(shuō)微軟的小冰。
聊天對(duì)話機(jī)器的應(yīng)用場(chǎng)景也很廣泛,比如說(shuō):銀行的自助辦卡機(jī)器人、展會(huì)講解解說(shuō)等等。
?
我們對(duì)機(jī)器人說(shuō)句話,機(jī)器人從聽(tīng)取,到語(yǔ)義識(shí)別,認(rèn)知轉(zhuǎn)換,到最后調(diào)出我們所想要的東西,這個(gè)過(guò)程看似簡(jiǎn)單,其實(shí)內(nèi)藏許多黑科技,讓我們來(lái)一一解析一下。
?
1、我們對(duì)機(jī)器人說(shuō)句話:我想看一下今天的天氣?
技術(shù)實(shí)現(xiàn):不論是語(yǔ)音、文字,機(jī)器首先要采集到我們的問(wèn)題,語(yǔ)音還需要語(yǔ)音轉(zhuǎn)換的一個(gè)過(guò)程,且內(nèi)容轉(zhuǎn)換結(jié)果必須準(zhǔn)確,否則就有點(diǎn)像不同語(yǔ)言體系的人在對(duì)話,有種雞同鴨講的感覺(jué),結(jié)果肯定也是一個(gè)大坑了。
?
2、語(yǔ)義識(shí)別
技術(shù)實(shí)現(xiàn):通常這個(gè)階段,已經(jīng)將內(nèi)容轉(zhuǎn)換為一段文字,程序會(huì)對(duì)文字進(jìn)行分詞,結(jié)合關(guān)鍵字截取拼接語(yǔ)義(這里需要AI的訓(xùn)練)
3、認(rèn)知轉(zhuǎn)換
技術(shù)實(shí)現(xiàn):上述的那就話中,今天是個(gè)關(guān)鍵詞,天氣是個(gè)關(guān)鍵詞,? 在訓(xùn)練庫(kù)中需要提煉詞槽,將可能語(yǔ)句盡可能提供給機(jī)器人
?
4、調(diào)用結(jié)果
當(dāng)認(rèn)知轉(zhuǎn)換完成后,需要對(duì)關(guān)鍵詞進(jìn)行規(guī)則判斷,比如說(shuō), 想看 + 今天+ 天氣,組成時(shí)候,自動(dòng)調(diào)用查詢天氣接口
?
上述的結(jié)果,更多需要我們對(duì)機(jī)器人進(jìn)行訓(xùn)練,讓它學(xué)習(xí),要不然結(jié)果肯定不是那么友好的。?
?
二、技術(shù)需求
?
通過(guò)文字輸入問(wèn)題,動(dòng)態(tài)理解轉(zhuǎn)化,識(shí)別內(nèi)容,進(jìn)行機(jī)器解答和語(yǔ)音提示。
PS:上述的需求基本可以理解為你叫機(jī)器人做一件事,機(jī)器人領(lǐng)悟,按照你的要求執(zhí)行。
進(jìn)階:可以采用語(yǔ)音輸入,轉(zhuǎn)換為文字,之后的序列一樣。(需要陣列麥克風(fēng))
三、技術(shù)選型
1、采用C# winform 作為程序主題
2、采用win7 TTS 作為語(yǔ)音朗讀功能
3、采用百度理解交互技術(shù) UNIT 作為識(shí)別基礎(chǔ)
?本篇的重點(diǎn)在于如何對(duì)機(jī)器UNIT 進(jìn)行配置與訓(xùn)練(機(jī)器識(shí)別會(huì)理解錯(cuò)誤,需要進(jìn)行糾錯(cuò)),最后的winform 只是調(diào)用結(jié)果顯示,不作為重點(diǎn)關(guān)注。
四、實(shí)現(xiàn)
1、新建winform 窗體
?
?
2、添加TTS,引用System.Speech
?
?
3、進(jìn)行 語(yǔ)音朗讀測(cè)試
?
SpeechSynthesizer voice = new SpeechSynthesizer(); //創(chuàng)建語(yǔ)音實(shí)例
? ? ? ? ? ?voice.Rate = 2; //設(shè)置語(yǔ)速,[-10,10]
? ? ? ? ? ?voice.Volume = 100; //設(shè)置音量,[0,100]
? ? ? ? ? ?voice.SpeakAsync(“您好!”); ?//播放指定的字符串,這是異步朗讀
?
PS:有些win7 系統(tǒng)TTS 有問(wèn)題,需要自己百度查找,下載TTS 進(jìn)行安裝。目前上述支持中文,輸入英文,只會(huì)念字母,因?yàn)樾枰首x類別做轉(zhuǎn)換,詳細(xì)請(qǐng)百度speech 操作。
?
?
?4、結(jié)合百度理解與交互技術(shù)
?
百度提供的sdk 目前只支持android 和IOS,但有提供http API,所以筆者采用C#實(shí)現(xiàn)了。
先去官網(wǎng)注冊(cè)成為百度開發(fā)者。
?
(1) 創(chuàng)建應(yīng)用
?
?(2) 創(chuàng)建場(chǎng)景,場(chǎng)景編號(hào)是后面需要用到的
?
?
(3)新建單元,官方提供對(duì)話單元和問(wèn)答單元,我們選擇創(chuàng)建對(duì)話單元
?
?
?
(4)、對(duì)對(duì)話單元進(jìn)行配置,新建詞藻
?
?
?
?
新建詞藻
?詞藻詞典有自定義的,也有系統(tǒng)的,本文中選擇系統(tǒng)通用的。也可以下載自定義模板,寫入自己的自定義詞典
?
?
這個(gè)對(duì)話單元中,有文本回復(fù)和執(zhí)行函數(shù),我們這里選文本回復(fù)
觸發(fā)的規(guī)則:會(huì)話規(guī)則中,上述的詞藻已填充,那么文本內(nèi)容才會(huì)出現(xiàn)
?
?
保存完成,后再次新建對(duì)話單元,主要說(shuō)明介紹我們的公司
?
?
?
?
?
?跳轉(zhuǎn)到數(shù)據(jù)中心,進(jìn)行新建對(duì)話樣本
?
?
?
?
?添加
?
?依法將公司介紹關(guān)鍵詞添加
?
來(lái)的訓(xùn)練與驗(yàn)證板塊
輸入打開菜單,一開始輸入,可能得到錯(cuò)誤答案,你要 @UNIT 糾正意圖與詞槽,手動(dòng)將關(guān)鍵詞和意圖、取詞、詞藻匹配上
?
?
?完成后的結(jié)果:
?
(1)、
配置基本參數(shù)
/// <summary>
? ? /// 理解與交互技術(shù)UNIT?
? ? /// </summary>
? ? public class ConfigUnit
? ? {
? ? ? ? /// <summary>
? ? ? ? /// Api key
? ? ? ? /// </summary>
? ? ? ? public static String clientId = "";
? ? ? ? // 百度云中開通對(duì)應(yīng)服務(wù)應(yīng)用的 Secret Key
? ? ? ? public static String clientSecret = "";
? ? ? ? //場(chǎng)景Id
? ? ? ? public static string clientSceneId = "";
? ? }
部分解析實(shí)體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 還沒(méi)補(bǔ)充完整
? ? /// </summary>
? ? public class UnitSchema {
? ? }
}
錯(cuò)誤信息定義
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 = "服務(wù)器內(nèi)部錯(cuò)誤,請(qǐng)?jiān)俅握?qǐng)求, 如果持續(xù)出現(xiàn)此類錯(cuò)誤,請(qǐng)通過(guò)QQ群(224994340)聯(lián)系技術(shù)支持團(tuán)隊(duì)。"; break;
? ? ? ? ? ? ? ? case "2": errorDecrition = "服務(wù)暫不可用,請(qǐng)?jiān)俅握?qǐng)求, 如果持續(xù)出現(xiàn)此類錯(cuò)誤,請(qǐng)通過(guò)QQ群(224994340)或工單聯(lián)系技術(shù)支持團(tuán)隊(duì)。"; break;
? ? ? ? ? ? ? ? case "3": errorDecrition = "調(diào)用的API不存在,請(qǐng)檢查后重新嘗試。"; break;
? ? ? ? ? ? ? ? case "4": errorDecrition = "集群超限額。"; break;
? ? ? ? ? ? ? ? case "6": errorDecrition = "無(wú)權(quán)限訪問(wèn)該用戶數(shù)據(jù)。"; break;
? ? ? ? ? ? ? ? case "14": errorDecrition = "IAM鑒權(quán)失敗,建議用戶參照文檔自查生成sign的方式是否正確,或換用控制臺(tái)中ak sk的方式調(diào)用。"; break;
? ? ? ? ? ? ? ? case "17": errorDecrition = "每天請(qǐng)求量超限額。"; break;
? ? ? ? ? ? ? ? case "18": errorDecrition = "QPS超限額。"; break;
? ? ? ? ? ? ? ? case "19": errorDecrition = "請(qǐng)求總量超限額。"; break;
? ? ? ? ? ? ? ? case "100": errorDecrition = "無(wú)效的access_token參數(shù),請(qǐng)檢查后重新嘗試。"; break;
? ? ? ? ? ? ? ? case "110": errorDecrition = "access token無(wú)效。"; break;
? ? ? ? ? ? ? ? case "111": errorDecrition = "access token過(guò)期。"; break;
? ? ? ? ? ? ? ? case "282004": errorDecrition = "請(qǐng)求參數(shù)格式不正確。"; break;
? ? ? ? ? ? ? ? case "282900": errorDecrition = "必傳字段為空。"; break;
? ? ? ? ? ? ? ? case "282901":
? ? ? ? ? ? ? ? ? ? errorDecrition = "場(chǎng)景ID校驗(yàn)失敗,請(qǐng)確認(rèn)console中app和場(chǎng)景是否關(guān)聯(lián)了:https://console.bce.baidu.com/ai/#/ai/unit/app/list。"; break;
? ? ? ? ? ? ? ? case "282902":
? ? ? ? ? ? ? ? ? ? errorDecrition = "UNIT環(huán)境啟動(dòng)中,請(qǐng)稍后再試;如果持續(xù)出現(xiàn)此類錯(cuò)誤,請(qǐng)通過(guò)QQ群(224994340)聯(lián)系技術(shù)支持團(tuán)隊(duì)。"; break;
? ? ? ? ? ? ? ? case "282903":
? ? ? ? ? ? ? ? ? ? errorDecrition = "UNIT系統(tǒng)異常;如果持續(xù)出現(xiàn)此類錯(cuò)誤,請(qǐng)通過(guò)QQ群(224994340)聯(lián)系技術(shù)支持團(tuán)隊(duì)。"; break;
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? case "282000": errorDecrition = "服務(wù)器內(nèi)部錯(cuò)誤,如果您使用的是高精度接口,報(bào)這個(gè)錯(cuò)誤碼的原因可能是您上傳的圖片中文字過(guò)多,識(shí)別超時(shí)導(dǎo)致的,建議您對(duì)圖片進(jìn)行切割后再識(shí)別,其他情況請(qǐng)?jiān)俅握?qǐng)求, 如果持續(xù)出現(xiàn)此類錯(cuò)誤,請(qǐng)通過(guò)QQ群(631977213)或工單聯(lián)系技術(shù)支持團(tuán)隊(duì)。"; break;
? ? ? ? ? ? ?
? ? ? ? ? ? ? ? default: errorDecrition = "未知的錯(cuò)誤!"; 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對(duì)話接口
? ? ? ? public static UnitModel Unit_Utterance(string token, string sceneId, string query)
? ? ? ? {
? ? ? ? ? ? UnitModel result = new UnitModel();
? ? ? ? ? ? #region 基礎(chǔ)校驗(yàn)
? ? ? ? ? ? string error = "";
? ? ? ? ? ? if (string.IsNullOrWhiteSpace(token))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? error += "token不能為空!";
? ? ? ? ? ? }
? ? ? ? ? ? if (string.IsNullOrWhiteSpace(sceneId))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? error += "場(chǎng)景編號(hào)不能為空!";
? ? ? ? ? ? }
? ? ? ? ? ? if (string.IsNullOrWhiteSpace(query))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? error += "詢問(wèn)問(wèn)題不能為空!";
? ? ? ? ? ? }
? ? ? ? ? ? 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;
? ? ? ? }
? ? }
}
首先用單元測(cè)試結(jié)果:
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);
? ? ? ? ? ? ??
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
確定接口沒(méi)有問(wèn)題,結(jié)合到我們的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("請(qǐng)你輸入你要說(shuō)的話!");
? ? ? ? ? ? ? ? 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(); ? //創(chuàng)建語(yǔ)音實(shí)例
? ? ? ? ? ? voice.Rate = 2; //設(shè)置語(yǔ)速,[-10,10]
? ? ? ? ? ? voice.Volume = 100; //設(shè)置音量,[0,100]
? ? ? ? ? ?
? ? ? ? ? ? voice.SpeakAsync(result.returnSay); ?//播放指定的字符串,這是異步朗讀
? ? ? ? ??
? ? ? ? }
? ? }
}
結(jié)果展示
?
?
評(píng)價(jià)
理解和交互需要做大量的對(duì)話樣本和語(yǔ)言交互糾錯(cuò),才可以實(shí)現(xiàn)相對(duì)比較精準(zhǔn)的回答。
相關(guān)文章:
基于Accord.Audio和百度語(yǔ)言識(shí)別
認(rèn)識(shí)微軟Visual Studio Tools for AI
基于Emgu CV+百度人臉識(shí)別,實(shí)現(xiàn)視頻動(dòng)態(tài) 人臉抓取與識(shí)別
百度OCR文字識(shí)別-身份證識(shí)別
微軟人工智能和對(duì)話平臺(tái)--知識(shí)商城體驗(yàn)
原文地址:http://www.cnblogs.com/linbin524/p/8136799.html
.NET社區(qū)新聞,深度好文,歡迎訪問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的基于百度理解与交互技术实现机器问答的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Git 企业开发者教程
- 下一篇: 利用VSTS跟Kubernetes整合进