創作能手——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 數據科學家
譯者:虎說八道,審閱。