張正旺
【摘 要】古詩(shī)是中華民族的文化瑰寶?;赥ransformer模型,利用開源的深度學(xué)習(xí)庫(kù)Tensor2Tensor,僅需編寫幾十行代碼即可創(chuàng)建出一個(gè)寫詩(shī)機(jī)器人。結(jié)果表明,該寫詩(shī)機(jī)器人能夠?qū)懗龈袷揭?guī)范,頗具意境的七言古詩(shī)。
【關(guān)鍵詞】Transformer模型;深度學(xué)習(xí);Tensor2Tensor;寫詩(shī)機(jī)器人
中圖分類號(hào):TP183 文獻(xiàn)標(biāo)識(shí)碼: A 文章編號(hào): 2095-2457(2018)33-0004-003
DOI:10.19694/j.cnki.issn2095-2457.2018.33.002
【Abstract】Ancient poetry is a cultural treasure of the Chinese nation. Based on the Transformer model and using the open source deep learning library Tensor2Tensor, a poetry writing robot can be created with only dozens of lines of code. The result shows that the poem writing robot can write seven-character ancient poetry with standard format and artistic conception.
【Key words】Transformer model; Deep learning; Tensor2Tensor; Writing robot
0 引言
古詩(shī)是中華民族的文化瑰寶,其結(jié)構(gòu)精練,韻律優(yōu)美,意境高雅,具有穿越歷史時(shí)空的創(chuàng)造力、影響力和吸引力,眾多古詩(shī)流傳至今并仍讓我們深深為之著迷。人工智能(Artificial Intelligence),簡(jiǎn)稱AI,其研究始于1956年的達(dá)特茅斯會(huì)議,與歷史悠久的古詩(shī)相比,人工智能是一項(xiàng)非常年輕的技術(shù)。隨著大數(shù)據(jù)的積累和計(jì)算機(jī)軟硬件性能的提升,人工智能在各領(lǐng)域展現(xiàn)出極為廣闊的發(fā)展和應(yīng)用空間。深度學(xué)習(xí)是機(jī)器學(xué)習(xí)的一個(gè)分支,是現(xiàn)階段實(shí)現(xiàn)人工智能的一種主要技術(shù)手段。深度學(xué)習(xí)的應(yīng)用場(chǎng)景主要有:圖像識(shí)別與處理、目標(biāo)檢測(cè)、語(yǔ)音識(shí)別、自動(dòng)駕駛、自然語(yǔ)言處理等?;谏疃葘W(xué)習(xí),利用自然語(yǔ)言處理相關(guān)技術(shù),可以將計(jì)算機(jī)訓(xùn)練成一個(gè)寫詩(shī)機(jī)器機(jī)器人,讓計(jì)算機(jī)自動(dòng)生成格式規(guī)范的古詩(shī)。
1 研究現(xiàn)狀
近年來,隨著深度學(xué)習(xí)的快速發(fā)展,利用基于深度學(xué)習(xí)的自然語(yǔ)言處理技術(shù)自動(dòng)生成古詩(shī)的研究得到了學(xué)術(shù)界的廣泛關(guān)注。桂林電子科技大學(xué)的黃文明等[1]采用一種基于注意力機(jī)制的序列到序列模型得到作詩(shī)大綱,然后利用具有雙編碼器和注意力機(jī)制的序列到序列模型順序地生成詩(shī)的每一行。北京郵電大學(xué)的李爭(zhēng)[2]基于遞歸神經(jīng)網(wǎng)絡(luò)的古詩(shī)自動(dòng)生成模型能夠在給定關(guān)鍵詞的情況下自動(dòng)生成與其語(yǔ)義相關(guān)的古詩(shī)內(nèi)容。中國(guó)科學(xué)技術(shù)大學(xué)的蔣亮[3]設(shè)計(jì)了一種基于記憶的深度神經(jīng)網(wǎng)絡(luò)模型自動(dòng)基于圖片生成中國(guó)古詩(shī),該模型可以很有效地挖掘圖片中的視覺信息及語(yǔ)義信息。清華大學(xué)的Yi Xiaoyuan等[4]將古詩(shī)句的生成看作一個(gè)序列到序列的學(xué)習(xí)問題,基于遞歸神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,RNN)的Encoder-Decoder模型,構(gòu)建了一個(gè)以關(guān)鍵詞為輸入四行詩(shī)自動(dòng)生成系統(tǒng),該系統(tǒng)能學(xué)習(xí)詩(shī)中單行的語(yǔ)義、行與行之間的語(yǔ)義相關(guān)性及結(jié)構(gòu)、平仄模式的使用。愛丁堡大學(xué)的Zhang Xingxing等[5]提出了一種基于遞歸神經(jīng)網(wǎng)絡(luò)(RNN)的詩(shī)歌生成模型,該模型非常善于捕捉和學(xué)習(xí)詩(shī)歌的內(nèi)容和形式。
這些研究多數(shù)基于傳統(tǒng)的RNN模型,均可自動(dòng)生成格式規(guī)范的古詩(shī),但他們都需要研究者自己編寫大量代碼來完成系統(tǒng)的開發(fā)。GOOGLE大腦的研究人員[6]于2017年提出了一個(gè)摒棄了RNN結(jié)構(gòu),完全基于注意力機(jī)制的Transformer模型,隨后他們開源了一個(gè)基于Tensorflow框架的深度學(xué)習(xí)庫(kù)Tensor2Tensor,該庫(kù)提供了用于自然語(yǔ)言處理的Transformer模型。利用這個(gè)深度學(xué)習(xí)庫(kù),基于Transformer模型,僅需編寫少量代碼,即可簡(jiǎn)單快捷地訓(xùn)練出一個(gè)會(huì)寫詩(shī)的人工智能機(jī)器人。
2 Transformer模型簡(jiǎn)介
古詩(shī)自動(dòng)生成是一個(gè)序列到序列問題,目前處理這類問題較為有效的框架為Encoder-Decoder模型,該模型的結(jié)構(gòu)如圖1所示。模型中的Encoder部分采用GRU(Gated Recurrent Unit)、LSTM(Long Short-Term Memory)等遞歸神經(jīng)網(wǎng)絡(luò),卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN),以及RNN或CNN與注意力機(jī)制(Attention)相結(jié)合等機(jī)制學(xué)習(xí)源序列,得到一個(gè)固定長(zhǎng)度的向量表達(dá)式;模型中的Decoder部分以該向量表達(dá)式為輸入,采用類似與Encoder的機(jī)制學(xué)習(xí),得到目標(biāo)序列。如圖1中的“羌笛何需怨楊柳”經(jīng)過Encoder后轉(zhuǎn)變?yōu)轭愃朴冢?.5,0.2,0.1,-0.6,-0.4,1.0,1.2,0.8)的向量,Decoder以這個(gè)向量作為輸入,最終可習(xí)得下一句詩(shī)“春風(fēng)不渡玉門關(guān)”。
Transformer是一種處理序列到序列問題的新模型,其仍然沿用了經(jīng)典的Encoder-Decoder結(jié)構(gòu),但不再使用RNN或CNN進(jìn)行序列建模,而是完全使用自我注意力(self-attention)制。GOOGLE研究的結(jié)果表明,與RNN或CNN等結(jié)構(gòu)相比,Transformer模型可以在減少計(jì)算量和提高并行效率的同時(shí)獲得更好的學(xué)習(xí)效果,其結(jié)構(gòu)如圖2所示[6]。
Transformer模型的Encoder部分由Nx個(gè)(Nx=6)相同的層堆疊而成,每一層有兩個(gè)子層,第一個(gè)子層是多頭自我注意力層(Multi-head Attention),第二個(gè)子層是密集型全連接前饋網(wǎng)絡(luò)層(Feed Forward Network),每個(gè)子層中均使用一次殘差連接。Decoder部分的結(jié)構(gòu)與Encoder相似,也是由6個(gè)完全相同的層堆疊組成,每一層除了包括Multi-Head Attention子層和Feed Forward Network子層外,還有一個(gè)遮擋式多頭自我注意力層(Masked Multi-Head Attention),每個(gè)子層中也使用一次殘差連接。
3 利用Transformer模型創(chuàng)建寫詩(shī)機(jī)器人
Tensor2Tensor深度學(xué)習(xí)庫(kù)封裝了大量常見數(shù)據(jù)集和一些典型深度學(xué)習(xí)問題,并提供了相應(yīng)模型用于解決各類問題,目前可直接解決的問題有:圖像分類,語(yǔ)言模型、情感分析、語(yǔ)音識(shí)別、文本摘要,機(jī)器翻譯等,利用庫(kù)中所提供的模型還可以處理自行創(chuàng)建的各類新問題。寫詩(shī)機(jī)器人需要用到Tensor2Tensor提供的Transformer模型。
3.1 數(shù)據(jù)準(zhǔn)備
七言古詩(shī)簡(jiǎn)稱七古,是古詩(shī)中形式最活潑、體裁最多樣、句法和韻腳處理最自由,抒情敘事最富有表現(xiàn)力的一種形式,詩(shī)體全篇每句七字或以七字句為主[7]。真正意義的七古成熟于唐朝,盛行于唐宋代。為方便訓(xùn)練,訓(xùn)練采用的數(shù)據(jù)集為唐宋兩代的七言絕句。數(shù)據(jù)來源于Github上由Werner[8]收集的中國(guó)古詩(shī)詞數(shù)據(jù)庫(kù),該數(shù)據(jù)庫(kù)共收錄了從先秦到現(xiàn)代的共計(jì)85萬余首古詩(shī)詞。利用Python語(yǔ)句從與唐宋詩(shī)詞有關(guān)的五個(gè)CSV文件中提取出共79292首七言絕句作為訓(xùn)練數(shù)據(jù)集。
3.2 定義問題與數(shù)據(jù)處理
在Tensor2Tensor中利用Transformer模型處理古詩(shī)自動(dòng)生成問題,需要先編寫一個(gè)定義新問題的名為chinese_poetry.py的Python文件,代碼如下:
# coding=utf-8
from tensor2tensor.utils import registry
from tensor2tensor.data_generators import problem,text_problems
import re
@registry.register_problem
class ChinesePoetry(text_problems.Text2TextProblem):
@property
def approx_vocab_size(self):
return 2**15
@property
def is_generate_per_split(self):
return False
@property
def dataset_splits(self):
return[{"split": problem.DatasetSplit.TRAIN, "shards": 9,},
{"split": problem.DatasetSplit.EVAL, "shards": 1, }]
def generate_samples(self, data_dir, tmp_dir, dataset_split):
with open('./ml/data/tang7.txt') as opf:
for line in opf:
line = re.sub('。', ',', line, count=1)
line = re.sub('?', ',', line, count=1)
newline = line.split(',')
for i in range(3):
prev_line = newline[i]
curr_line = newline[i+1]
yield{"inputs": prev_line, "targets": curr_line}
將chinese_poetry.py保存在chinese_poetry目錄下,并在該目錄下再創(chuàng)建一個(gè)名為__init__.py的Python文件,該文件只包含一句代碼:from . import chinese_poetry。
古詩(shī)自動(dòng)生成問題類似于機(jī)器翻譯,是一個(gè)監(jiān)督學(xué)習(xí)問題,計(jì)算機(jī)在學(xué)習(xí)大量的詩(shī)句對(duì)后,能夠根據(jù)一句詩(shī)自動(dòng)生成下一句。每首七言絕句可生成三個(gè)數(shù)據(jù)樣本:(1)以詩(shī)的第一行作為輸入序列,第二行作為目標(biāo)序列;(2)以詩(shī)的第二行作為輸入序列,第三行作為目標(biāo)序列;(3)以詩(shī)的第三行作為輸入序列,第四行作為目標(biāo)序列。安裝好Tensor2Tensor深度學(xué)習(xí)庫(kù)后,利用下列Tensor2Tensor命令根據(jù)原始數(shù)據(jù)(79292首七言絕句)生成237876對(duì)TFRecord格式的數(shù)據(jù)樣本:
t2t-datagen --t2t_usr_dir=chinese_poetry \
--problem=chinese_poetry \
--data_dir=chinese_poetry/data
3.3 訓(xùn)練
訓(xùn)練所使用機(jī)器配置如下:32G內(nèi)存,8G顯存的GTX 1070顯卡。訓(xùn)練所使用的命令如下:
t2t-trainer --t2t_usr_dir=chinese_poetry --problem=chinese_poetry \
--data_dir=chinese_poetry/data --output_dir=chinese_
poetry/train \
--model=transformer --hparams_set=transformer_base_
single_gpu \
--schedule=train --train_steps=500000
上述指令表示訓(xùn)練數(shù)據(jù)所采用的模型為Transformer模型,所采用的超參數(shù)集為 transformer_base_single_gpu,訓(xùn)練步數(shù)50萬步。在訓(xùn)練了兩天又七個(gè)多小時(shí)后,一共訓(xùn)練了361800步,結(jié)果已基本收斂,因此停止繼續(xù)訓(xùn)練。
3.4 測(cè)試
訓(xùn)練好的模型就是一臺(tái)寫詩(shī)機(jī)器人,只需要給訓(xùn)練好的模型提供一行詩(shī)句,模型即可自動(dòng)生成下一句。Tensor2Tensor提供了t2t-decoder這個(gè)命令來完成此類動(dòng)作。完整指令如下:
t2t-decoder --t2t_usr_dir=chinese_poetry --problem=chinese_poetry \
--data_dir=Chinese_poetry/data --output_dir=Chin-
ese_poetry/train \
--model=transformer --hparams_set=transformer_
base_single_gpu \
--decode_hparams="beam_size=4,alpha=0.6" \
--decode_from_file=Chinese_poetry/poetry.txt
以杜甫《聞官軍收河南河北》(這首詩(shī)不在訓(xùn)練集中)這首七律的首句“劍外忽傳收薊北”作為詩(shī)的第一句,讓訓(xùn)練出來的寫詩(shī)機(jī)器人相繼生成后續(xù)詩(shī)句,結(jié)果如圖3所示。
輸入“劍外忽傳收薊北”后,計(jì)算機(jī)生成的下一句為“又煩前送相公歸”;輸入變?yōu)椤坝譄┣八拖喙珰w”,計(jì)算機(jī)生成“人間父子無窮勝”;以“人間父子無窮勝”為輸入序列,輸出結(jié)果為“筆下明明開辟初”。從生成結(jié)果來看,生成的古詩(shī)非常規(guī)范,亦頗有意境,描述了一幅戰(zhàn)后親人即將團(tuán)聚的景象。
4 討論與結(jié)語(yǔ)
通過與訓(xùn)練數(shù)據(jù)對(duì)比可以發(fā)現(xiàn),上面生成的最后一行詩(shī)“筆下明明開辟初”完完全全來自于訓(xùn)練數(shù)據(jù),其原因可能是因?yàn)閿?shù)據(jù)量不夠,訓(xùn)練時(shí)出現(xiàn)過擬合現(xiàn)象。為了防止訓(xùn)練數(shù)據(jù)里詩(shī)句被寫詩(shī)機(jī)器人原樣照抄,減少過擬合,除了增大訓(xùn)練數(shù)據(jù)量外,還可調(diào)整模型中的一些正則化超參的值,如Dropout值等,后期也應(yīng)該增加一些防剽竊處理措施。此外,此寫詩(shī)機(jī)器人僅僅依據(jù)詩(shī)的上一句來生成下一句,訓(xùn)練后容易導(dǎo)致寫出來的詩(shī)主題不明確,內(nèi)容不清晰。因此,對(duì)于七言絕句而言,可以通過如下兩種方式增加訓(xùn)練樣本:(1)以詩(shī)的第一行加第二行作為輸入序列,第三行作為目標(biāo)序列;(2)以詩(shī)的一二三行作為輸入序列,第四行作為目標(biāo)序列。
在技術(shù)進(jìn)步的引導(dǎo)下,在國(guó)內(nèi)外眾多大公司的鼎力支持下,深度學(xué)習(xí)系統(tǒng)的開發(fā)逐漸趨于平民化,即不需要具備很強(qiáng)的人工智能專業(yè)背景,也可利用現(xiàn)成的框架開發(fā)出具有實(shí)用價(jià)值的深度學(xué)習(xí)系統(tǒng),深度學(xué)習(xí)模型的使用門檻越來越低,深度學(xué)習(xí)技術(shù)的使用變得越來越簡(jiǎn)單。如前所示,寥寥幾十行代碼,即可借助Tensor2Tensor深度學(xué)習(xí)庫(kù)開發(fā)出一個(gè)人工智能寫詩(shī)機(jī)器人,但要想獲得比較好的學(xué)習(xí)結(jié)果,讓系統(tǒng)能真正寫出比較完美的古詩(shī),還有大量的工作可做。
【參考文獻(xiàn)】
[1]黃文明, 衛(wèi)萬成與鄧珍榮, 基于序列到序列神經(jīng)網(wǎng)絡(luò)模型的古詩(shī)自動(dòng)生成方法. 計(jì)算機(jī)應(yīng)用研究: 第1-7頁(yè).
[2]李爭(zhēng), 基于神經(jīng)網(wǎng)絡(luò)的古詩(shī)詞自動(dòng)生成研究, 2018, 北京郵電大學(xué). 第 1-66頁(yè).
[3]蔣亮, 深度神經(jīng)網(wǎng)絡(luò)在基于圖片生成中國(guó)古詩(shī)問題中的研究與應(yīng)用, 2018, 中國(guó)科學(xué)技術(shù)大學(xué). 第1-67頁(yè).
[4]Yi Xiaoyuan, Li Ruoyu, Sun Maosong. Generating Chinese classical poems with RNN encoder-decoder. (2016-04-06). https://arxiv.org/abs/1604.01537.
[5]Zhang Xingxing, Mirella L. Chinese poetry generation with recurrent neural networks. Proc of Conference on Empirical Methods in Natural Language Processing. October 25-29, 2014, Doha, Qatar.
[6]Ashish Vaswani, Noam Shazeer, Niki Parmar, et.al. Attention Is All You Need. 31st Conference on Neural Information Processing Systems (NIPS 2017), Long Beach, CA, USA.
[7]百度百科. https://baike.baidu.com/item/七言古詩(shī).
[8]https://github.com/werner-wiki/Poetry.