讓機器人替你聊天,還不被人看出破綻!如何訓練一個克隆版的你?
聊天機器人到底是什么呢?說白了,就是計算機程序通過聽覺或文本方法進行對話。
當今最流行的四個對話機器人是:蘋果的Siri、微軟Cortana、谷歌助理、亞馬遜的Alexa。他們能夠幫你查比分、打電話,當然,偶爾他們也會出錯。
本文,我們主要會詳細介紹聊天機器人在文本方面的運作。
在這篇文章中,我們將看到如何使用深度學習模型訓練聊天機器人用我們所希望的方式在社交媒體上進行對話。
意圖&深度學習
如何訓練一個高水平的聊天機器人呢?
高水平的工作聊天機器人是應當對任何給定的消息給予最佳反饋。這種最好的反應應該滿足以下要求:
回答對方問題
反饋相關信息
問后續問題或用現實方法繼續對話
這三個方面是機器人表現出來的內容,而隱含其中沒有表現出來的則是一系列流程:理解發送者的意圖,確定反饋信息的類型(問一個后續問題,或者直接反應等),并遵循正確的語法和詞法規則。
請注意,意圖二字至關重要。只有明確意圖,才能保證在后續流程的順利進行。對于意圖,讀者通過本篇文章,將會看到,深度學習是最有效的解決意圖問題的方法之一。
深度學習的方法
聊天機器人使用的深度學習模型幾乎都是Seq2Seq。2014年,IlyaSutskever,OriolVinyals,andQuocLe發表了《SequencetoSequenceLearningwithNeuralNetworks》一文。摘要顯示,盡管機器翻譯已經做的很好,但Seq2Seq卻模型能更好的完成各種各樣的NLP的任務。
Seq2Seq模型由兩個主要部件組成,一個是編碼器RNN,另一個是解碼器RNN。從高層次上來說,編碼器的工作是將輸入文本信息生成固定的表示。解碼器則是接收這個表示,并生成一個可變長度的文本,以響應它。
讓我們來看看它是如何在更詳細的層次上工作的。
正如我們所熟知的,編碼器RNN包含了許多隱藏的狀態向量,它們每個都表示從上一次時間步驟中獲取的信息。例如,在第3步序中的隱藏狀態向量是前三個單詞的函數。通過這個邏輯,編碼器RNN的最終隱藏狀態向量可以被認為是對整個輸入文本的一種相當精確的表示。
而解碼器RNN負責接收編碼器的最后隱藏狀態向量,并使用它來預測輸出應答的單詞。讓我們看看第一個單元。該單元的工作是使用向量表示v,并決定其詞匯表中哪個單詞是最適合輸出響應的。從數學上講,這就意味著我們計算詞匯中的每一個單詞的概率,并選擇值的極大似然。
第二單元是向量表示v的函數,也是先前單元的輸出。LSTM的目標是估計以下條件概率。
讓我們來解構這個方程式意味著什么。
左側指的是輸出序列的概率,這取決于給定輸入序列。
右側包含p(yt|v,y1,,yt),它是所有單詞的概率向量,條件是在前一步的向量表示和輸出的情況下。其中pi等價于西格瑪(或累計求和)的乘法。則右側可降為p(Y1|V)*p(y2|v,y1)*p(Y3|v,y1,y2)
在繼續之前,讓我們先做一個簡單的例子。
讓我們在第一張圖片中輸入文本:你明天有空嗎?
大多數人都會怎么回答呢?一般都會用yes、yeah、no開始。
在我們完成了網絡訓練之后,概率p(Y1|V)將是一個類似于下面的分布。
再來看我們需要計算的第二個概率,p(y2|v,y1)表是一個函數,詞的分布y1以及向量的表示結果v,而pi將產生最終結果并作為我們的最終反應。
Seq2Seq模型的最重要特性之一是它提供的多功能性。當你想到傳統的ML方法(線性回歸,庫卡機器人驅動器維修,支持向量機)和深等深學習方法時,這些模型需要一個固定的大小輸入,并產生固定大小的輸出。
但是輸入的長度必須事先知道。這是對諸如機器翻譯、語音識別和問答等任務的一個很大的限制。這些任務我們都不知道輸入短語的大小,我們也希望能夠生成可變長度響應,而不僅僅局限于一個特定的輸出表示。而Seq2Seq模型允許這樣的靈活性!
自2014以來,Seq2Seq模型已經有了很多改進,你可以在這篇文章結尾相關論文部分中閱讀更多關于Seq2Seq的文章。
數據集的選擇
在考慮將機器學習應用于任何類型的任務時,我們需要做的第一件事都是選擇數據集,并對我們需要的模型進行訓練。對于序列模型,我們需要大量的會話日志。從高層次上講,這個編碼器-解碼器網絡需要能夠正確理解每個查詢(編碼器輸入)所期望的響應類型(解碼器輸出)。
一些常見的數據集包括:康奈爾電影對話語料庫、ubuntu語料庫和微軟的社交媒體對話語料庫。
雖然大多數人都在訓練聊天機器人來回答具體信息或提供某種服務,但我更感興趣的是更多的有趣的應用程序。有了這篇文章,我想看看我是否可以用我自己的生活中的對話日志來訓練一個Seq2Seq的模型來學習對信息的反應。
獲取數據
我們需要創建一個大量的對話數據,在我的社交媒體上,我使用了Facebook、GoogleHangouts、SMS、Linkedin、Twitter、Tinder和Slack等著與人們保持聯系。
Facebook:這是大部分培訓數據的來源。facebook有一個很酷的功能,讓你可以下載你所有的Facebook數據。包含所有的信息、照片、歷史信息。
Hangouts:您可以根據這個文章的指示來提取聊天數據
SMS:可以快速獲得所有之前的聊天記錄(sms備份+是一個不錯的應用程序),但我很少使用短信。
Linkedin:Linkedin確實提供了一種工具,可以在這里獲取數據的歸檔。
Twitter:這其中沒有足夠的私人信息。
Tinder:這其中的對話不是數據集。
Slack:我的Slack剛剛開始使用,只有幾個私有消息,庫卡機器人,計劃手動復制。
創建數據集
數據集的創建是機器學習的一個重要組成部分,它涉及到數據集預處理。這些源數據存檔格式不同,并且包含我們不需要的部分(例如,fb數據的圖片部分)。
正如您所看到的,Hangouts數據的格式與facebook數據有一點不同,而linkedin的消息以csv格式進行。我們的目標是使用所有這些數據集來創建一個統一的文件,命名為(FRIENDS_MESSAGE,YOUR_RESPONSE)
為了做到這一點,我編寫了一個python腳本,可以在這里查看。
此腳本將創建兩個不同的文件。其中一個是Numpy對象(conversationDictionary.npy)包含所有輸入輸出對。另一個是一個大的txt文件(conversationData.txt)包含這些輸入輸出對的句子形式,一個對應一個。通常,我喜歡共享數據集,但是對于這個特定的數據集,我會保持私有,因為它有大量的私人對話。這是最后一個數據集的快照。
詞向量
LOL,WTF,這些都是在我們的會話數據文件中經常出現的所有單詞。雖然它們在社交媒體領域很常見,但它們并不是在很多傳統的數據集中。通常情況下,我在接近NLP任務時的第一個直覺是簡單地使用預先訓練的向量,因為它們能在大型主體上進行大量迭代的訓練。
然而,由于我們有這么多的單詞和縮寫,而不是在典型的預先訓練的單詞向量列表中,因此,生成我們自己的單詞向量對于確保單詞正確表達是至關重要的。