天天看點

什麼是我所說的ConversationalRobot?

作者:段清華

個人首頁:http://qhduan.com

Github連結: https://github.com/qhduan/

原文連結,點選文末閱讀全文直達:https://github.com/qhduan/ConversationalRobotDesign

這篇文章包括 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

什麼是我所說的ConversationalRobot?

從人機互動的角度看ConversationalRobot

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

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

從機器人的角度來看Conversational Robot

什麼是我所說的ConversationalRobot?

從機器人的角度來看ConversationalRobot

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

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

内部元件,從Dialogue System的主要骨架說起

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

什麼是我所說的ConversationalRobot?

Principal components of a spoken dialog system

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

一個更簡單的圖例如:

什麼是我所說的ConversationalRobot?

Traditional Pipeline for Task-oriented Systems

(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)

什麼是我所說的ConversationalRobot?

The principal dialogue acts used by the HIS System

關于這個清單的詳細意義與探讨,會在後續的章節進行。

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

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

假設我們問“愛因斯坦出生于哪一年?”

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

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

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

複制

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

我們獲得了潛在的答案類型,和潛在包含答案的資料條目。我們再從中搜尋我們的答案。

這個方法的方法與條件:

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

Knowledge-based (KB QA)

當然也可以說語義網、知識圖譜等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 的實作,我們後續張章節會讨論。