1. 程式人生 > >基於LSTM網路的藏頭詩自動生成

基於LSTM網路的藏頭詩自動生成

最近在研究LSTM的網路結構,尤其是LSTM內部結構(隱藏權重和偏置),這篇部落格作為一個概括,簡單說用LSTM完成的任務,一個是藏頭詩和古詩的自動生成,一個是IMDB影評資料的文字情感分析。

這篇部落格先講一下第一個任務:用LSTM網路實現藏頭詩(也包括古詩)的自動生成,之後再更新用於情感分析。

自然語言處理是教會機器如何去處理或者讀懂人類語言的系統,目前比較熱門的方向,Long Short Term Memory (LSTM)是迴圈神經網路的改進,在自然語言處理方面有明顯的優勢,在當前卷積神經網路流行的時期依然擔當者重要角色。本文采用兩層的LSTM網路,訓練資料集為34646首唐詩。文中詳細介紹了詩歌資料的預處理過程,包括資料清洗、統計詞頻、生成字型檔、根據字型檔把每一首詩轉化為一個向量。詩歌轉化為詞向量採用one-hot編碼的方式,因此不需要藉助其他工具輔助轉化,但存在詞向量維度較大的問題。在文中,我們給出了生成藏頭詩效果,同時作為拓展,使用訓練好的網路也可以生成古詩。根據引數控制,我們可以指定生成七言或五言詩,實驗結果表明我們搭建的LSTM網路能夠高效地生成藏頭詩,古詩。

在未進入深度學習時代,NLP也是一個蓬勃發展的領域。然而,在所有的上述任務中,我們都需要根據語言學的知識去做大量的,複雜的特徵工程。如果你去學習這個領域,那麼整個四年你都會在從事這方面的研究,比如音素,語素等等。在過去的幾年中,深度學習的發展取得了驚人的進步,在一定程度上我們可以消除對語言學的依賴性。由於進入的壁壘降低了,NLP 任務的應用也成為了深度學習研究的一個重大的領域之一【1】。

今年,基於LSTM的系統可以學習翻譯語言、控制機器人、影象分析、文件摘要、語音識別影象識別、手寫識別、控制聊天機器人、預測疾病、點選率和股票、合成音樂等等任務【2】 【3】。在2017年,LSTM的提出人(Juergen Schmidhuber

)團隊做了一個統計,如圖(1),LSTM網路在世界最有價值的五大公司的應用,統計表明當前在這五大公司的應用廣泛【4】【5】。

圖1、LSTM網路在世界最有價值的五大公司的應用

繼去年“機器學習生成恐怖影象”後,MIT研究人員在今年的萬聖節推出了“AI寫恐怖故事”的專案【6】,利用RNN和線上學習演算法,結合Reddit上人類寫的恐怖故事資料,生成恐怖故事,生成的句子包括“它的面板冰冷蒼白,好像在我的肺裡來回移動,試圖留在我的靈魂裡”。Shelley每小時就會在推特上寫一個新的恐怖故事的開頭,並以#yourturn(#該你了#)的話題標籤邀請人類續寫,然後Shelley會回覆人類的續寫,如此迴圈往復。

從上面的例子我們也可以看到迴圈神經網路在自然語言的應用潛力很大,但可以看到在自動生成小說時,還需要人類來豐富故事的內容,AI進行創作還是需要人類輔助。

基於LSTM的影評情感分析【7】採用的資料均是英文資料,而本文中特別地採用了中文資料,而且是古詩資料集,因此文中沒有采用word-to-vector的方式,也沒有采用結巴分詞,這是受到古詩的特點制約的。也可以說是因為當前沒有針對古詩的分詞操作,因此從我們最後的生成結果可以看到生成的詩歌在形式上和古詩很相似,當時在意境上還有很大的欠缺。這一章主要介紹當前LSTM的應用背景,下面介紹本文采用的LSTM結構 。

一、LSTM網路結構

人類並不是每時每刻都從頭開始思考。正如你閱讀這篇文章的時候,你是在理解前面詞語的基礎上來理解每個詞。你不會丟棄所有已知的資訊而從頭開始思考。你的思想具有持續性。這正是迴圈神經網路在自然語言處理的優勢,自然語句正好也是迴圈神經網路的鏈式結構,完美契合。

在介紹LSTM網路之前,需要先介紹一般的迴圈神經網路(RNN),結構如圖(2)。

圖2、普通的迴圈神經網路結構

在程式中執行時,迴圈神經網路採用的是引數共享的方式,也就是實際上一層迴圈神經網路只有一個cell(圖中的A區域),在深入學習研究之後,發現cell內部存在的權重也是在訓練的,但這部分權重不需要程式設計師去定義,而且也不能直接檢視,而在模型載入時會載入這部分權值,這是迴圈神經網路和卷積神經網路很大的一個區別。

圖3、RNN cell結構

從圖(3)我們給出了當迴圈神經網路輸入資料維度為一維,內部單元數只有一個時的cell內部結構。該圖詳細闡述了RNN內部的引數傳遞。圖四是當輸入資料維度變為2,cell內部單元數增加為2時的結構,從結構圖中可以看到單元之間資料是獨立的而每個單元的上一個狀態是之間cell內部每個單元的狀態集合。也就是單元之前看似獨立又相互聯絡。

圖4、增加單元后迴圈神經網路結構

而我們使用的LSTM網路和迴圈神經網路也是採用的鏈式結構,只是在cell內部設計更為複雜,LSTM在結構上增加了三個門,包括輸入門,遺忘門,輸出門,這是流行的解釋,個人覺得也可以理解為四個門,因為結構中權重主要四個部分,啟用函式也為4個。LSTM內部引數較多,但是引數之間的聯絡緊密。


圖5、LSTM主要結構

RNN 的關鍵點之一就是他們可以用來連線先前的資訊到當前的任務上,例如使用過去的視訊段來推測對當前段的理解。如果 RNN 可以做到這個,他們就變得非常有用。有時候,我們僅僅需要知道先前的資訊來執行當前的任務。例如,我們有一個語言模型用來基於先前的詞來預測下一個詞。如果我們試著預測“the clouds are in the sky” 最後的詞,我們並不需要任何其他的上下文 —— 因此下一個詞很顯然就應該是 sky。在這樣的場景中,相關的資訊和預測的詞位置之間的間隔是非常小的,RNN 可以學會使用先前的資訊。

但是同樣會有一些更加複雜的場景。假設我們試著去預測“I grew up inFrance... I speak fluent French”最後的詞。當前的資訊建議下一個詞可能是一種語言的名字,但是如果我們需要弄清楚是什麼語言,我們是需要先前提到的離當前位置很遠的 France 的上下文的。這說明相關資訊和當前預測位置之間的間隔就肯定變得相當的大。不幸的是,在這個間隔不斷增大時,RNN 會喪失學習到連線如此遠的資訊的能力。

LSTM是一種 RNN 特殊的型別,可以學習長期依賴資訊。LSTM 由Hochreiter & Schmidhuber【8】提出,並在近期被Alex Graves【9】進行了改良和推廣。在很多問題,LSTM 都取得相當巨大的成功,並得到了廣泛的使用。LSTM 通過刻意的設計來避免長期依賴問題。記住長期的資訊在實踐中是 LSTM 的預設行為,而非需要付出很大代價才能獲得的能力!所有 RNN 都具有一種重複神經網路模組的鏈式的形式。在標準的 RNN 中,這個重複的模組只有一個非常簡單的結構,例如一個 tanh 層。

LSTM 的關鍵就是細胞狀態,水平線在圖上方貫穿執行。細胞狀態類似於傳送帶。直接在整個鏈上執行,只有一些少量的線性互動。資訊在上面流傳保持不變會很容易。LSTM 有通過精心設計的稱作為“門”的結構來去除或者增加資訊到細胞狀態的能力。門是一種讓資訊選擇式通過的方法【10】。他們包含一個 sigmoid 神經網路層和一個 pointwise 乘法操作。Sigmoid 層輸出 0 到 1 之間的數值,描述每個部分有多少量可以通過。0 代表“不許任何量通過”,1 就指“允許任意量通過”!LSTM 擁有三個門,來保護和控制細胞狀態。

遺忘門:

在我們 LSTM 中的第一步是決定我們會從細胞狀態中丟棄什麼資訊。這個決定通過一個稱為忘記門層完成。該門會讀取 h_{t-1} 和 x_t,輸出一個在0 到 1 之間的數值給每個在細胞狀態 C_{t-1} 中的數字。1 表示“完全保留”,0 表示“完全捨棄”。讓我們回到語言模型的例子中來基於已經看到的預測下一個詞。在這個問題中,細胞狀態可能包含當前主語的性別,因此正確的代詞可以被選擇出來。當我們看到新的主語,我們希望忘記舊的主語。

圖6、LSTM內部遺忘門

輸入門:

下一步是確定什麼樣的新資訊被存放在細胞狀態中。這裡包含兩個部分。第一,sigmoid 層稱“輸入門層” 決定什麼值我們將要更新。然後,一個 tanh 層建立一個新的候選值向量,\tilde{C}_t,會被加入到狀態中。下一步,我們會講這兩個資訊來產生對狀態的更新。

在我們語言模型的例子中,我們希望增加新的主語的性別到細胞狀態中,來替代舊的需要忘記的主語。

圖7、LSTM內部輸入門

輸出門:

最終,我們需要確定輸出什麼值。這個輸出將會基於我們的細胞狀態,但是也是一個過濾後的版本。首先,我們執行一個 sigmoid 層來確定細胞狀態的哪個部分將輸出出去。接著,我們把細胞狀態通過tanh 進行處理(得到一個在 -1 到 1 之間的值)並將它和 sigmoid 門的輸出相乘,最終我們僅僅會輸出我們確定輸出的那部分。在語言模型的例子中,因為他就看到了一個 代詞,可能需要輸出與一個動詞 相關的資訊。例如,可能輸出是否代詞是單數還是負數,這樣如果是動詞的話,我們也知道動詞需要進行的詞形變化。

圖8、LSTM內部輸出門

介紹完LSTM的結構,對於LSTM的原理有一個比較清晰的認識時候,接下來介紹如何使用LSTM網路。

二、資料預處理

本文藏頭詩自動生成採用的是全唐詩,一共包含34646首唐詩。資料格式為詩歌名加上詩歌內容,如圖(9)。所有詩歌存放在一個txt文件中,每一行儲存一首詩。

圖9、資料集簡介

資料預處理的過程,實際上是文字處理的過程,先對詩歌進行拆分,提取詩歌內容。步驟包括資料清洗、統計詞頻、生成字型檔、根據字型檔把每一首詩轉化為一個向量。

1.進行原始資料清洗(這裡只進行去除詩歌題目)

圖10、詩歌資料清洗

2.統計詞頻。(詩歌中就是統計字頻,下面只是小樣本測試)

3.根據詞頻排序,生成字型檔

4根據字型檔把每一首詩轉化為一個向量。(這個向量以字型檔中的漢字數作為維度,每個維度中通過0和1來表示這個漢字在這首詩中是否出現。)

該程式是使用詞庫法進行的資料處理。

One-hot編碼:

本實驗在轉化為詞向量的過程中採用的one-hot編碼,在資料處理和特徵工程中,經常會遇到型別資料,如性別分為[男,女],手機運營商分為[移動,聯通,電信]等,我們通常將其轉為數值帶入模型,如[0,1], [-1,0,1]等,但模型往往預設為連續型數值進行處理,這樣其實是違揹我們最初設計的,也會影響模型效果。

圖11、one-hot編碼例項

把唐詩轉化為向量形式,接下里就可以輸入LSTM網路進行訓練了。

三、訓練與模型生成

首先我們要訓練好模型。這裡採用的是2層的LSTM框架,每層有128個隱藏層節點,batch_size設為64。訓練資料來源於全唐詩。訓練引數:rnn_size=128,num_layers=2,batch_size = 64(每次取64首詩進行訓練),Learning_rate=0.01。

圖12、兩層LSTM結構圖

執行環境採用Linux系統,python2.7,tensorflow1.2.0。執行環境截圖如圖13()。

圖13、執行環境

 

四、藏頭詩生成效果

以美麗華中大為頭生成的藏頭詩:

五言詩:

美酒賤人少,上月同辭帷。

麗柳晴光禁,黃雲敞照橋。

華丘相見去,羅晰得餘看。

中水覆成泰,朱林測不通。

大顏之上安,二妃豈知情。

七言詩:

美妻不說秋來斷,鎖檻低頭太阿扶。

麗藻昏昏不病身,疏花飄去使中春。

華桂三叫雲火空,山僧荊棘得無痕。

中原風野客爭摧,當死相思盛酒卮。

大牢頭上馬行人,延面香窗風外愁。

武漢別名江城,這哥別名源於李白的《與史郎中欽聽黃鶴樓上吹笛》,一為遷客去長沙,西望長安不見家。黃鶴樓中吹玉笛,江城五月落梅花。鐫刻於如今重建的黃鶴樓。下面以江城美景為頭:

五言詩:

江焰紅花裡,風經雨起煙。

城西深夜後,葉滿不勝經。

美潔漏將受,出門臨碧池。

景間陪待罷,佳景盡依依。

七言詩:

江邊樹綠半堪山,八月西洲伴春色。

城郭花開雪滿地,滿江楊柳歸何處。

美女塵中心自偶,遠平一是子為珍。

景陽幽色最臨聲,此意浮風坐繞禪。

 

 

拓展部分(古詩生成)

古詩生成和藏頭詩比較接近,差別在於藏頭詩是指定一個字,然後使用訓練好的LSTM網路預測每一句詩歌的內容。而生成古詩不指定詩歌內容(可以限定是5言或七言),詩歌第一個字有程式隨機生成,然後接下來全部由LSTM網路生成,生成的詩歌長度也是不一定的。

五言詩:

花偏君亦長,一別少看花。

項小黔州路,天邊山已深。

渡長淮河上,月夜南山分。

情世不可識,歌枝一少愁。

七言詩:

彼處聞寒溜泉頻,竹峰蛛網木濃陰。

先生成性思成遠,白髮幽人事肯醒。

惟有月圓心便寢,起經徒到意無身。

跂襟藉筍叢青菊,聲價同親奈欲何。

五、總結與展望

本文設計了基於LSTM網路的藏頭詩自動生成框架,文中詳細介紹LSTM網路的結構以及原理,對資料預處理過程分為資料清洗、統計詞頻、生成字型檔、根據字型檔把每一首詩轉化為一個向量。對於採用的one-hot編碼原理,優缺點文中做了細緻的分析。從最後的生成結果看,生成的藏頭詩和古詩基本符合唐詩的形式,在詩歌意境方面還有很大的提升空間。

深入分析其原因,主要是One-hot方法很簡單,但是它的問題也很明顯:1)它沒有考慮單詞之間相對位置的關係;2)維度等於字型檔的總數,這種方法造成維度災難。詞向量可能非常非常長!因此可以採用分詞法,比如說中文處理比較流行的結巴分詞。然後對詞進行編碼。這樣詩歌已經會有明顯提高。同時也可以用LSTM網路生成小說等。這是未來可以完成的工作。