創作能手——LSTM「詩人」

摘要: 本文作者介紹了她的一個小實驗:創建一個會寫詩歌的LSTM網路。

代碼是詩歌,這是WordPress的哲學的一部分,作為一名程序猿和一位詩人的我一直喜歡這句話。我一直有一個疑問:可以做一個可以寫出原創詩歌的機器人嗎?

帶著這個疑問我一直思考,我知道如果我的機器人學習寫詩,首先必須先會讀詩。在2017年,有人使用WordPress發布了超過五十萬個標籤為詩歌的帖子。我向一些多產的詩人詢問,問他們是否願意和我一起進行有趣的實驗:他們是否允許我的機器人閱讀他們的作品,以便學習詩歌的形式和結構,以至於學會寫自己的詩歌?特別感謝這些為科學而合作的勇敢的作家們!

什麼是LSTM,它是如何生成文本的?

Advertisements

我在實驗中使用了一種稱為LSTM或長短期記憶網路的神經網路來構建我的機器人。

神經網路通過使用圖層將問題分解成一系列較小的問題:例如,假設你正在訓練一個神經網路來識別一個正方形。一層可能負責識別直角,另一層可能識別平行線,這些特徵都必須存在才能使圖像成為正方形。神經網路通過訓練數以百萬計的正方形圖像來學習所需的特徵。

現在假設你正在使用一個神經網路來預測這個序列中的下一個字母:

th_

對於一個人來說,這個任務是非常簡單的,你會猜e。如果你是一個說英文的人,你不會猜測是q,那是因為你已經學會了它後面沒有q存在的情況。LSTM可以「記住」以前的狀態來通知其當前的決定。

像許多LSTM文本生成示例一樣,我的機器人也是一次生成一個字元來生成文本。所以要想以任何有意義的方式把話彙集起來,首先要學會如何說話。為了實現這一點,它需要數百萬個包含有效單詞的示例序列。WordPress.com有我們需要的材料。

Advertisements

準備數據集

我從Elasticsearch索引中抽出了上面列出的所有詩歌。根據每個\n字元的字數,我用一個非常簡單的規則去除了詩歌的所有內容。如果一個文本塊包含許多單詞,但很少\n字元,這可能是一個或多個段落的集合。然而,一段文字與文字散布在許多行中更可能是一首詩。為了達到這個實驗的目的,我特別感興趣的是LSTM是否可以學習結構,如斷行和節,以及其他詩歌裝置,如押韻,聲調,和聲和合併。所以,把訓練數據限制在比較結構化的詩里是有道理的。

一旦一段文字被確定為一首詩,我就把它寫到一個文本文件中,並在其前加上一個字++++\n來表示一首新詩的開始。通過這種方式,我得到了大約500KB的訓練數據。通常我會嘗試用至少1MB的文字來訓練LSTM,所以我需要找到更多的詩歌!

訓練LSTM網路

找到足夠的數據集后,我開始建立一個LSTM網路。我使用Python庫keras來滿足我所有的神經網路需求,而keras的GitHub庫有幾十個示例腳本來幫助你學習使用幾種不同類型的神經網路,包括使用LSTM的文本生成。在此示例之後,我運行了我的代碼,並開始嘗試不同的模型配置。這個模式的目標是製作原創詩歌。在這種情況下,過度擬合可能導致生成與輸入文本非常相似的文本。(這就像剽竊,沒有詩人喜歡!)防止過度擬合的一種方法是添加丟失到你的網路。這迫使每個步驟的權重的隨機子集降到零。這就像是迫使網路「忘記」一些剛剛學到的東西。

我使用FloydHub的GPU來訓練我的網路,這使我能夠像使用筆記本電腦一樣快速地訓練網路。我的第一個網路有一個LSTM層,後面是一個dropout層。它有斷行和節,幾乎所有的字元組合都是真正的單詞。事實上,第一次迭代產生了這個:

我添加了LSTM層,試驗每個圖層中的dropout級別,直到確定使用下面的最終模型。我選擇在三個LSTM層,因為在這一點上訓練時間開始變得不合理,但結果相當不錯。

model = Sequential()model.add(LSTM(300, input_shape=(maxlen, len(chars)), return_sequences=True, dropout=.20, recurrent_dropout=.20))model.add(LSTM(300, return_sequences=True, dropout=.20, recurrent_dropout=.20))model.add(LSTM(300, dropout=.20, recurrent_dropout=.20))model.add(Dropout(.20))model.add(Dense(len(chars)))model.add(Activation('softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam')

這是一個模型之間比較后得到的損失曲線:

事實證明,使用adam優化器時,這種情況非常普遍。請注意,當我將LSTM層添加到網路中時,模型的驗證損失總體上繼續下降,速度也更快。這意味著在更短的時期內可以獲得可行的結果,但是額外的層次增加了每個時期的訓練時間。一個LSTM層訓練每個epoch大約需要600秒,然而,三層LSTM每個epoch需要7000秒,需要幾天才能完成訓練。所以,驗證丟失速度的下降實際上並不意味著更快的結果。儘管訓練花費的時間較長,但我完全主觀認為,三層LSTM網路所產生的詩歌更好。

生成詩歌

為了產生完整的原始文本,我還需要改變文本的生成方式。在keras庫中,腳本從訓練數據中選擇一個隨機的字元序列作為訓練網路的輸入。我從開始在訓練集中的每首詩都用++++\n區分,我認為這足以創造出完整的原始輸出。但結果是荒謬的組合\n,_,.,和&。經過一些試驗和錯誤之後,我發現種子序列需要與訓練序列具有相同數量的字元。最終,我使用了300個字元的序列,所以我通過重複++++\n剛好300個字元來生成一代。

產生新一輪詩歌后,我進行了最後的抄襲檢查。為此,我首先在訓練集中創建了所有獨特的4-gram(包含4個詞的短語)的集合,並且為我的機器人詩歌創作了同樣的東西,然後我計算了這兩個集合的交集。通常情況下,這個交集包含如下內容:

·i don』t want

·i can not be

·i want to be

·the sound of the

詩歌!

每個輸出模型權重意味著我們可以在訓練期間的幾個點上載入模型。在設計上,訓練數據最顯著的特徵是每行幾個字元,下面是一個訓練結束後生成的詩歌的例子:

The pare of frowning the wand the sallt a merien.

You will we mece wore and and the bite.

in is what to call stor the mathing all your bray.

它已經學到了一些使用的詞語,模仿了每一行之間空白空間的慣例。從遠處看,那看起來像是一首詩!在單個LSTM模型的損失收斂之後,模型學習了節和線斷。

The and the beautiful specting

The flight of how the way

I am the room of the words.

I have seen to see

But your heart will see the face

除了標題行之外,我最喜歡的另一個是:

the wind is only for me

而單一的LSTM模型在一首詩中並沒有很好地掌握主題,而在它所產生的全部工作中似乎都有一個共同的線索。這是由單一LSTM模型生成的所有詩歌的詞云:

如果sun是訓練數據中最普遍的辭彙,這並不令人驚訝,但事實並非如此!這是一個由訓練數據生成的文字云:

艾米莉·狄金森(Emily Dickinson)寫了關於自然和死亡的詩歌,而我的機器人寫關於天體的詩:

Seen will be found

Mere seeds smiles

I red my the day

the day of the way

the kind be the end

添加第二個LSTM層后,我們開始看到其他詩歌特徵,如頭韻和韻律。

它也開始產生一些非常有詩意的短語。例如:

there』s a part of the world.

between the darkness.

the shadows stay the day.

到目前為止,我們已經看到了節,韻(內部和行結尾),重複和頭韻。但是,偶爾有戲劇性的天賦,這個機器人在這個時候產生的詩歌通常是不連貫的辭彙集。它的廢話絕大部分都沒有語法結構。

然而,這開始改變,增加了第三個LSTM層。這種模式更有可能產生語法上合理的線條,即使仍然是荒謬的。例如:

The father of the light is not a fist of the bones

這個句子沒有意義,但是正確地放置了詞性。它也具有一致性,並且對名詞從句具有一般的詩意。

但三層LSTM模式的最高成就就是這首完整的詩:

From your heart of the darkness

I stay

and struggle on the soul

本文由阿里云云棲社區組織翻譯。

文章原標題:《to-a-poem-is-a-bott-the-stranger》,

作者:卡莉Stambaugh 數據科學家

譯者:虎說八道,審閱。

Advertisements

你可能會喜歡