【NLP实战】如何基于Tensorflow搭建一个聊天机器人
實(shí)戰(zhàn)是學(xué)習(xí)一門技術(shù)最好的方式,也是深入了解一門技術(shù)唯一的方式。因此,NLP專欄計(jì)劃推出一個(gè)實(shí)戰(zhàn)專欄,讓有興趣的同學(xué)在看文章之余也可以自動動手試一試。
本篇介紹如何基于tensorflow快速搭建一個(gè)基于seq2seq框架的聊天機(jī)器人。
作者&編輯 | 小Dream哥
1?語料準(zhǔn)備?
用于聊天機(jī)器人訓(xùn)練的語料應(yīng)該是一系列的問答對,即大量的如下的形式問答對:
Q:“今天天氣怎么?”
A:“天氣預(yù)報(bào)說今天會下大暴雨的”
此外,為了減少數(shù)據(jù)處理時(shí)的padding量,對訓(xùn)練語料進(jìn)行了分桶的處理,如下圖所示:
所謂分桶,就是按照Q和A的長度進(jìn)行重新的組織,例如上例Q的長度為7,A的長度為13,則這條語料會分在“bucket_5_15.db”文件中。
2 模型搭建
這里介紹的是基于seq2seq框架的聊天機(jī)器人,關(guān)于seq2seq框架的相關(guān)的理論內(nèi)容,可以看一下筆者這一篇文章:
【NLP-ChatBot】能閑聊的端到端生成型聊天機(jī)器人背后都有哪些技術(shù)?
下面我們看看如何基于tensorflow,搭建一個(gè)seq2seq+attention的聊天機(jī)器人。
(1) 構(gòu)建seq2seq編解碼器的特征抽取器
這里采用LSTM作為encoder和decoder的特征抽取器:
# LSTM cells
(2) 處理輸入數(shù)據(jù)
采用tensorflow的placeholder模塊,先定義輸入數(shù)據(jù)的shape。這里定義了encoder_inputs,decoder_inputs,decoder_weights,targets三個(gè)列表。
# inputs
#encoder_inputs表示解碼器的輸入,這個(gè)列表對象中的每一個(gè)元素表示一個(gè)占位符,其名字分別為encoder0, encoder1,…,encoder39
#encoder{i}的幾何意義是編碼器在時(shí)刻i的輸入。
for i in range(buckets[-1][0]):
# 輸出比輸入大 1,這是為了保證下面的targets可以向左shift 1位
for i in range(buckets[-1][1] + 1):
?#target_weights 是一個(gè)與 decoder_outputs 大小一樣的 0-1 矩陣。該矩陣將目標(biāo)序列長度以外的其他位置填充為標(biāo)量值 0。
(3) 搭建引入attention機(jī)制的seq2seq模型
encoder先將cell進(jìn)行deepcopy,因?yàn)閟eq2seq模型是兩個(gè)相同的特征抽取模型,但是模型參數(shù)不共享,所以encoder和decoder要使用兩個(gè)不同的LSTMCell。
然后,直接調(diào)用系統(tǒng)函數(shù)embedding_attention_seq2seq()搭建引入attention機(jī)制的seq2seq模型。這里介紹下該函數(shù)的各個(gè)輸入。
encoder_inputs:編碼器的輸入;
decoder_inputs:解碼器的輸入;
num_encoder_symbols:source的vocab_size大小,用于embedding矩陣定義;
num_decoder_symbols:target的vocab_size大小,用于embedding矩陣定義;
embedding_size:embedding向量的維度;
num_heads:Attention頭的個(gè)數(shù),就是使用多少種attention的加權(quán)方式,用更多的參數(shù)來求出幾種attention向量;
output_projection: 輸出的映射層,因?yàn)閐ecoder輸出的維度是output_size,所以想要得到num_decoder_symbols對應(yīng)的詞還需要增加一個(gè)映射層;
feed_previous:是否將上一時(shí)刻輸出作為下一時(shí)刻輸入,一般測試的時(shí)候置為True,此時(shí)decoder_inputs除了第一個(gè)元素之外其他元素都不會使用;
initial_state_attention:默認(rèn)為False, 初始的attention是零;若為True,將從initial state和attention states開始。
def seq2seq_f(encoder_inputs, decoder_inputs, do_decode):
? ?return tf.contrib.legacy_seq2seq.embedding_attention_seq2seq(#自定義的cell,可以是GRU/LSTM, 設(shè)置multilayer等# embedding 維度
(4)構(gòu)建損失計(jì)算層
因?yàn)椴捎玫氖莝ampled_loss,在解碼器和loss層要加一個(gè)projection層來做適配。
# 如果vocabulary太大,我們還是按照vocabulary來sample的話,內(nèi)存會爆
構(gòu)建sampled_loss層,也是直接調(diào)用sampled_softmax_loss函數(shù),關(guān)于sampled_loss相關(guān)的理論問題,我們再找個(gè)機(jī)會單獨(dú)討論吧。
def sampled_loss(labels, logits):
(5) 計(jì)算損失和logits
這里調(diào)用了系統(tǒng)函數(shù)model_with_buckets,這樣對每個(gè)bucket都構(gòu)造一個(gè)模型,然后訓(xùn)練時(shí)取相應(yīng)長度的序列,不同長度的模型參數(shù)共享。
self.outputs, self.losses = tf.contrib.legacy_seq2seq.model_with_buckets(
(6) 構(gòu)建優(yōu)化器和保存訓(xùn)練模型
params = tf.trainable_variables()
????# 用梯度下降法優(yōu)化# 模型參數(shù)保存
(7) 開始訓(xùn)練
params = tf.trainable_variables()
????# 用梯度下降法優(yōu)化# 模型參數(shù)保存
模型搭建好之后,就可以給模型為數(shù)據(jù),開始訓(xùn)練了。
def step(
#1.將語料放到之前定義好的列表中,待模型讀取 ?for i in range(encoder_size):?#2.開始訓(xùn)練
3 如何進(jìn)行訓(xùn)練和測試
(1) 進(jìn)行訓(xùn)練
在s2s.py中,做如下的設(shè)置,并設(shè)置好學(xué)習(xí)率,batch_size等其他超參數(shù),執(zhí)行s2s.py進(jìn)行訓(xùn)練。
tf.app.flags.DEFINE_boolean(
開始訓(xùn)練后,會打印出來當(dāng)前的loss值,如下圖所示:
模型文件會生成在model文件夾中。
(2) 進(jìn)行測試
在s2s.py中,做如下的設(shè)置:
tf.app.flags.DEFINE_boolean(
然后,可以輸入問句,看機(jī)器人怎么回答了。因?yàn)槲矣?xùn)練的不充分,所以機(jī)器人的回答會出現(xiàn)重復(fù)的。另一方面,這種生成式的機(jī)器人,可控性不強(qiáng),目前基本處于研究階段。
4 如何獲取代碼與交流
至此,介紹了如何利用tensorflow平臺自己搭建一個(gè)基于seq2seq框架的聊天機(jī)器,代碼在我們有三AI的github可以下載:https://github.com/longpeng2008/yousan.ai/tree/master/natural_language_processing
找到seq2seqChatbot文件夾,執(zhí)行python3 s2s.py就可以進(jìn)行訓(xùn)練或者測試了。
代碼來源于github,也可參考這個(gè)github:
https://github.com/qhduan/Seq2Seq_Chatbot_QA
總結(jié)
生成式的聊天機(jī)器人技術(shù)框架非常簡潔,在構(gòu)建過程是端到端(End-to-End)的,實(shí)現(xiàn)簡單。因此,我見過很多簡歷上寫的聊天機(jī)器人項(xiàng)目是基于此框架的,大多雷同,建議讀者在簡歷上寫這個(gè)項(xiàng)目時(shí)要慎重,非要寫的話,務(wù)必要突出差異。
讀者們可以留言,或者加入我們的NLP群進(jìn)行討論。感興趣的同學(xué)可以微信搜索jen104,備注"加入有三AI NLP群"。
下期預(yù)告:基于BERT的文本分類模型
知識星球推薦
掃描上面的二維碼,就可以加入我們的星球,助你成長為一名合格的自然語言處理算法工程師。
知識星球主要有以下內(nèi)容:
(1) 聊天機(jī)器人。考慮到聊天機(jī)器人是一個(gè)非常復(fù)雜的NLP應(yīng)用場景,幾乎涵蓋了所有的NLP任務(wù)及應(yīng)用。所以小Dream哥計(jì)劃以聊天機(jī)器人作為切入點(diǎn),通過介紹聊天機(jī)器人的原理和實(shí)踐,逐步系統(tǒng)的更新到大部分NLP的知識,會包括語義匹配,文本分類,意圖識別,語義匹配命名實(shí)體識別、對話管理以及分詞等。
(2) 知識圖譜。知識圖譜對于NLP各項(xiàng)任務(wù)效果好壞的重要性,就好比基礎(chǔ)知識對于一個(gè)學(xué)生成績好壞的重要性。他是NLP最重要的基礎(chǔ)設(shè)施,目前各大公司都在著力打造知識圖譜,作為一個(gè)NLP工程師,必須要熟悉和了解他。
(3) NLP預(yù)訓(xùn)練模型?;诤A繑?shù)據(jù),進(jìn)行超大規(guī)模網(wǎng)絡(luò)的無監(jiān)督預(yù)訓(xùn)練。具體的任務(wù)再通過少量的樣本進(jìn)行Fine-Tune。這樣模式是目前NLP領(lǐng)域最火熱的模式,很有可能引領(lǐng)NLP進(jìn)入一個(gè)全新發(fā)展高度。你怎么不深入的了解?
轉(zhuǎn)載文章請后臺聯(lián)系
侵權(quán)必究
往期精選
總結(jié)
以上是生活随笔為你收集整理的【NLP实战】如何基于Tensorflow搭建一个聊天机器人的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【直播】如何获得更加高效的深度卷积神经网
- 下一篇: 【AutoML】优化方法可以进行自动搜索