科技的不斷發展帶動着人們生活品質不斷的提升,其中一方面就展現在日常家庭生活中,智能裝置層出不窮,給人們的生活帶來了很大的便利。
以電視為例,幾十年前的電視還是按鈕式的,每次換台還要跑到電視跟前;後來使用遙控器控制成為了主流,人們可以舒服的窩在沙發裡看電視;再後來随着網際網路及移動通信技術的發展,電視、機頂盒、空調等,都可以在手機上進行控制,再也不用幾個遙控器之間來回倒騰了,還不耽誤刷微網誌;近年來随着人工智能的發展,語音識别、合成技術日趨成熟,家電已經可以了解語音指令,能夠按照人類的交流方式進行人機互動了,人們隻需要動嘴說說話就可以完成各種操控。
一種智能家居的典型場景如下圖所示,以智能音箱為核心,所有裝置通過WiFi與智能音箱連接配接并可以接受智能音箱的控制指令。
人們可以和音箱打招呼,音箱能夠自然的回答問好;也可以詢問天氣,音箱能夠自動根據目前位置搜尋并回答未來一天的天氣;還可以直接對着音箱說一聲"把燈關掉",音箱應該能夠控制關掉燈,或者主動詢問"要關哪個燈",在得到明确指令後再執行指定的操作。

本文将借助微軟認知服務中的多個服務實作一個簡單的智能家居應用,來模拟一個語音控制開關燈的場景,期望能給予大家一些啟示,并期望大家可以利用更多的微軟認知服務擴充出更多炫酷實用的功能。
這一節我們看一下語音控制開關的流程是怎樣的。
從場景上來看很簡單,人直接說"開燈",燈就可以打開,當然說"請把燈打開",燈也應該能夠打開。
但是對于傳統的程式員來說,實作起來主要的難點在于如何讓程式了解人類說的話,尤其是使用者一般都是用很自然的語言去說,使用者的習慣不一樣,文法結構也不一樣。
為了解決這個難點,這裡我們将借助微軟認知服務裡的語音轉文本服務和語言了解服務來賦予程式了解人類說話的能力。
要做到這些,主要分三個步驟:
第一步,借助語音轉文本服務,将使用者的語音輸入識别成對應的文字,比如"開燈"、"請把燈打開"等等。
第二步,借助語言了解服務來将自然語言轉為程式可以了解的意圖。不管使用者是說"開燈"還是"請把燈打開",語言了解服務都可以識别出使用者的意圖是打開(TurnOn)。
第三步,按照識别出的使用者的意圖去控制燈打開或關閉。
語音轉文本服務提供将音頻流轉錄為文本的能力,微軟的語音轉文本服務采用了和微軟小娜相同的技術。應用程式借助此服務可以輕松地将聲音轉錄為文字,之後可以直接顯示或做更進一步的使用。
語音服務提供SDK和REST API兩種使用方式。使用SDK可以将服務更友善的內建到應用程式中,并且可以提供額外的功能,如實時的中間轉錄結果、靜默一段時間自動停止、轉錄超長的音頻等。目前提供的SDK有.Net、C/C++、Java版本,如果使用其它程式設計語言,可以考慮更通用的REST API方式,但是不能提供SDK中所有的功能。
語音轉文本服務的線上體驗位址是https://azure.microsoft.com/zh-cn/services/cognitive-services/speech-to-text/,可以先通過此頁面對該服務有個初步的認識。
如果裝置有麥克風,可以點選開始錄音,然後對着麥克風說話,檢視語音轉文本的效果;如果沒有麥克風,也可以點選下方的兩個示例體驗一下。
可以看到網頁在錄音的過程中,同時顯示語音轉文本的中間結果,并按照最新播放的内容不斷糾正舊文本、顯示新文本,最終給出了一個最佳的文本結果。
後面要在程式中調用語音轉文本服務,必須要有服務密鑰才可以。
試用密鑰的有效期是 30 天,每月 5000 個事務,每分鐘 20 個。每個賬号隻能申請一次試用。
申請步驟:
打開申請試用頁面:https://azure.microsoft.com/zh-cn/try/cognitive-services/?api=speech-services
找到語音服務,點選右側的擷取API密鑰
在彈出頁面點選來賓7天試用下面的開始使用(不用管這裡顯示的7天,語音服務現在還是預覽版,有30天的試用期,申請完成後顯示30天)
在服務條款頁面勾選同意,選擇國家/地區為中國,下一步
選擇要使用的賬号,筆者這裡選擇Microsoft
登入後可以看到密鑰申請成功,如下圖所示
這裡要注意圖中重點标出的部分,一個是終結點中westus,這個是目前密鑰可使用的區域,試用密鑰都是westus;另一個是下面的密鑰1和密鑰2。區域和密鑰稍後在後面程式代碼中要用到,大家可以單獨記下來或者保持該網頁不要關閉,友善後續使用。
上面30天的試用密鑰過期後如果想繼續免費使用該服務,還可以到Azure門戶中申請密鑰,前提是首先要有Azure賬戶。
如果還沒有Azure賬戶,可以免費注冊一個。打開免費注冊頁面,https://azure.microsoft.com/zh-cn/free/ai/,點選免費開始,然後按提示一步步補充完整注冊資訊。注冊過程中需要驗證手機号及信用卡,而且會看到1美元的預付款,不過不用擔心,這1美元隻是用來驗證信用卡是否可用,會在幾天後返還。
有了Azure賬戶後,打開Azure門戶網站,https://portal.azure.com/,點選建立資源,搜尋找到Speech(預覽),按提示一步步建立,就可以得到對應的密鑰。
語言了解服務,Language Understanding Intelligence Service,簡稱LUIS。後面文中使用LUIS來代替語言了解服務。
LUIS提供線上的API服務,可以将使用者輸入的自然語言描述的文本,轉換成為計算機能夠直接使用的結構化的資訊,這樣應用程式就可以借助LUIS了解人類自然語言的輸入。
LUIS的線上體驗場景是https://azure.microsoft.com/zh-cn/services/cognitive-services/language-understanding-intelligent-service/。
打開網頁後,可以看到如下圖所示的示例。可以選擇一條指令來觀察燈光的變化,也可以通過輸入自定的指令文本來控制燈光,可以試試自己習慣的文法,看能否正确的控制燈光變化。
在使用LUIS的過程中,我們最初會接觸到app這個詞,這裡的app是指LUIS應用程式。一個LUIS應用程式其實對應的就是一個語言了解模型。通常情況下,一個LUIS應用程式(即一個模型),是用來解決一個特定域(主題)内的語言了解問題的。
舉個例子,對于旅行相關的主題,如預訂機票、酒店等,可以建立一個LUIS應用程式,而對于購物相關的主題,如搜尋商品、下單,可以再建立另外一個LUIS應用程式。
意圖(Intent),表示使用者想要執行的任務或操作。比如詢問天氣、預訂機票等,都是意圖,在控制開關燈的例子中,開燈和關燈就是意圖。
實體(Entity),想當于上面意圖中的參數。比如對象、時間、地點等,都可以标記為實體。舉個例子,幫我預定明天北京飛往西雅圖的飛機,這裡用到了三個實體:明天、北京、西雅圖,分别表示了時間、始發地、目的地三個參數。
另外,實體在不同的意圖之間是可以共享的。舉個例子,明天天氣怎麼樣,這個語句的意圖是詢問天氣,而明天是其中的一個實體,表示時間參數,和上一個例子中的實體是一樣的。
語句(Utterance),是LUIS應用需要處理的使用者的輸入。在訓練時提供的語句應該是盡可能包含不同的說話方式或不同的文法的,這樣訓練出來的結果會更好一些。
LUIS提供一些預先建構好的域、實體及意圖,覆寫了比較全的場景。一種常見的做法是添加預建構的内容,然後疊代完成自定義的模型。
我們這裡的示範的場景比較簡單,直接動手從頭定制一個語音控制開關燈需要用到的LUIS應用程式。
打開LUIS網站https://www.luis.ai,并登入對應的微軟賬号。
如果是第一次登入,網站還會請求通路對應賬号的一些資訊,點Yes繼續。網站首次加載較慢,需要耐心等待,必要的時候可以重新整理重新再次加載。
如果頁面跳轉到了歡迎頁面https://www.luis.ai/welcome,可以翻到頁面最下方,點選Create LUIS app,然後在下一個頁面補充缺失的資訊,将Country設為China,并勾選I agree條款,然後點選Continue。
直到看到My Apps頁面,才算登入完成,如下圖所示
點選Create new app,建立一個新的LUIS應用。注意,Culture要選擇Chinese,Name随意,這裡使用LightControl。然後點選Done完成建立。
建立完LUIS應用程式後會直接進入Intents頁面,也可以通過點選左側的Intents進入。然後點Create new intent建立一個新的意圖。
在彈出窗中輸入意圖的名稱,這裡使用TurnOn表示開燈的意圖,完成後點選Done。注意這裡意圖的名稱在後面程式中會用到,拼寫及大小寫要保持前後一緻。
完成後會進入TurnOn意圖的設定頁面,可以在輸入框中輸入不同的語句,然後回車就可添加到語句清單中。這裡添加了4條語句:打開、開燈、請開燈、把燈打開。
點選左側Intents回到意圖頁面,然後重複上面的步驟,添加TurnOff意圖表示關燈,并添加4條語句:關閉、關燈、請關燈、關閉燈泡。
意圖是必需的,而實體不是必需的。可以根據具體的場景來決定是否添加實體,比如有需要控制客廳燈和卧室燈兩個燈,應該定義個實體來标記房間是客廳還是卧室,而不是使用多個意圖分别控制不同的燈。
LUIS支援多種類型的實體來應對各種複雜的情況,包括簡單實體、清單實體、正規表達式、複合實體等,這裡不詳細展開,有興趣的可以參考https://docs.microsoft.com/zh-cn/azure/cognitive-services/luis/luis-concept-entity-types裡的介紹。
在我們下面的例子中隻控制一個燈,這裡就不添加實體了。
添加完意圖和實體後就可以訓練了,可以看到右上角有個帶紅點的Train按鈕,點選就可以直接訓練。訓練速度非常快,幾秒種之後看到紅點變成綠點就表示訓練完成了。
點選右上角的Test,會滑出Test側邊欄,在輸入框中輸入測試語句并回車,可以看到對應的意圖及得分。這裡使用的測試語句是請幫我把燈打開,可以看到識别到的意圖是TurnOn,得分是0.86,意圖正确且比較接近1,結果還不錯。
點選頂部的PUBLISH進入釋出頁面,在頁面中點選Publish按鈕就直接釋出了。釋出成功後可以看到右側的版本号及釋出時間。
将頁面翻到底部可以找到服務釋出後的區域、密鑰和終結點。
要注意這裡的終結點是以q=結尾的,需要在終結點的最後拼上要測試的語句,比如請幫我把燈打開,得到一個完整的連結,然後再從浏覽器裡打開,就可以看到識别後的結果。
識别結果是以JSON格式傳回的,其中topScoringIntent是最比對的意圖,我們後面要用到。
LUIS應用在釋出後可以繼續改進資料,添加新語句或意圖或實體,然後再訓練,再釋出。在這樣的周期中反複疊代,最終達到最佳的效果。
在上一步釋出的終結點最後拼上一個新的語句"北京天氣怎麼樣",然後在浏覽器進行測試,可以發現最終topScoringIntent是TurnOff,這顯然是不對的,而且得分隻有0.14,和其它幾個意圖的得分差不多。
我們需要對模型改進一下,再進行一次疊代。回到LUIS的意圖頁面,我們可以看到這裡有一個None意圖,這是建立完LUIS應用程式後自帶的一個意圖,可以直接打開該意圖的頁面,在其中添加一條語句無關語句,比如"北京天氣怎麼樣"。
還一種做法是通過審查終結點上得到的語句來改進模型。點選左側的Review endpoint utterances,進入審查頁面,可以看到我們剛才在終結點上查詢的語句,我們可以把"北京天氣怎麼樣"右側的Aligned Intent改為None,然後點選右側的對勾,此時,該語句就會被自動加到了None意圖中。
然後再次訓練、釋出,再使用之前的終結點查詢"北京天氣怎麼樣",可以看到結果正确,topScoringIntent是None意圖。
Tips:最佳實踐是None意圖中語句的數量應占總語句數量的10%~20%。
點選SETTINGS進入應用程式設定頁面就可以看到Application ID,某些情況下會用到。
如果要在程式中調用LUIS服務,必須要有密鑰。LUIS 中有兩種密鑰:創作密鑰和終結點密鑰。
創作密鑰是在首次登入LUIS時自動配置設定的,終結點密鑰是在Azure門戶申請的。終結點密鑰不是必需的,可以在下面的示例中繼續使用創作密鑰。但是創作密鑰的免費配額要比終結點密鑰低得多,是以還是建議在LUIS應用程式釋出後,申請一個終結點密鑰并配置設定給LUIS應用程式供外部調用。
創作密鑰是在登入LUIS時自動建立的免費密鑰,建立的多個LUIS應用程式使用同一個密鑰,且每月隻能調用1千次。
創作密鑰的值可以在User settings中找到,點選右上賬戶名出現下拉菜單,再點選Settings,就可以看到創作密鑰:
也可以在釋出頁面的終結點處看到創作密鑰:
終結點密鑰是在Azure門戶中申請的密鑰,申請的免費密鑰的配額是月1萬次調用,每秒最多5次調用,遠大于創作密鑰的配額。
終結點密鑰的申請方法和前面介紹的在Azure門戶中申請語音服務密鑰的方法類似,在建立資源時搜尋LUIS即可找到Language Understanding服務,按步驟建立個免費密鑰即可。
這裡我們換一種申請方式,在Visual Studio中借助Tools for AI來申請密鑰。
確定已安裝Visual Studio 2017并安裝了Tools for AI擴充。
如果沒有安裝,請參考AI應用開發實戰 - 從零開始配置環境中Windows下開發環境搭建的第1節安裝VS和第5節安裝Tools for AI插件。
確定Visual Studio中登入了對應的微軟賬号。
如果沒有登入,可以在Visual Studio的右上角看到登入按鈕,點選後按步驟登入。
確定可以看到Azure訂閱
在視圖菜單中,選擇Cloud Explorer,如下圖點選賬戶管理,確定可以刷出你的訂閱,如果沒有刷出,請嘗試重新開機Visual Studio并稍後再試。
建立認知服務
在視圖菜單中,選擇伺服器資料總管,找到AI工具,在Azure認知服務上點右鍵,建立新認知服務。
選擇已有的訂閱,新申請的賬戶通常會有個名為免費試用的訂閱。選擇一個已有的資源組,如果沒有資源組,需要在Azure上先建立一個。API類型選擇LUIS。服務名可以随便起,這裡使用LUIS。位置可以先東亞,East Asia。定價申請免費的,直接選F0。點選确定來建立。
建立成功後可以在Azure認知服務下看到名為LUIS的服務,右鍵選擇管理密鑰,就可以看到申請的密鑰1和密鑰2。新申請的密鑰需要幾分鐘的部署時,之後才可以使用。
新申請的終結點密鑰需要配置設定到LUIS應用程式中才可以使用對應的終結點進行查詢。
回到LUIS的釋出頁面,翻到最下面的Resources and Keys,切換到Asia Regions,點選Add Key按鈕。
在彈出的Assign a key to your app對話框中,依次選擇剛才使用的訂閱和建立的密鑰,點選Add Key按鈕。
可以看到Resoures and Keys中Asia Regions下出現了終結點密鑰和使用該密鑰的終結點位址。
程式的源代碼在https://github.com/MS-UAP/LightControl,将源代碼下載下傳到本地後,用Visual Studio 2017打開解決方案檔案src\LightControl.sln。
在解決方案資料總管中找到Form1.cs,輕按兩下打開對應的設計界面,如下圖所示。
左側是一個圖檔控件,可以顯示燈打開時和關閉時的圖檔,來模拟真實的開關燈操作。在解決方案資料總管中可以看到LightOn.png和LightOff.png兩張圖檔,用來顯示燈處在不同的狀态下。
右側是一個文本框,用來顯示一些日志,比如語音轉文本過程中的中間結果、最終結果以及識别出的意圖等資訊。通過日志,我們可以看到語音服務和LUIS是否已正常連接配接并正常工作,如果出現異常,也會在這裡顯示異常資訊,友善對問題進行排查。
在Form窗體上點右鍵,檢視代碼,打開該窗體的代碼頁面。
首先,在構造函數中,控件初始化完成後,讓圖檔控件顯示一張關閉着的燈的圖檔:
然後,封裝要用到的一些界面操作,例如,在右側文本框中追加日志輸出,模拟打開燈,關閉燈等:
這個代碼示例中,我們用語音服務SDK來處理音頻轉文本,用語言了解服務SDK來提取文本中的意圖。
首先添加SDK的引用。切換到解決方案資料總管,在LightControl下的引用上點右鍵,選擇管理NuGet程式包。
在打開的NuGet包管理器中,依次搜尋并安裝下面3個引用:
Microsoft.CognitiveServices.Speech
Newtonsoft.Json
Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime
然後回到Form1.cs的代碼編輯頁面,引用命名空間
然後配置兩個服務用到的密鑰、區域及終結點
本文前面申請到的語音服務的30天試用密鑰是6d04e77c6c6f4a02a9cf942f6419ffaf,區域是westus。前面定制的LUIS應用程式的ID是130e348f-d131-41d1-96b2-a29d42cc1d96,密鑰這裡示例先用創作者密鑰58c57e08c8d540a4aa2196588eb69f8a,終結點字元串比較長,但是LUIS SDK中隻需配置到域名即可,不需要後面的路徑,是以這裡的終結點是https://westus.api.cognitive.microsoft.com
然後初始化SDK
添加成員變量語音識别器和意圖預測器,并在Form1_Load函數中初始化,挂載對應的事件處理函數。
Tips:Form1_Load函數需通過在Form窗體設計界面直接輕按兩下窗體的标題欄來添加。
然後補充完整幾個事件處理函數
語音轉文本時會不斷的接收到中間結果,這裡把中間結果輸出到日志視窗中
識别出現錯誤的時候,也把錯誤資訊輸出到日志視窗
靜默幾秒後,SDK會認為語音結束,此時傳回語音轉文本的最終結果。這裡拿到結果後,在日志視窗中顯示最終結果,并進一步處理文本結果
添加處理文本的函數,這裡從文本中擷取意圖,然後根據意圖的值,來執行開燈或關燈操作
然後,添加對LUIS SDK的調用,可以從文本中擷取意圖
編譯運作,并對着麥克風說出指令,就可以看到對應的效果了。同時我們可以看到語音轉文本的中間結果在不斷變化,說明服務端會根據後續接收到的音頻不斷進行調整,最終傳回一個最佳的結果。
本文通過介紹語音轉文本服務及語言了解服務,并将兩個服務內建在一個程式中完成了個模拟的智能家居應用。
回頭看一下我們的場景非常簡單,這裡提出一些改進作為習題供大家練習:
現在隻能控制一個燈,可以考慮控制更多的燈,客廳燈,卧室燈,等等,可以考慮在LUIS中增加實體來實作這個目标。
如果每次開燈或關燈時,智能家居都可以用人類的語音回報給人"燈已打開"、"已經把燈關上了",這樣的話可以得到更好的體驗。微軟認知服務也提供了文本轉語音的服務,在不久的将來還會支援開發者定義自己的語音字型,可以定制自己喜歡的聲音,使得使用者的體驗更好。
實作了多個燈的控制及語音回報以後,還可以考慮讓智能家居應用支援多輪對話。比如,當人說開燈的時候,智能家居可以詢問"要打開哪裡的燈",并按照後續補充的指令打開對應的燈。
當然還可以舉出更多的場景使得智能家居更完美,大家可以充分種用微軟提供的認知服務,考慮并設計自己的智能家居應用。