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