武麗芬,嚴(yán)學(xué)勇,趙 吉
(1.晉中學(xué)院 數(shù)學(xué)系,山西 晉中 030619;2.中國聯(lián)通晉中分公司,山西 晉中 030601;3.晉中學(xué)院 信息技術(shù)與工程系,山西 晉中 030619)
詩歌是人類文學(xué)皇冠上的明珠,讓機(jī)器自動(dòng)生成詩歌,在人工智能領(lǐng)域極具挑戰(zhàn)性,傳統(tǒng)的詩歌生成方法主要有Word Salada(詞語沙拉)、基于模板和模式的方法、基于遺傳算法的方法、基于摘要生成的方法、基于統(tǒng)計(jì)機(jī)器翻譯的方法。這些傳統(tǒng)方法非常依賴詩詞領(lǐng)域?qū)I(yè)知識(shí),需要專家設(shè)計(jì)大量的人工規(guī)則,對(duì)生成詩詞的格律和質(zhì)量進(jìn)行約束,同時(shí)遷移能力很差。隨著深度學(xué)習(xí)技術(shù)的發(fā)展,詩歌生成的研究進(jìn)入了一個(gè)嶄新階段,本文將唐代詩歌作為研究對(duì)象,對(duì)比了兩種遞歸神經(jīng)網(wǎng)絡(luò)模型在唐詩寫作方面的效果。
循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)具有其特有的記憶功能,是除卷積神經(jīng)網(wǎng)絡(luò)之外深度學(xué)習(xí)中使用頻率最高的一種網(wǎng)絡(luò)結(jié)構(gòu)。在傳統(tǒng)神經(jīng)網(wǎng)絡(luò)中,各個(gè)網(wǎng)絡(luò)層之間是全連接的,各層的各個(gè)神經(jīng)元是獨(dú)立無連接的,而RNN 網(wǎng)絡(luò)則能把序列化的、與時(shí)間相關(guān)的輸入數(shù)據(jù)間的關(guān)系表達(dá)出來。類似于在一句唐詩中,某個(gè)詞的出現(xiàn)必定與前幾個(gè)甚至前幾句詩中的詞有關(guān),完美狀態(tài)下這樣的循環(huán)神經(jīng)網(wǎng)絡(luò)可以記憶任意長(zhǎng)度的序列化信息,其結(jié)構(gòu)示意圖如圖1 所示,Xt為輸入數(shù)據(jù),A 為記憶單元,X0輸入到A 后得到的中間信息,再把中間信息輸給X1,以此類推。
圖1 RNN 結(jié)構(gòu)展開示意圖
LSTM 本質(zhì)是一種特殊的RNN,其優(yōu)勢(shì)在于不僅可以像RNN 一樣記憶先前輸入的數(shù)據(jù)特征,還可以選擇性遺忘一些對(duì)當(dāng)前模型預(yù)測(cè)結(jié)果作用不大的特征信息。LSTM 是由Hochreiter &Schmidhuber 提出的,之后Alex Graves 對(duì)其進(jìn)行了改進(jìn)和推廣,在處理很多與時(shí)序性相關(guān)的問題上,LSTM 模型均被證明具備突出的預(yù)測(cè)能力。RNN 訓(xùn)練參數(shù)是采用梯度下降法計(jì)算曲線的局部最小值,當(dāng)略微越過最低點(diǎn)時(shí),在梯度相反方向上會(huì)出現(xiàn)較大的梯度,這就會(huì)使得出現(xiàn)反向遠(yuǎn)離要求的局部極小值,進(jìn)入重復(fù)尋求最小值的過程[1]。隨著計(jì)算次數(shù)的增加,梯度很快減小,再次接近這個(gè)最小值需要運(yùn)算很長(zhǎng)時(shí)間,出現(xiàn)梯度消失現(xiàn)象[2],而LSTM 網(wǎng)絡(luò)很好地解決了RNN 網(wǎng)絡(luò)這一缺陷,其結(jié)構(gòu)示意圖如圖2 所示。
圖2 LSTM 示意圖
LSTM 是具有循環(huán)神經(jīng)網(wǎng)絡(luò)模塊的鏈?zhǔn)叫问絒3],在LSTM 結(jié)構(gòu)中存在3 個(gè)門單元,分別是輸入門,忘記門,輸出門[1]。如當(dāng)前層輸入數(shù)據(jù)xt進(jìn)入和上一層輸出的中間信息ht-1組合之后通過激活函數(shù)(sigmoid)得到一個(gè)ft值,這個(gè)ft值全部在0 到1 的范圍內(nèi),ft內(nèi)將會(huì)和上一層輸出的Ct-1作乘法操作組合在一起,相當(dāng)于進(jìn)行一個(gè)有選擇的丟棄。Ct是LSTM 網(wǎng)絡(luò)當(dāng)中永久維護(hù)更新的一個(gè)參數(shù),由于每一階段需要保留和丟棄的信息不一致,故每一階段都需要得出當(dāng)前階段的Ct值。上述信息組合會(huì)得到一個(gè)it,it為當(dāng)前層要保留的信息,it與Ct組合將控制參數(shù)Ct進(jìn)行更新得到新的Ct,記為nCt,接著對(duì)本層Ct進(jìn)行最終更新,更新方法為Ct=ft*Ct-1+it*nCt。更新后需要根據(jù)輸入ht-1和xt來判斷輸出的狀態(tài)特征,輸入經(jīng)過sigmoid 層得到判斷條件,然后經(jīng)過tanh 層得到一個(gè)-1 到1 之間的向量,該向量與輸出門得到的判斷條件相乘得到最終該LSTM 單元的輸出。最終輸出ht=ot*tanh(Ct),其中ot=σ(W0[ht-1,xt]+b0,為當(dāng)前層輸入數(shù)據(jù)xt和上一層輸出的中間數(shù)據(jù)ht-1組合后得到的尚未有選擇保留和遺忘的數(shù)據(jù)。
采用Python 網(wǎng)絡(luò)爬蟲技術(shù)在“全唐詩網(wǎng)”(https://www.gushiwen.org)提取目標(biāo)數(shù)據(jù),調(diào)用re.compile()方法提前編譯提取的正則表達(dá)式,避免每次提取時(shí)重新編譯導(dǎo)致效率降低,利用map()方法進(jìn)行映射操作,將各自對(duì)應(yīng)位置的元素用“:”連接起來,map 方法返回由全部唐詩字符串構(gòu)成的列表。
對(duì)爬取到的數(shù)據(jù)進(jìn)行預(yù)處理,舍棄字符串中包含的“-”“*”“_”等特殊符號(hào),并通過原詩查詢予以校正。把唐詩語料庫中出現(xiàn)的漢字組成的詞匯表導(dǎo)出到映射表,其鍵為漢字,值為該漢字映射的數(shù)值,由映射值構(gòu)成唐詩數(shù)據(jù)。
利用TensorFlow 的tf.contrib.rnn.BasicRNNCell()方法定義一個(gè)循環(huán)神經(jīng)網(wǎng)絡(luò)單元,將該單元堆疊為兩層的神經(jīng)網(wǎng)絡(luò)。根據(jù)輸出數(shù)據(jù)是否為空判斷初始化神經(jīng)網(wǎng)絡(luò)的狀態(tài),利用tf.nn.embedding_lookup()構(gòu)造輸入矩陣,得到神經(jīng)網(wǎng)絡(luò)的輸出,利用tf.nn.bias_add()將偏置項(xiàng)加到輸出矩陣和權(quán)重矩陣的乘積上,得到網(wǎng)絡(luò)最后輸出。
采用one-hot 編碼轉(zhuǎn)化,利用tf.nn.softmax_cross_entropy_with_logits()傳入真實(shí)值和預(yù)測(cè)值(即神經(jīng)網(wǎng)絡(luò)的最后輸出)計(jì)算交叉熵?fù)p失,這里得出的交叉熵?fù)p失為全部漢字的交叉熵?fù)p失,維度較高,因此利用tf.reduce_mean()將損失降維并求均值。再利用tf.train.AdamOptimizer(learning_rate).minimize(loss)進(jìn)行梯度下降最小化損失。最后將損失均值,最小化損失等op 返回供后續(xù)模型調(diào)用或訓(xùn)練使用。
利用tf.nn.softmax()方法將神經(jīng)網(wǎng)絡(luò)最后輸出轉(zhuǎn)化為各詞出現(xiàn)的概率以及神經(jīng)網(wǎng)絡(luò)當(dāng)前狀態(tài)。
創(chuàng)建名為inference 的模塊,在該模塊下創(chuàng)建名為tang_poems.py 的編碼文件,封裝一個(gè)名為run_training 的方法調(diào)用數(shù)據(jù)預(yù)處理得到的唐詩向量數(shù)據(jù)、漢字映射表及詞匯表。
在預(yù)測(cè)值漢字轉(zhuǎn)化方法中,需要傳入神經(jīng)網(wǎng)絡(luò)的最終預(yù)測(cè)值以及詞匯表,根據(jù)漢字使用頻度,定義是一個(gè)長(zhǎng)度為6030 的數(shù)組,數(shù)組元素代表對(duì)應(yīng)詞匯表中各漢字出現(xiàn)的概率。由于神經(jīng)網(wǎng)絡(luò)訓(xùn)練完成后權(quán)重矩陣一定,意味著當(dāng)輸入某個(gè)漢字時(shí),神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)出的下一個(gè)漢字是固定的。也就是說多次傳入某個(gè)漢字調(diào)用模型寫詩,模型所作的詩句是一定的。這顯然與作詩初衷不符。若讓機(jī)器能夠創(chuàng)作出不同詩句,則必須在詞預(yù)測(cè)上加入一些隨機(jī)性的因素,每次預(yù)測(cè)不選擇出現(xiàn)概率最高的漢字,而是將概率映射到一個(gè)區(qū)間上,在區(qū)間上隨機(jī)采樣,輸出概率較大的漢字對(duì)應(yīng)區(qū)間較大,被采樣的概率也較大,但程序也有小概率會(huì)選擇到其他字。
在實(shí)現(xiàn)上則需要將概率表進(jìn)行升級(jí),對(duì)概率表元素重新賦值,使其第i 個(gè)元素變?yōu)樵怕时砬癷 個(gè)元素的和,生成一個(gè)服從均勻分布在[0,1)之間的隨機(jī)值,尋找該隨機(jī)值在新概率表中的位置,將該位置作為本次預(yù)測(cè)的結(jié)果,恰好實(shí)現(xiàn)隨機(jī)又不完全隨機(jī)的目的。例如原概率表為[0.1,0.2,0.18,0.25,0.21,0.06],升級(jí)后的新概率表為[0.1,0.3,0.48,0.73,0.94,1.0],生成的隨機(jī)值為0.4,那么其在新概率表中索引到的下標(biāo)為2,也就是根據(jù)隨機(jī)值0.4 索引到概率區(qū)間[0,0.48]上,選取到該區(qū)間內(nèi)的最后一個(gè)概率值,而這個(gè)概率值又是隨機(jī)的(原概率表中各漢字對(duì)應(yīng)的概率排列并無規(guī)律可言),即本質(zhì)是在[0,0.48]這個(gè)概率區(qū)間上隨機(jī)進(jìn)行采樣。
系統(tǒng)本質(zhì)上屬于分類問題,因此采用交叉熵構(gòu)造損失函數(shù)。交叉熵公式為:L=-y*logP+-(1-y)*log(1-P)。其中y 為神經(jīng)網(wǎng)絡(luò)最后一層的輸出值,P 為該值經(jīng)過softmax 激活后的概率值,概率值越大說明預(yù)測(cè)的事件越穩(wěn)定,即熵值越低,而-logP 函數(shù)圖像恰好擬合了熵值和概率值之間的映射關(guān)系,并且每個(gè)樣本預(yù)測(cè)值為分類號(hào)0或1,0 表示預(yù)測(cè)結(jié)果不是該漢字,1 表示預(yù)測(cè)結(jié)果是該漢字。那么當(dāng)y 為0 或1 時(shí),L 中總會(huì)有一部分為0,另一部分恰好為交叉熵值,則可以一步計(jì)算出預(yù)測(cè)結(jié)果為0或1 的樣本的交叉熵?fù)p失值。
調(diào)用RNN 模型和LSTM 模型,各隨機(jī)生成20 句唐詩,在Robo 3t 下觀察RNN 與LSTM 各自作詩水平,RNN 模型平均交叉熵?fù)p失觀察結(jié)果為6.53426236 429408;LSTM模型平均交叉熵?fù)p失觀察結(jié)果為4.26054176463658。
(1)在交叉熵?fù)p失方面。LSTM 的平均交叉熵?fù)p失和最低交叉熵?fù)p失都顯著優(yōu)于RNN,RNN 的最低交叉熵?fù)p失均出現(xiàn)在第一代訓(xùn)練批次中,且在訓(xùn)練后期的損失值反而高于其平均損失,說明RNN 的損失函數(shù)在經(jīng)過前幾代訓(xùn)練后得到收斂。反觀LSTM 的最低損失多數(shù)出現(xiàn)在訓(xùn)練后期,說明其訓(xùn)練過程更加有效,隨著訓(xùn)練迭代次數(shù)不斷增加能夠持續(xù)降低損失值。
(2)在作詩水平方面。RNN 所作詩句明顯不符合作詩預(yù)期,大多為一個(gè)字或三到四個(gè)字,并未連成完整詩句。而LSTM 所作詩句不僅對(duì)仗工整,且與唐詩相似度極高。測(cè)試結(jié)果有力證明在作詩方面LSTM 模型優(yōu)于RNN模型。
通過模型測(cè)試循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)與長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)在寫詩方面的效果比較,得出LIST 模型明顯優(yōu)于RNN 模型??梢奓STM 模型善于建立時(shí)間序列數(shù)據(jù)間的非線性關(guān)系,適用于詞句的預(yù)測(cè)。RNN 神經(jīng)網(wǎng)絡(luò)的訓(xùn)練過程采用BPTT 算法,隨著遞歸層數(shù)的增加,計(jì)算梯度下降時(shí),會(huì)出現(xiàn)梯度消失和梯度爆炸問題,嚴(yán)重影響模型效果,而LSTM 則從神經(jīng)單元的結(jié)構(gòu)上對(duì)此進(jìn)行了優(yōu)化[1],大大減小了其訓(xùn)練過程中梯度消失和梯度爆炸的問題。RNN 只能夠處理短期依賴問題,而LSTM 得益于其特有的神經(jīng)元內(nèi)部結(jié)構(gòu)使之既能夠處理短期依賴問題,又能夠處理長(zhǎng)期依賴問題。在處理時(shí)序性信息時(shí)效果明顯優(yōu)于RNN,在自然語言處理應(yīng)用方面比RNN 更高效。