實戰 | 讓機器人替你聊天,還不被人看出破綻?來,手把手教你訓練一個克隆版的你

如何使用深度學習模型訓練聊天機器人用咱們所但願的方式在社交媒體上進行對話。AI時代,電腦的另外一端真的多是個聊天機器人node

編譯 | AI科技大本營(rgznai100)python

參與 | 史天git


聊天機器人究竟是什麼呢?說白了,就是計算機程序經過聽覺或文本方法進行對話。github

當今最流行的四個對話機器人是:蘋果的Siri、微軟Cortana、谷歌助理、亞馬遜的Alexa。他們可以幫你查比分、打電話,固然,偶爾他們也會出錯。web

本文,咱們主要會詳細介紹聊天機器人在文本方面的運做。express

在這篇文章中,咱們將看到如何使用深度學習模型訓練聊天機器人用咱們所但願的方式在社交媒體上進行對話。ubuntu

意圖&深度學習

如何訓練一個高水平的聊天機器人呢?服務器

高水平的工做聊天機器人是應當對任何給定的消息給予最佳反饋。這種「最好」的反應應該知足如下要求:網絡

  • 回答對方問題session

  • 反饋相關信息

  • 問後續問題或用現實方法繼續對話

這三個方面是機器人表現出來的內容,而隱含其中沒有表現出來的則是一系列流程:理解發送者的意圖,肯定反饋信息的類型(問一個後續問題,或者直接反應等),並遵循正確的語法和詞法規則。

請注意,「意圖」二字相當重要。只有明確意圖,才能保證在後續流程的順利進行。對於「意圖」,讀者經過本篇文章,將會看到,深度學習是最有效的解決「意圖」問題的方法之一。

深度學習的方法

聊天機器人使用的深度學習模型幾乎都是 Seq2Seq。2014年,Ilya Sutskever, Oriol Vinyals, and Quoc Le 發表了《Sequence to Sequence Learning with Neural Networks》一文。摘要顯示,儘管機器翻譯已經作的很好,但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、Google Hangouts、SMS、Linkedin、Twitter、Tinder和Slack 等着與人們保持聯繫。

Facebook:這是大部分培訓數據的來源。facebook有一個很酷的功能,讓你能夠下載你全部的Facebook數據。包含全部的信息、照片、歷史信息。

Hangouts:您能夠根據這個文章的指示來提取聊天數據

https://blog.jay2k1.com/2014/11/10/how-to-export-and-backup-your-google-hangouts-chat-history/

SMS:能夠快速得到全部以前的聊天記錄(sms備份+是一個不錯的應用程序),但我不多使用短信。

Linkedin:Linkedin確實提供了一種工具,能夠在這裏獲取數據的歸檔。

https://www.linkedin.com/start/join?session_redirect=https%3A%2F%2Fwww.linkedin.com%2Fpsettings%2Fmember-data

Twitter:這其中沒有足夠的私人信息。

Tinder:這其中的對話不是數據集。

Slack:個人Slack剛剛開始使用,只有幾個私有消息,計劃手動複製。

建立數據集

數據集的建立是機器學習的一個重要組成部分,它涉及到數據集預處理。這些源數據存檔格式不一樣,而且包含咱們不須要的部分(例如,fb數據的圖片部分)。

正如您所看到的,Hangouts數據的格式與facebook數據有一點不一樣,而linkedin的消息以csv格式進行。咱們的目標是使用全部這些數據集來建立一個統一的文件,命名爲(FRIENDS_MESSAGE,YOUR_RESPONSE)

爲了作到這一點,我編寫了一個python腳本,能夠在這裏查看

https://github.com/adeshpande3/Facebook-Messenger-Bot/blob/master/createDataset.py

此腳本將建立兩個不一樣的文件。其中一個是Numpy對象(conversationDictionary.npy)包含全部輸入輸出對。另外一個是一個大的txt文件(conversationData.txt)包含這些輸入輸出對的句子形式,一個對應一個。一般,我喜歡共享數據集,可是對於這個特定的數據集,我會保持私有,由於它有大量的私人對話。這是最後一個數據集的快照。

詞向量

LOL,WTF,這些都是在咱們的會話數據文件中常常出現的全部單詞。雖然它們在社交媒體領域很常見,但它們並非在不少傳統的數據集中。一般狀況下,我在接近NLP任務時的第一個直覺是簡單地使用預先訓練的向量,由於它們能在大型主體上進行大量迭代的訓練。

然而,因爲咱們有這麼多的單詞和縮寫,而不是在典型的預先訓練的單詞向量列表中,所以,生成咱們本身的單詞向量對於確保單詞正確表達是相當重要的。

爲了生成單詞向量,咱們使用了word2vec模型的經典方法。其基本思想是,經過觀察句子中單詞出現的上下文,該模型會建立單詞向量。在向量空間中,具備類似上下文的單詞將被置於緊密的位置。關於如何建立和訓練word2vec模型的更詳細的概述,請查看個人一個好友Varma羅漢的博客。

https://github.com/adeshpande3/Facebook-Messenger-Bot/blob/master/Word2Vec.py

*更新:我後來瞭解到TensorFlow Seq2Seq函數從零開始對單詞embeddings進行訓練,所以我不會使用這些單詞向量,儘管它們仍然是很好的實踐*

用TensorFlow建立Seq2Seq模型

如今咱們建立了數據集並生成了咱們的單詞向量,咱們就能夠繼續編碼Seq2Seq模型了。我在python腳本中建立和訓練了模型

https://github.com/adeshpande3/Facebook-Messenger-Bot/blob/master/Seq2Seq.py

我試着對代碼進行評論,但願你能跟着一塊兒。該模型的關鍵在於TensorFlow的嵌入_RNN_seq2seq()函數。你能夠在這裏找到文檔。

https://www.tensorflow.org/tutorials/seq2seq

跟蹤培訓進展

這個項目的一個有趣的地方是,能看到網絡訓練時,響應是如何發生變化的。訓練迴路中,我在輸入字符串上測試了網絡,並輸出了全部非pad和非eos口令。

首先,您能夠看到,響應主要是空白,由於網絡重複輸出填充和eos口令。這是正常的,由於填充口令是整個數據集中最多見的口令。

而後,您能夠看到,網絡開始輸出「哈哈」的每個輸入字符串。

這在直覺上是有道理的,由於「哈哈」常常被使用,它是對任何事情均可以接受的反應。慢慢地,你開始看到更完整的思想和語法結構在反應中出現。如今,若是咱們有一個通過適當訓練的Seq2Seq模型,那麼就能夠創建facebook messenger 聊天機器人

如何創建一個簡單的fb messenger 聊天機器人

這個過程並非太難,由於我花了不到30分鐘的時間來完成全部步驟。基本的想法是,咱們使用簡單的express應用程序創建了一個服務器,在Heroku上安裝它,而後設置一個facebook頁面鏈接。但最終,你應該有一個相似這樣的 Facebook 聊天應用程序。

您能夠向您的聊天機器人發送消息(這種初始行爲只是響應它所發送的全部內容)。

部署訓練有素的TensorFlow模型

如今是時候把一切都放在一塊兒了。因爲tensorflow和node之間尚未找到一個很好的接口(不知道是否有一個官方支持的包裝器),因此我決定使用slack服務器部署個人模型,並讓聊天機器人的表達與它進行交互。您能夠在這裏查看slack服務器代碼

https://github.com/adeshpande3/Chatbot-Flask-Server

以及聊天機器人的index.js文件

https://github.com/adeshpande3/Facebook-Messenger-Bot/blob/master/index.js

測試它!

若是你想和這個機器人聊天,那就繼續點擊這個連接

https://www.messenger.com/

或者點擊facebook頁面,發送消息

https://www.facebook.com/Adits-FB-Chatbot-822517037906771/

第一次響應可能須要一段時間,由於服務器須要啓動。

也許很難判斷機器人是否真的像我那樣說話(由於沒有不少人在網上和我聊天),可是它作的很好!考慮到社會媒體標準,語法是能夠經過的。你能夠選擇一些好的結果,但大多數都是至關荒謬的。這能幫助我在晚上睡得更好的,畢竟不能在任什麼時候間用skynet。

我認爲第一個是特別有趣的,由於「juju green」實際上彷佛是一種 Juju Smith-Schuster,鋼人隊寬接收器,和 Draymond Green,前鋒金州勇士。有趣的組合。

雖然如今的表現還不太好。讓咱們來考慮一下改善它的方法吧!

改進方法

從與chatbot的交互中能夠看到的改進方法,有很大的改進空間。通過幾條信息後,很快就會明白,不只僅是進行持續的對話就好了。chabtot不可以把思想聯繫在一塊兒,而一些反應彷佛是隨機的、不連貫的。下面是一些能夠提升咱們聊天機器人性能的方法。

  • 合併其餘數據集,以幫助網絡從更大的會話語料庫中學習。這將消除聊天機器人的「我的特性」,由於它如今已經被嚴格訓練了。然而,我相信這將有助於產生更現實的對話。

  • 處理編碼器消息與解碼器消息無關的場景。例如,當一個對話結束時,你次日就開始一個新的對話。談話的話題可能徹底無關。這可能會影響模型的訓練。

  • 使用雙向LSTMs,注意機制和套接。

  • 優化超參數,如LSTM單元的數量、LSTM層的數量、優化器的選擇、訓練迭代次數等。

你如何創建像你同樣的聊天機器人- 流程回顧

若是你一直在跟進,你應該對建立一個聊天機器人所須要的東西已經有了一個大體的概念。讓咱們再看一遍最後的步驟。在GitHub repo 中有詳細的說明。

https://github.com/adeshpande3/Facebook-Messenger-Bot/blob/master/README.md

  1. 找到全部你與某人交談過的社交媒體網站,並下載你的數據副本。

  2. 從CreateDataset中提取全部(消息、響應)對py或您本身的腳本。

  3. (可選)經過Word2Vec.py爲每個在咱們的對話中出現的單詞 生成單詞向量。

  4. 在Seq2Seq.py中建立、訓練和保存序列模型。

  5. 建立Facebook聊天機器人。

  6. 建立一個Flask服務器,在其中部署保存的Seq2Seq模型。

  7. 編輯索引文件,並與Flask服務器通訊。

最後給你們貢獻一些可供查閱的資源:

相關論文

  • Sequence to Sequence Learning

  • https://arxiv.org/pdf/1409.3215.pdf

  • Seq2Seq with Attention

  • https://arxiv.org/pdf/1409.0473.pdf

  • Neural Conversational Model

  • https://arxiv.org/pdf/1506.05869.pdf

  • Generative Hierarchical Models

  • https://arxiv.org/pdf/1507.04808.pdf

  • Persona Based Model

  • https://arxiv.org/pdf/1603.06155.pdf

  • Deep RL for Dialogue Generation

  • https://arxiv.org/pdf/1606.01541.pdf

  • Attention with Intention

  • https://arxiv.org/pdf/1510.08565.pdf

  • Diversity Promoting Objective Functions

  • https://arxiv.org/pdf/1510.03055.pdf

  • Copying Mechanisms in Seq2Seq

  • https://arxiv.org/pdf/1603.06393.pdf

其餘有用的文章

  • Seq2Seq的優秀博文

  • http://suriyadeepan.github.io/2016-06-28-easy-seq2seq/

  • 斯坦福大課程PPT

  • http://web.stanford.edu/class/cs20si/lectures/slides_13.pdf

  • Tensorflow Seq2Seq

  • https://www.tensorflow.org/tutorials/seq2seq

  • 使用Tensorflow Seq2Seq函數的視頻教程

  • https://www.youtube.com/watch?v=ElmBrKyMXxs

相關文章
相關標籤/搜索