剛開始學習RNN的時候利用英文文本訓練寫英文的文章侮繁。出于練手的目的寫一個文言文的模型的練習色徘。
本模型利用了一個簡單的LSTM模塊各薇,即帶記憶的RNN业岁。雖然LSTM也有類似RNN的局限性鳞仙,但是訓練一個小型的中文文本應該是沒有問題。
快速復習下LSTM原理:
為了快速搭建笔时,我選用了Keras棍好,不多說,快速搭建模型神器允耿。
第一步數(shù)據(jù)處理借笙,就是把每一個出現(xiàn)過的字都標上一個index
from __future__ import print_function
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import LSTM
import numpy as np
import random
import sys
import collections
#我們這里用的訓練文本是《項羽本紀》
path = "xiangyubenji.txt"
text = open(path).read()
print('corpus length:', len(text))
#corpus length: 11247
print(text[:10])
#項籍者,下相人也较锡,字
chars = sorted(list(set(text)))
print('total chars:', len(chars))
#total chars: 1075
char_indices = dict((c, i) for i, c in enumerate(chars))
indices_char = dict((i, c) for i, c in enumerate(chars))
我們來定義下每次訓練文本的句長业稼。這里定義40個字為一句吧。
step為3蚂蕴,下一句是3個字以后低散。其實可以自由定義。
簡單的來說訓練的X就是一句話
訓練的Y就是這句話結(jié)束后的下一個字骡楼。
maxlen = 40
step = 3
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
sentences.append(text[i: i + maxlen])
next_chars.append(text[i + maxlen])
print('nb sequences:', len(sentences))
print(sentences[:1])
print(next_chars[:1])
#nb sequences: 3736
#['項籍者熔号,下相人也,字羽君编。初起時跨嘉,年二十四。其季父項梁吃嘿,梁父即楚將項燕祠乃,為秦將王翦']
#['所']
我們把每句話每個字都向量話。我們用1個1075個元素的向量來表示一個字兑燥,按每個字的index在那個位置標記1(不懂參考one hot encoding)亮瓷。所以一句話就要 40 x 1075 個元素。
X = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
for t, char in enumerate(sentence):
X[i, t, char_indices[char]] = 1
y[i, char_indices[next_chars[i]]] = 1
建立模型,非常簡單降瞳,只用一層LSTM模塊嘱支,輸出為128. 單次步長為一句話的長度,輸入為1075. input_shape=(maxlen, len(chars))
# build the model: a single LSTM
print('Build model...')
model = Sequential()
model.add(LSTM(128, input_shape=(maxlen, len(chars))))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))
optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
接下來我們來訓練這個模型挣饥,來60次epoch除师。
每次10訓練完之后 打出來看看效果。隨機從文中選擇一句話開始扔枫,打出后面預測的四百個字汛聚。
for iteration in range(1, 60):
print()
print('-' * 50)
print('Iteration', iteration)
model.fit(X, y, batch_size=128, nb_epoch=1)
if iteration % 10 == 0:
start_index = random.randint(0, len(text) - maxlen - 1)
for diversity in [1.2]:
# 在sample的時候選擇的分布可選值[0.2, 0.5, 1.0, 1.2]:
print()
print('----- diversity:', diversity)
generated = ''
sentence = text[start_index: start_index + maxlen]
generated += sentence
print('----- 用這句話來開頭寫個故事: "' + sentence + '"')
print('----- 你準備好了,我開始瞎扯了:')
print()
sys.stdout.write(generated)
for i in range(400):
x = np.zeros((1, maxlen, len(chars)))
for t, char in enumerate(sentence):
x[0, t, char_indices[char]] = 1.
preds = model.predict(x, verbose=0)[0]
#大概的原理是從概率到index的映射范圍
next_index = sample(preds, diversity)
next_char = indices_char[next_index]
generated += next_char
sentence = sentence[1:] + next_char
sys.stdout.write(next_char)
sys.stdout.flush()
print()
def sample(preds, temperature=1.0):
# helper function to sample an index from a probability array
preds = np.asarray(preds).astype('float64')
preds = np.log(preds) / temperature
exp_preds = np.exp(preds)
preds = exp_preds / np.sum(exp_preds)
probas = np.random.multinomial(1, preds, 1)
return np.argmax(probas)
其實就這么點短荐。我們來看看效果倚舀。
[epoch10]:
西叹哭,必舉秦矣。故不如先斗秦趙痕貌。夫被堅執(zhí)銳风罩,義不如公;坐而運策舵稠,公不如義超升。”因下令沛公曰‘曰“沛公蓋蓋亦我逐其寶”反柱查,魏沛公與以責令行廓俭,常何且至時,項異楚也唉工⊙衅梗”於是項項王十壁遂沛誅遂誅。財項伯亦郡項伯徙約地擊淋硝,七史披史者事雹熬,大咸王馬烏武沛與楚乃信項孰聞初亦,行阻陳縣而侍者谣膳?不他行殺塞馀何竿报;為期曹保子勝高齊當時為項梁射故項人相來,三素魏人亡城不北继谚。田榮言與阿沛公烈菌。項大破與江召益夜反有詳漢”軍淮罵馬稍哀將屠,而免立司而楚將軍花履,通辦得芽世;罪漢入城勝諸,我中別可戰(zhàn)罪若兵於言當高诡壁。沛苛如济瓢、謹往騎去萬耳景卮萬人武夫山將有舉,具有安廣劍國為項王內(nèi)并趙彭妹卿,戰(zhàn)敗滅:其糧旺矾,多二用也《峥耍”沛勝即天下相圍之公相項羽謂自曰當之不敢數(shù)略誅箕宙。不使者名可知遂不為其耳。項羽大久漢曰:“首項氏與焉項積曰:“糧數(shù)不然铺纽。籍於是項王謂羊欲立國誅歲卒扒吁,項王引姻受右,欲為遇披從而北者於義者。今不敗從所屬於行雕崩,遂霸於田榮不免∪谧玻恐恐復可勝又關(guān)處盼铁,危貴籍聞。韓及然人尝偎,乃應渡河擊東意饶火,公就‘得噲以其臣,諸侯侯諸將六出數(shù)高致扯。項梁
[epoch20]:
無西意肤寝,而北擊齊。徵兵九江王布抖僵。布稱疾不往鲤看,使將將數(shù)千人行。項王由此怨布也耍群。漢之义桂。樊噲周項王。
項約軍走引兵渡三金蹈垢,亦言慷吊。城數(shù)百項王,都鴻萬數(shù)傷降入曹抬,復煩王其秦溉瓶,遂去四北陵之。項王瞋之脫逐谤民。漢王弟南數(shù)千壁遂煩堰酿,瞳三胡萬人,使人追說漢王赖临,非從一為萬行胞锰。。項弟氏兢榨,闋之數(shù)上嗅榕。
居數(shù)百百言,數(shù)百壁項羽追軍吵聪,此亦分至凌那,漢王皆為憐侯。長嬰說為騎齊王吟逝。齊人而射數(shù)寶項王帽蝶。項羽急,曰:“諾块攒。相大杓猴乎励稳?”曰:“心為凍信乘佃乘,聞楚皆則兵屬秦常,軍咸陽至久都也驹尼。
西時趣避,不當成金從武侯。項王如史殺之新翎,年程帕。諸侯至范陵,走項王地啰。項氏愁拭、魯中,聞皆走下亏吝,引兵西岭埠。漢王徇魯,項王顺呕。項羽天下彭項王枫攀。軍戰(zhàn)而北與西,封又株茶。關(guān)項王来涨,乃散知代王。長懷軍启盛,項王蹦掐。項羽渡沛事騎,使人追忍沛僵闯。項羽謂無事之卧抗,知張矣。漢王因玉力鳖粟,水走社裆。、臣江桓張馬章向图?”項氏則功之泳秀,走楚楚而立秦嘉霸矣。今者攻罪關(guān)榄攀,諸將軍薛秦萬為騎城嗜傅。籍俱太曹無益子意,皆復南聲行萬人檩赢,得吳南南月必人下屬與籍倍侯吕嘀。諸侯吏相曰:“雖吏吏卒,使項王乃自合馬
[epoch30]:
帝,曰:“古之帝者地方千里偶房,必居上游趁曼。”乃使使徙義帝長沙郴縣棕洋。趣義帝行彰阴,其群臣稍”背齊數(shù),
時時拍冠,兵漢梁患年,項羽乃召彭越王簇抵。漢王擊秦嘉庆杜,以惡侯與齊與齊。齊碟摆,南功於項王曰:“曰:“起高”何能勝亡走我何棄:“城軍滎晃财,誅非游食,封項羽為詩將章卒者典蜕、東安子北有前断盛,壽金奴、漢兵四力者秦軍愉舔,項王乃相置漢數(shù)十钢猛、睢其以至韓用,得楚十四轩缤,故天亡至命迈,觀破秦入,斬西火的。長公已壶愤、,間與韓游戰(zhàn)馏鹤,近令其心為地征椒,滎又不人,封人軍中湃累,捍內(nèi)未江勃救,北數(shù)由陽關(guān),故立為上為長君遺為封武脱茉,嘗從古漢剪芥,可與彭戰(zhàn),可為獨將琴许,須又不重税肪。欣月走勝故益為翟為王王患來,初之。知者高益兄!夫角走楚锻梳,楚楚之出,睢有所知净捅,王曰:“疑枯,為王將,下蛔六。今歲走城漢甬荆永,此秦戰(zhàn),破秦易国章。於具钥。王聞所諾。漢於歇漢王液兽,得殺數(shù)十骂删,從心長史若。項羽乃定陶懷王四啰,漢王乃使徙瞳漢王父亦叱宁玫、分燒,婦為常柑晒,收其怒欧瘪,殺之卒上《仄”乃謂恋追、與梁
當漢王有碭成皋。長罚屋,欲漢苦囱,如公十復數(shù)侯。約欲攻立事立誅為諸君王脾猛,封令衛(wèi)為前撕彤,郎王數(shù)為沛公沛軍事而塞王∶退”乃即項王未:“吾聞
[epoch60]:
張良出羹铅,要項伯。項伯即入見沛公愉昆。沛公奉卮酒為壽职员,約為婚姻,曰:“吾入關(guān)跛溉,秋豪不敢焊切;扮授。如用之帝者,专肪,大漢王刹勃?”乃曰:“巴、間以楚嚎尤,追九軍至荔仁,騎何陽,長史若者芽死,不敢出乏梁。公。
沛公先為封項王曰:“彭越左劫積关贵,楚王急掌呜,乃城之膠無不至江陽,定陶所知坪哄。陳馀受東與韓而必公∈拼郏”漢王聽翩肌,誡漢王至,披王定陶報項王禁悠。項王使沛公軍項王聞之王三年戰(zhàn)陽念祭。項王乃自王為項王乃疑沛公鼠渺。項羽乃召沛公曰:“吾入急功偿,而恐,至破中冈在,使者高行瓷产,故楚於張耳站玄。項王乃相引兵四面王。項王渡侵濒旦,急下株旷,盡降不別,左勿楚北尔邓,聞羽引欲立漢王父後以來出女晾剖。項王乃馳行,斬睢梯嗽,故八君齿尽。”項王即之灯节,曰:“旦有不趣循头∶喙溃”項王曰:“田角項羽大破曰曰:“謹諾楚以楚,巴得楚之楚破之贷岸。章曰:“章邯乃魏項王項王伏壹士,置軍,無以至東定偿警,項梁怒曰:“田陽為齊受天下躏救,使人新六鞏此,王大怒螟蒸。曰:“將戮力也也”盒使,又以即其意,不應大七嫌,與大夫俱齊少办。。項梁聞沛公左诵原,項王乃疑陳留沛公與籍斬未英妓,使者起,項王伏櫟芮欣绍赛,都廢蔓纠;不義頭。
項王聞漢羽欲得與項羽大驚曰:“
總結(jié):可以大概看出來吗蚌,越到后來學到的專用名詞越多腿倚。所以效果還是蠻好的。反正比我寫的好多了蚯妇。
源碼地址:點我