如何使用深度學習模型訓練聊天機器人用咱們所但願的方式在社交媒體上進行對話。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的任務。
正如咱們所熟知的,編碼器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)將是一個相似於下面的分佈。
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數據的圖片部分)。
爲了作到這一點,我編寫了一個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
跟蹤培訓進展
首先,您能夠看到,響應主要是空白,由於網絡重複輸出填充和eos口令。這是正常的,由於填充口令是整個數據集中最多見的口令。
而後,您能夠看到,網絡開始輸出「哈哈」的每個輸入字符串。
這在直覺上是有道理的,由於「哈哈」常常被使用,它是對任何事情均可以接受的反應。慢慢地,你開始看到更完整的思想和語法結構在反應中出現。如今,若是咱們有一個通過適當訓練的Seq2Seq模型,那麼就能夠創建facebook messenger 聊天機器人
如何創建一個簡單的fb messenger 聊天機器人
這個過程並非太難,由於我花了不到30分鐘的時間來完成全部步驟。基本的想法是,咱們使用簡單的express應用程序創建了一個服務器,在Heroku上安裝它,而後設置一個facebook頁面鏈接。但最終,你應該有一個相似這樣的 Facebook 聊天應用程序。
如今是時候把一切都放在一塊兒了。因爲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。
從與chatbot的交互中能夠看到的改進方法,有很大的改進空間。通過幾條信息後,很快就會明白,不只僅是進行持續的對話就好了。chabtot不可以把思想聯繫在一塊兒,而一些反應彷佛是隨機的、不連貫的。下面是一些能夠提升咱們聊天機器人性能的方法。
合併其餘數據集,以幫助網絡從更大的會話語料庫中學習。這將消除聊天機器人的「我的特性」,由於它如今已經被嚴格訓練了。然而,我相信這將有助於產生更現實的對話。
處理編碼器消息與解碼器消息無關的場景。例如,當一個對話結束時,你次日就開始一個新的對話。談話的話題可能徹底無關。這可能會影響模型的訓練。
使用雙向LSTMs,注意機制和套接。
優化超參數,如LSTM單元的數量、LSTM層的數量、優化器的選擇、訓練迭代次數等。
你如何創建像你同樣的聊天機器人- 流程回顧
若是你一直在跟進,你應該對建立一個聊天機器人所須要的東西已經有了一個大體的概念。讓咱們再看一遍最後的步驟。在GitHub repo 中有詳細的說明。
https://github.com/adeshpande3/Facebook-Messenger-Bot/blob/master/README.md
找到全部你與某人交談過的社交媒體網站,並下載你的數據副本。
從CreateDataset中提取全部(消息、響應)對py或您本身的腳本。
(可選)經過Word2Vec.py爲每個在咱們的對話中出現的單詞 生成單詞向量。
在Seq2Seq.py中建立、訓練和保存序列模型。
建立Facebook聊天機器人。
建立一個Flask服務器,在其中部署保存的Seq2Seq模型。
編輯索引文件,並與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