Conversational UI / Conversational Robot 雜談

草稿,我的原文在 qhduan/ConversationalRobotDesign 看看能不能找到有興趣的人,作者微信:longinusd

題圖來自 Free Image on Pixabay - Beautiful, Fashion, Dark, Woman

什麼是我所說的 Conversational Robot

包括 Dialogue System, QA System, Chatbot 簡述。 下面大部分文字是整體的介紹,當然要完全把這三個部分都詳細說完,可能就夠一本書了,沒幾百篇論文的閱讀出不來。 主要是因為每個系統的每個實現方法經常都是獨立的一個領域,而很少有介紹完整成品的東西,也幾乎沒有完整的書籍。

Conversational Robot 的來歷

主要是為了避免dialogue和chat這兩個詞。

Dialogue System 和 Chatbot 都有其比較特定的含義,這裡避開他們。 然後使用了 Conversational 這個詞。

簡單的來說

我所定義的

Conversational Robot = Dialogue System + QA System + Chabot + Other Needed Support Components

其中Dialogue System是骨架,其他部分是血肉

其實單獨來說,每個系統都可以獨立存在。 例如一般的百科全書,如果不嚴格的討論,我們可以認為它是一個QA System。 它本身是很有用的,也可以獨立存在。

甚至說Chatbot本身,如果應用在心理輔導、嬰幼兒陪伴等領域,也可以單獨的作為一個應用。

而我之所以把Dialogue System作為主要部分,主要是因為我認為機器人存在的目標最主要是完成任務,我認為傳統意義上的Dialogue System,本質就是一個Task-Oriented System。這符合我對於 Robot 的哲學理解,即執行任務是第一要務。

從人機交互的角度看Conversational Robot

人與機器有很多交互方式,而語音、語言交互是一項重要的交互方式。

自然語言理解(NLP)包括了語音識別,語音合成,文本理解,文本生成等等範疇,可以說從人機交互的角度來說,Conversational Robot 在這裡特指語言的理解、生成這一過程的相關部件。

從機器人的角度來看Conversational Robot

從機器人的角度來講,一個智能體(Intelligent Agent),從外界環境接受信息,這個信息主要的一個信息來源就是人。 而人能提供例如語音(說話),語言(微信打字),視頻(機器視覺),動作(動作、手勢識別)等信息。

Conversational Robot 特指接受語言,或者經過轉換的語音數據,根據對文本的理解,產生一些執行操作。 執行操作可以由其他部件完成。最終把執行結果返回給人的這一個過程的相關部件。

內部組件,從Dialogue System的主要骨架說起

一個傳統的Dialogue System如下圖所示

(Jason D. Williams, The Dialog State Tracking Challenge Series: A Review, 2016)

一個更簡單的圖例如:

(Hongshen Chen, A Survey on Dialogue Systems:Recent Advances and New Frontiers, 2017)

語音識別(ASR)

圖中ASR負責識別語音,對於一條用戶的語音輸入可能有多個結果

例如不同識別到的文本和對應的可信度

例如用戶說(注意是語音):「我要去上海」

結果可能是

[

{

"sentence": "我要去上海",

"score": 0.4

},

{

"sentence": "我要去商海",

"score": 0.3

},

{

"sentence": "我要去傷害",

"score": 0.1

}

]

實際上很多關於對話系統的文章都沒有仔細說這部分,這也是顯而易見的,因為語音識別有更專門的領域專家去研究。絕大部分系統的假設都是能拿到比較準確的識別結果,至少是像上面那樣的的結果列表,之後的工作。類似的,圖中的TTS也是一般被忽略。

自然語言理解(NLU or SLU or LU)

這部分在有些資料被稱為SLU(Spoken Language Understanding), 有的資料也稱為NLU(Natual Language Understanding),甚至LU(Language Understanding)。 也有一些文獻稱之為Semantic Decoding,因為它的結果也被稱為Semantic Frame, 也就是把用戶輸入的句子(utterance)轉換為了一種Semantic Frame,即抽象出了用戶所期望行為的語義。

這部分主要根據語音輸入的結果,判斷用戶意圖。

從含義角度來說,輸出的是,三個部分內容:

SLOT(S): 問題所需要的數據參數

INTENT: 用戶意圖

DOMAIN: 問題領域

如(Yun-Nung Chen, SYNTAX OR SEMANTICS? KNOWLEDGE-GUIDED JOINT SEMANTIC FRAME PARSING)的例子:

W: tell vivian to be quiet

S: contact=vivian, message=be quiet

D: communication

I: send_text

也就是用戶輸入了tell vivian to be quiet之後, 或者這句話的DOMAIN(D)是communication, INTENT是send_text, 有兩個slot, 分別是聯繫人contact=vivian還有信息內容message=be quiet

這些內容會被後續的部件處理。

從一些實際應用的角度來說,這部分LU在一些系統里也被描述為會產生潛在的user-action列表。也就是「用戶想做什麼」的行為列表和每種行為的可能性

例如用戶輸入:「明天晚上的電影」,結果可能是

[

{

"user_action": "request(movie_name, date=tomorrow_night)",

"score": 0.5

},

{

"user_action": "request(movie_name, date=tomorrow)",

"score": 0.3

},

{

"user_action": "inform(date=tomorrow_night)",

"score": 0.1

}

]

這些列表可能類似下面的行為,其中Usr列打對號的就是用戶可能產生的行為列表,我們以後會在單獨的NLU相關章節詳細探討這部分內容。 (Steve Young, The Hidden Information State model: A practical framework for POMDP-based spoken dialogue management, 2010)

關於這個列表的詳細意義與探討,會在後續的章節進行。

Dialogue State Tracker & Dialogue Policy

在某些系統上,這兩部分是分離的,在而在很多系統上,實際就是一個部分。也有一些資料把這部分稱為Dialogue Management。這部分也被稱為Belief Tracking & Policy Optimization / Policy Learning。

需要狀態管理是因為對話並不僅僅是單輪的,而是需要多輪進行,或者說完成一個任務很可能需要跟用戶反覆交互。用戶很可能修改之前的意圖、提供的參數等等內容。如果對話只是一問一答,即當前問題和以前的問題、回答都沒關係的話,那實際上就不算Dialogue System,而是QA System了(Question & Answer)

系統需要保存之前用戶的問題,也要保存自己回答的結果,例如:

request的格式:request(a, b=x, c=y,...) 即請求參數a,並且提供(可選的)參數b=x等。

inform的格式:inform(a=x, b=y) 即提供信息,用戶可以向系統提供信息,系統也可以向用戶提供信息(答案或查詢結果)。

舉例如下:

用戶:我想找北京去上海的火車

-> user_action: request(車票列表, 起始地=北京, 目的地=上海)

-> sys_action: inform(車票列表=執行部件的答案, 起始地=北京, 目的地=上海)

系統回答實例:從北京去上海的車票有xx趟,如下:xxxxx

用戶:從杭州去的呢?

-> user_action: request(車票列表, 起始地=杭州)

-> sys_action: inform(車票列表=執行部件的答案, 起始地=杭州, 目的地=上海)

系統回答示例:從杭州去上海的車票有yy趟,如下:yyyyy

假設上面兩條是連續的問題,那麼系統在回答第二條的時候,用戶是沒直接提示目的地的(這裡是符合自然語言習慣的),那麼目的地這個狀態,就應該由DST部件存儲下來(相當於機器的短期記憶),在一定假設下,補全並猜測到用戶的完整意圖。

在第二次回答中,如果系統並不確定目的地是上海(例如根據某個概率值),那麼可能就會產生下面的情況:

用戶:我想找北京去上海的火車

-> user_action: request(車票列表, 起始地=北京, 目的地=上海)

-> sys_action: inform(車票列表=執行部件的答案, 起始地=北京, 目的地=上海)

系統回答實例:從北京去上海的車票有xx趟,如下:xxxxx

## 以上部分和上面的例子一樣

用戶:從杭州去的呢?

-> user_action: request(車票列表, 起始地=杭州)

-> sys_action: confirm(起始地=杭州,目的地=上海)

## confirm是確認操作,期待用戶回答諸如是/否,yes/no的回答

系統回答示例:您是說從杭州去上海的車票嗎?

用戶:是的

-> user_action: confirm()

-> sys_action: inform(車票列表=執行部件的答案, 起始地=杭州, 目的地=上海)

系統回答示例:從杭州去上海的車票有yy趟,如下:yyyyy

或者如果系統實在不確定,或者比較愚蠢,甚至可能是:

用戶:我想找北京去上海的火車

-> user_action: request(車票列表, 起始地=北京, 目的地=上海)

-> sys_action: inform(車票列表=執行部件的答案, 起始地=北京, 目的地=上海)

系統回答實例:從北京去上海的車票有xx趟,如下:xxxxx

## 以上部分和上面的例子一樣

用戶:從杭州去的呢?

-> user_action: request(車票列表, 起始地=杭州)

-> sys_action: request(目的地=上海)

## 上面最後一行代表,機器也可以向用戶請求信息

系統回答示例:請告訴我目的地是哪裡?

用戶:是上海

-> user_action: inform(目的地=上海)

-> sys_action: inform(車票列表=執行部件的答案, 起始地=杭州, 目的地=上海)

系統回答示例:從杭州去上海的車票有yy趟,如下:yyyyy

這些不同的操作,最終都成功引導到了結果。當然理論上第一次最好,因為用戶操作最少,但是如果ASR部件、NLU部件甚至DST部件產生了錯誤(例如聽錯了、理解錯誤、管理失誤等等),那麼是有可能產生後兩次的對話。

所以DST和DP部件,主要是管理歷史狀態,並且根據狀態生成一個sys_action,系統所要應對的行為。

自然語言生成 NLG

自然語言生成部件的主要目的是根據系統的相應類型,生成自然語言回答。

一般來說這部分主要是套模板。

當然現在也有一些使用如seq2seq模型等等產生的NLG方法。這些方法的出現一來是為了提高系統的魯棒性,另一方面是希望系統說話更接近人類說話方式,最終提高用戶體驗。

語音合成 TTS

這部分是指從文字到語音合成的部分,並不在我所定義的Conversational Robot的範疇內。絕大部分Dialogue System或其他相關文獻也都會忽略,因為模塊本身可以獨立運作,並且有比較成熟的解決方案。

問答系統 QA System

這裡簡單探討QA系統的幾種形式

問答匹配 Question & Answer Selection/Matching/Searching

假設我們有一堆問答對(q_1, a_1, q_2, a_2, ..., q_n, a_n)

如果這個時候新來了一個問題,最樸素的想法就是去這些問答對裡面搜索,找到答案(假設有的話)。

問題是,問題本身的形式可能多種多樣,例如:

  • 你從哪來?
  • 你哪來的?
  • 你從哪裡來?
  • 你來自哪裡?

這些問題本身都代表一樣的含義,或者說他們有相似的語義(Semantic)。

那麼問題來了,如何確定答案?

假設我們有一個函數f(x, y),當兩個問題相似的時候f(q_1, q_2)趨近於1,當兩個問題不相似的時候f(q_1, q_3)趨近於0。

那麼用戶只要輸入一個新問題q_user,那麼我們只要從資料庫裡面計算argmax{q_i} f(q_i, q_user)就好了。也就是從資料庫中找到與問題q_user最相似的問題。

當然還有另一種類似的做法,假設一個函數g(x, y),當一個問題q和答案a是一對的時候(也就是a是q的正確答案),那麼g(q, a)趨近於1,如果不是一對,則趨近於0。

當用戶來了新問題q_user,那麼我們只要遍歷資料庫裡面的所有答案尋找argmax{a_i} g(q_user, a_i),則可以找到,最符合用戶問題的答案

當然實際應用的時候,我們不可能真的遍歷資料庫的所有問題(可能有幾百萬條數據,時間性能不允許),這個時候我們可以通過其他手段。

例如我們有一個函數vec(x),它可以把一個問題或者答案轉換成一個有限長度的實數向量。然後我們還有一個函數similarity(x, y),用來判斷兩個向量是否相似。那麼當用戶來了一個問題q_user的時候,我們可以先把它向量化得到vec(q_user),然後再去匹配我們已經預先向量化好的其他問題。 即argmax{vec(q_i)} similarity(vec(q_user), vec(q_i))

因為向量相似匹配的演算法,可能遠快於遍歷所有問題(或答案)。(例如用K-neighbour相關演算法如BallTree等)

用深度學習解決此類問題的論文比較多,例如:

(Ming Tan, LSTM-BASED DEEPLEARNING MODELS FOR NON-FACTOID ANSWER SELECTION, 2016)

IR-based

利用搜索引擎,或者類似搜索引擎的技術

假設我們問「愛因斯坦出生於哪一年?」

然後把這個問題直接丟給搜索引擎,或者經過某種轉換到某個形式(例如把問題修改為文本「愛因斯坦 出生 年份」)

假設去搜索,第一條結果可能如下:

阿爾伯特·愛因斯坦- 維基百科,自由的百科全書

zh.wikipedia.org/zh-han阿爾伯特·愛因斯坦

阿爾伯特·愛因斯坦,或譯亞伯特·愛因斯坦(德語:Albert Einstein,1879年3月14日-1955年4月18日),猶太裔理論物理學家,創立了現代物理學的兩大支柱之一的相對論 :274,也是質能等價公式(E = mc2)的發現者。他在科學哲學領域頗具影響力。因為「對理論物理的貢獻,特別是發現了光電效應的原理」,他榮獲1921年諾貝爾物理學獎 ...

而我們根據問題可以判斷用戶的意圖是希望結果是「哪一年」,也就是問題答案很可能是(18xx年, 19xx年, 18xx-xx-xx, 19xx-xx-xx)之類的形式。

我們獲得了潛在的答案類型,和潛在包含答案的數據條目。我們再從中搜索我們的答案。

這個方法的方法與條件:

  • 答案比較短(一個詞或一個短語)的時候
  • 把問題轉換為可能更容易搜索到答案的形式
  • 猜測用戶所希望的答案類型(是人?地點?時間?其他?)

Knowledge-based

當然也可以說語義網、知識圖譜等based

這個角度解決QA問題首先我們需要有一堆資料庫,常見使用三元組(triples)的形式保存,例如:

  • (愛因斯坦,出生於,1879)
  • (愛因斯坦,職業,物理學家)
  • (愛因斯坦,死於,1955)
  • (中國,首都,北京)
  • (美國,首都,華盛頓)

類似這樣,一般來說三元組中間那是一個關係(relation),而兩邊是兩個實體(entity),我們也可以寫作出生於(愛因斯坦,1879),出生於(這篇文章的作者,2020),類似這樣的形式

假設我們有很多這樣的三元組數據,那麼我們解決:「愛因斯坦出生在哪年」這樣的問題方法,是把問題轉換為一種邏輯形式,例如:

愛因斯坦出生在哪年 => 出生於(愛因斯坦, ?x)

中國的首都 => 首都(中國, ?y)

其中出生於和首都都是關係,而中國和愛因斯坦都是實體,而?x和?y都是自由變數,這裡代指我們想要尋求的答案。

從這個角度解決QA問題有一套比較完整的方法論,如RDF,Semantic Web,SPARQL等技術和方法

也有一些文獻使用了結合deep learning與sequence-to-sequence等技術的的Knowledge-based解決方案,具體內容我們後續會討論。

Chatbot

這裡Chatbot特指中文的閑聊機器人

閑聊機器人是帶有一定「娛樂」意味的機器人。當然也可以用作例如心理輔導,心理幫助,嬰幼兒教育,兒童陪伴等等內容。

這部分就不是完成一個任務,不是需要答案,而更多的是陪伴、娛樂、放鬆。一個Chatbot最簡單的成功指標就是,本質是鼓勵用戶多和Chatbot交流,用戶使用時長和用戶下次繼續使用的意願,如果用戶願意一直陪著Chatbot聊天,那就成功了。

一般來說Chatbot只有兩種技術,template-based和neural-based

template-based

也就是根據模板來選擇回答

最簡單的模板例如:

用戶:你喜歡 * 嗎?

系統:我喜歡 * 啊,你喜歡嗎?

系統:我喜歡 * 啊,你還喜歡什麼別的嗎?

用戶:你吃過 * 嗎?

系統:我是機器人,不吃 *

系統:* 好吃嗎?你告訴我唄

用戶:你覺得 * 怎麼樣?

系統:這取決於你對 * 的理解,我不好回答啊

系統:我覺得 * 還不錯吧,你怎麼看?

可以看出,上面模板的*可以代指很多東西

當然實際應用上,模板可能比上面複雜的多,可以解決更多問題,設置算術題,計算,遞歸等等

這方面比較完整的研究是AIML語言,即 Artificial Intelligence Markup Language 語言。

是一種XML格式的標記語言,這部分方法也曾經是試圖解決圖靈測試的主力研究方法。

更多內容可以參考:

Wikipedia AIML

AIML tutorial

neural-based

是以神經機器翻譯模型為參考,用來生成對話的模型。即基於深度學習的 sequence-to-sequence 模型(或變種),來生成對話。

這類模型直接訓練對話,得到端到端的結果。訓練數據大部分來自於電影字幕、社交媒體,或者其他已有的對話數據。

這方便比較前沿的研究如

(Jiwei Li, Adversarial Learning for Neural Dialogue Generation, 2017)

(Jiwei Li, Deep Reinforcement Learning for Dialogue Generation, 2016)

更多 Template-based 和 Neural-Based 的實現,我們後續張章節會討論。


推薦閱讀:

如何設計聊天機器人用戶界面
【學術】針對多輪對話理解和信息轉移的端對端記憶網路
直播預告:基於動態詞表的對話生成研究 | PaperWeekly x 微軟亞洲研究院
Chatbot專題閱讀小組 | 每周一起讀 #08

TAG:深度學習DeepLearning | 機器學習 | chatbot |