如何利用深度學習寫詩歌
原文:https://www.analyticsvidhya.com/blog/2018/03/text-generation-using-python-nlp/
由於自然語言處理(NLP)領域的重大進步,機器能夠自己理解上下文和編造故事。文字生成的例子包括,機器編寫了流行小說的整個章節,比如《權力的遊戲》和《哈利波特》,取得了不同程度的成功。在本文中,我們將使用python和文字生成的概念來構建一個機器學習模型,可以用莎士比亞的風格來寫十四行詩。讓我們來看看它!
現在,有大量的資料可以按順序分類。它們以音訊、視訊、文字、時間序列、感測器資料等形式存在。針對這樣特殊類別的資料,如果兩個事件都發生在特定的時間內,A先於B和B先於A是完全不同的兩個場景。然而,在傳統的機器學習問題中,一個特定的資料點是否被記錄在另一個資料點之前是不重要的。這種考慮使我們的序列預測問題有了新的解決方法。
文字是由一個挨著一個的字元組成的,實際中是很難處理的。這是因為在處理文字時,可以訓練一個模型來使用之前發生的序列來做出非常準確的預測,但是之前的一個錯誤的預測有可能使整個句子變得毫無意義。這就是讓文字生成器變得棘手的原因!
為了更好地理解程式碼,請瀏覽這兩篇文章。LSTM背後的理論(連結:https://www.analyticsvidhya.com/blog/2017/12/fundamentals-of-deep-learning-introduction-to-lstm/)
文字生成的步驟
匯入依賴
載入資料
建立對映
資料預處理
模型構建
生成文字
讓我們詳細地看一下每一個步驟。
匯入依賴
import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import LSTM
from keras.utils import np_utils
載入資料
text=(open("/Users/pranjal/Desktop/text_generator/sonnets.txt").read())
text=text.lower()
這裡,我們正在載入所有莎士比亞十四行詩的集合,這些十四行詩可以從這裡(連結:http://www.gutenberg.org/cache/epub/1041/pg1041.txt)下載。我清理了這個檔案以刪除開始和結束的學分,並且可以從我的git儲存庫下載。 文字檔案被開啟並儲存在text中。然後將該內容轉換為小寫,以減少可能單詞的數量(稍後將對此進行詳細介紹)。
建立對映
對映是在文字中為字元/單詞分配任意數字的步驟。這樣,所有的惟一字元/單詞都對映到一個數字。這一點很重要,因為機器比文字更能理解數字,這使得訓練過程更加容易。
characters = sorted(list(set(text)))
n_to_char = {n:char for n, char in enumerate(characters)}
char_to_n = {char:n for n, char in enumerate(characters)}
我已經建立了一個字典,其中給文字中每個獨特的字元分配一個數字。所有獨特的字元首先儲存在字元中,然後被列舉。
這裡還必須注意,我使用了字元級別的對映,而不是單詞對映。然而,與基於字元的模型相比,基於單詞的模型與其他模型相比具有更高的準確性。這是因為基於字元需要一個更大的網路來學習長期依賴關係,因為它不僅要記住單詞的順序,而且還要學會預測一個語法正確的單詞。但是,在基於單詞的模型中,後者已經被處理好了。
資料預處理
在構建LSTM模型時,這是最棘手的部分。將手頭的資料轉換成可供模型訓練的格式是一項困難的任務。 我會把這個過程分解成小的部分,讓你更容易理解。
X = []
Y = []
length = len(text)
seq_length = 100
for i in range(0, length-seq_length, 1):
sequence = text[i:i + seq_length]
label =text[i + seq_length]
X.append([char_to_n[char] for char in sequence])
Y.append(char_to_n[label])
這裡,X是我們的訓練序列,Y是我們的目標陣列。seq_length是我們在預測某個特定字元之前要考慮的字元序列的長度。for迴圈用於遍歷文字的整個長度,並建立這樣的序列(儲存在X中)和它們的真實值(儲存在Y中),為了更好地弄清楚“真實值”的概念。讓我們以一個例子來理解這一點:
對於4的序列長度和文字“hello india”,我們將有X和Y表示如下:
現在,LSTMs接受輸入的形式是(number_of_sequence, length_of_sequence, number_of_features),這不是陣列的當前格式。另外,我們需要將陣列Y轉換成一個one-hot編碼格式。
X_modified = np.reshape(X, (len(X), seq_length, 1))
X_modified = X_modified / float(len(characters))
Y_modified = np_utils.to_categorical(Y)
我們首先將陣列X重構為所需的維度。然後,我們將X_modified的值進行縮放,這樣我們的神經網路就可以更快地訓練,並且更少的機會被困在區域性最小值中。此外,我們的Y_modified是一個熱編碼,以刪除在對映字元過程中可能引入的任何順序關係。也就是說,與“z”相比,“a”可能會被分配一個較低的數字,但這並不表示兩者之間有任何關係。
最後的陣列將是:
建立模型
def vgg_bn_drop(input):
def conv_block(ipt, num_filter, groups, dropouts, num_channels=None):
model = Sequential()
model.add(LSTM(400, input_shape=(X_modified.shape[1], X_modified.shape[2]), return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(400))
model.add(Dropout(0.2))
model.add(Dense(Y_modified.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam')
文字生成
string_mapped = X[99]
for i in range(seq_length):
x = np.reshape(string_mapped,(1,len(string_mapped), 1))
x = x / float(len(characters))
pred_index = np.argmax(model.predict(x, verbose=0))
seq = [n_to_char[value] for value in string_mapped]
string_mapped.append(pred_index)
string_mapped = string_mapped[1:len(string_mapped)]
嘗試不同模型
基線模型:
當訓練為1個週期,批大小為100時,給出如下輸出:
's the riper should by time decease,
his tender heir might bear his memory:
but thou, contracted toet she the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the th'
這個輸出沒有多大意義。它只是重複同樣的預測,就好像它被困在一個迴圈中一樣。這是因為與我們訓練的微型模型相比,語言預測模型太複雜了。
讓我們試著訓練同樣的模型,但是將時間週期變長。
加強訓練時間的模型:
這次我們訓練我們的模型為100個週期,批大小設定為50。我們至少得到了一個非重複的字元序列,其中包含了相當數量的合理單詞。此外,該模型還學會了生成一個類似14行詩的結構。
'The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to thine own besire,
that in the breath ther doomownd wron to ray,
dorh part nit backn oy steresc douh dxcel;
for that i have beauty lekeng norirness,
for all the foowing of a former sight,
which in the remame douh a foure to his,
that in the very bumees of toue mart detenese;
how ap i am nnw love, he past doth fiamee.
to diserace but in the orsths of are orider,
waie agliemt would have me '
但是,這個模型還不夠好,不能產生高質量的內容。所以現在我們要做的是當一個深度學習模型沒有產生好的結果時,每個人都會做的事情。建立一個更深層次的架構!
一個更深的模型:
一位機器學習的大牛曾經說過:如果模型做得不好,那就增加層數!我將用我的模型做同樣的事情。讓我們再新增一個LSTM層,裡面有400個單元,然後是一個引數為0.2的dropout層,看看我們得到了什麼。
"The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to the world's false sporoe,
with eyes so dond touls be thy domfornds,
which for memorion of the seasons new;
mike own self-love to shou art constant
how can i then be oy love doth give,
the rose looks fair, but fairer bomments age.
now with the seas that i have seen dychl
that mot to teed of you, if h ho bontent,
and all the ress of the heartai thee;
the world will was iis bound and farty "
結果開始變得有趣。語法實現了自我增強,保持了十四行詩的結構和標點的完整。然而,這仍然需要很大的改進。讓我們嘗試探索一個更廣泛的網路,一個擁有更多單元的網路。
一個更廣的模型:
在兩個LSTM層中,我將單元的數量增加到700個。這個調整產生了以下的詩歌:
"The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to thine own bright eyes,
feed'st thy sigh aare so beuider poise,
oor maty dis surre that gairs mot me love thee;
when i braye the would and lays in the eesire.
than thmu disgrmed stand with my bootr still nsentente;
tell ia to thou art thou wilt woon'thy sook,
and touain then tor, give thy soue semping.
whose whod the better of your befaiss nu sante,
though i, suoll oas, and i lose bouh twa"
這個做法並沒有令我滿意,因為這些詞已經失去了意義。但是,有趣的是,這個模型開始嘗試建立一些韻腳。模型畢竟是在開始嘗試更深層次理解詩歌!但是,對於訓練出既有意義又優美的詩歌的目標,我們不能妥協,對嗎?
讓我們把它放在一個超大的模型中。
一個超大的模型:
我將層數增加到3層,每層有700個單元,並訓練了100個週期。產生的結果是一篇巨集偉的詩篇。請看:
"The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to thine own bright eyes,
feed'st thy light's flame with self-substantial fuel,
my beept is she breat oe bath dasehr ill:
tirse do i pine and turfeit day by day,
or gluttoning on all, or all away.
Lxxvi
why is my verse so barren of new pride,
so far from variation or quick change?
why with the time do i not glance aside
to new-found methods, and to compounds strange?
why write i stil"
這篇詩歌不僅用詞準確,而且也學會了押韻。我們本可以有一件更巨集偉的藝術品,但是作為入門LSTM的一個開始,這就夠了。這已經是比大多數人更好地表達了!
★推薦閱讀★
相關文章
- 深度學習(三)之LSTM寫詩深度學習
- 機器也可以寫詩——中文詩歌生成網路初探
- 工人詩歌
- 如何學習和利用深度學習演算法框架深度學習演算法框架
- 不只會作詩 谷歌AI還能寫歌谷歌AI
- 關於詩歌的故事
- 如何利用深度學習製作專業水準的照片?深度學習
- 【深度學習】不要被深度學習一葉障目不見泰山;NLP 解決方案是如何被深度學習改寫的?...深度學習
- DT仿 中華詩歌網程式
- 如何利用深度學習分類Yelp上的商業圖片深度學習
- 自制簡單的詩歌搜尋系統
- 教你如何利用 XMind 高效學習?
- 深度學習(一)深度學習學習資料深度學習
- AI 智慧寫情詩、藏頭詩AI
- 深度學習小課堂:如何利用遞迴神經網路生成文字?深度學習遞迴神經網路
- 深度學習+深度強化學習+遷移學習【研修】深度學習強化學習遷移學習
- 深度學習及深度強化學習研修深度學習強化學習
- 深度學習學習框架深度學習框架
- 【Get】用深度學習識別手寫數字深度學習
- 深度學習深度學習
- ####深度學習深度學習
- 深度 學習
- 利用docker部署深度學習模型的一個最佳實踐Docker深度學習模型
- 利用ENV/深度學習工具提取防塵網覆蓋資訊深度學習
- 深度學習及深度強化學習應用深度學習強化學習
- 寫寫程式碼 聽聽歌
- 利用OpenCV和深度學習來實現人類活動識別OpenCV深度學習
- 深度學習筆記8:利用Tensorflow搭建神經網路深度學習筆記神經網路
- 利用深度學習和機器學習預測股票市場(附程式碼)深度學習機器學習
- [譯] 利用 Keras 深度學習庫進行詞性標註教程Keras深度學習詞性標註
- 利用ENVI深度學習進行遙感變化監測教程深度學習
- 讀懂深度學習,走進“深度學習+”階段深度學習
- 深度學習——學習目錄——學習中……深度學習
- 深度:如何從系統層面優化深度學習計算?優化深度學習
- MySQL深度學習MySql深度學習
- 深度學習模型深度學習模型
- 深度學習《StarGAN》深度學習
- 深度學習《patchGAN》深度學習