◆陳冰兒 勞南新
(廣東工業大學(廣州)計算機學院 廣東 510006)
流行音樂是當代華語樂壇的重要組成部分,其流行體現在日常生活的許多方面,例如:表達和傳遞個人情感、觀點態度或在各種節日場合上傳達信息。在不同類型的流行音樂中,很多歌曲之所以讓人覺得百聽不厭,一方面是由于其悅耳動聽的旋律節奏,另一面也取決于歌詞的精煉優美。作為音樂中幾乎不可缺少的一部分,歌詞和詩詞一樣,一般遵循每句末字押韻的規定,從而使歌詞在被演唱時朗朗上口,正如許嵩在其歌曲《雅俗共賞》中對歌曲創作的描述:落筆傳神還要容易傳唱、情節起伏跌宕讓人向往等。除此之外,歌詞還要表現出語言的簡潔和準確運用,吸引聽眾,激發想象力,表達情感。
盡管神經網絡在詩歌生成方面的應用比較廣泛,但在流行音樂歌詞生成中的應用還具有很大的研究空間。許嵩作為當代華語樂壇的一名原創歌手,其想象豐富、意境悠遠又富有內涵的歌詞非常值得研究。本文以許嵩專輯中的歌詞為實驗數據,整理和分析許嵩作詞的規律,采用長短期記憶網絡(Long Short-Term Memory,LSTM)模型訓練生成許嵩風格的歌詞。從而使神經網絡在現代音樂歌詞生成中得到了很好的應用,不僅有利于現代流行歌曲的發展,同時也使漢語文化在音樂詩歌方面得以更好地傳承和發揚。
自然語言處理是人工智能和語言學領域的重要分支學科,文本可用于序列建模,其在機器翻譯,語音識別,圖像字幕,語言識別,視頻字幕等方面意義重大。在自然語言處理中,文本的自動撰寫是一個重要的應用領域。序列到序列的文本生成是自動將詞語的腳本從“源系列”轉換為目標序列的最有效方法,例如由多到少的關鍵詞、關鍵短語、自動摘要提取等,以及由少到多的文本生成,包括句子的復寫,由關鍵詞、主題生成文章或者段落等。
循環神經網絡(Recurrent Neural Network,RNN)是一種從序列或時間序列數據中獲取信息的神經網絡[1]。它是前饋神經網絡的擴展,不同于一般的神經網絡結構,它可以處理可變數據長度。長短期記憶網絡是一種時間循環神經網絡,它是由Schmidhuber和Hochreiter于1997年提出的一種網絡技術[2]。它通過構造一些額外的指令來解決RNN存在的梯度消失問題,比RNN更高效。這就像是對RNN的一次升級,LSTM適用于基于序列的任務和任何類型的序列數據。RNN具有內存限制的缺陷,而LSTM在長期依賴方面沒有任何內存限制。LSTM網絡適用于分析文本數據序列并預測下一個詞語,由于其獨特的設計結構,LSTM適合于處理和預測時間序列中間隔和延遲較長的重要事件。
近年來,神經網絡在文本生成方面的應用已經取得了大量的研究成果。在過去的幾十年里,自動生成詩歌一直是一個熱門的研究課題。國內外的研究者對詩歌文本生成模型的構建也展開了相關研究。其中,He和Zhou等人利用統計機器翻譯(SMT)系統生成新的古典詩歌,并提出了一種自動評價詩歌的新方法[3]。Zhang和Lapata開展了用RNNs創作中國詩歌的工作[4],這在當時是一個很好的創舉,可以通過算法自動生成一些詩句。周昌樂等人構建了一種基于遺傳算法的宋詞生成計算模型并進行了系統實現[5],基本能夠自動生成具有一定欣賞價值的詩詞,也填補了我國當時在研究漢語詩歌自動生成方面的不足。作者梁健楠等人利用RNN自動學習古詩句的語義表示,并設計了多種方法自動計算兩句詩詞的上下文關聯性[6],使計算機具有初步模擬人類創作詩歌的能力。
由于自然語言文本從本質上來看是一種序列模型,序列模型的一個明顯特點就是前面的序列元素與后面的序列元素有著統計概率上的聯系。循環神經網絡利用其隱藏層的傳導聯系,能記錄前面的神經元信息,在序列建模上有著顯著的效果,其結構如圖1所示。

圖1 RNN時間線展開圖
由于神經網絡普遍采用梯度下降法來學習訓練,樸素的循環神經網絡隨著深度增加可能存在梯度消失或梯度爆炸等問題,這就會導致樸素的循環神經網絡訓練困難,難以收斂。既然樸素的循環神經網絡訓練困難是由于梯度消失或梯度下降導致的,那么就應該在神經元的輸入、輸出以及傳導中加入一些約束來解決這些問題。長短期記憶網絡LSTM在樸素的循環神經網絡的基礎上放置了三扇門,分別叫作輸入門、遺忘門和輸出門。當信息進入LSTM的網絡中時,可以根據規則來判斷其是否有用。只有符合算法認證的信息才被留下,不符的信息則通過遺忘門被遺忘,其結構如圖2所示。圖中看起來是三個單元格,其實是一個單元格在不同時刻的狀態。以中間的單元格為例,四個小矩形塊就是樸素神經網絡的隱藏層結構,其中三個塊的激活函數是sigmoid,第三個塊的激活函數是tanh。時刻的輸入和時刻的輸出進行拼接,然后輸入到下一個單元格中。輸入的分別進入四個小矩形塊中,每個塊中進行神經網絡中的矩陣乘法運算,有關“記憶”的部分完全由各種門結構來控制。單元格中上方橫線控制長時記憶,下方橫線控制短時記憶。

圖2 LSTM網絡展開結構圖
在實踐中,LSTM已經顯示其良好的自動生成效果,尤其在長序依賴問題中顯著優于樸素的循環神經網絡。還有LSTM的簡化變體GRU(Gated Recurrent Unit)[7],既保持了LSTM的效果,又使結構更加簡單。
本實驗采用的算法來源于深度學習研究科學家Andrej Karpathy的char-rnn模型[8],其基本思路就是把文本拆分成character-level,然后進行輸入、訓練及輸出。本實驗以中文漢字為基本單位進行模型建模,如圖3舉例所示,“如”字后面大概率會出現“果”,“傷”字后面大概率會出現“害”……

圖3 char-rnn模型示例
本實驗所用的數據集為百度文庫上搜索到的許嵩歌詞大全[9],此數據集中包含了許嵩自出道以來148首較流行歌曲的歌詞,總共7643行歌詞文本。其部分數據集展示如圖4所示。
本實驗采用Tensorflow作為主要框架,numpy進行基本數據處理,所用優化器為AdamOptimizer。需要注意的是,下載下來的txt數據集默認是ANSI編碼,需要通過“另存為”轉為UTF-8編碼,否則會編碼錯誤。

圖4 VAE_lyrics_UTF8.txt數據集部分示例
(1)class HParam()
此類用來對超參數進行設置,如batch_size、學習率、AdamOptimizer中的衰減率、衰減步數、神經網絡層數等,這些參數的選擇十分重要。模型設置的參數如表1所示。

表1 HParam()中超參數的設置
(2)class DataGenerator()
此類中的__init__()方法對文本中的漢字進行拆分并進行序號編碼,char2id()方法把字轉換成數字編碼,id2char()方法把數字編碼轉換成漢字,save_metadata()將漢字與數字編碼的映射關系存儲下來,next_batch()根據self.batch_size生成下一批訓練數據。
(3)class Model()
此類定義了模型的輸入、結構、優化器等核心結構內容。其中,with tf.name_scope()語法用于在tensorboard中可視化查看模型結構。神經單元調用了rnn_cell.BasicLSTMCell(),多層神經元調用了rnn_cell.MultiRNNCell(),損失函數調用了seq2seq.sequence_loss_by_example(),優化器調用了tf.train.AdamOptimizer()。
(4)train(data,model,args)函數
此函數定義了模型的訓練過程。其中,max_iter為最大迭代次數,每10次迭代輸出打印1次training_loss,每2000次迭代將訓練將結果存入lyrics_model.ckpt文件。
(5)sample(data,model,args)函數
此函數為模型訓練結束后生成歌詞樣例的函數。其中,tf.train.latest_checkpoint(args.log_dir)導入上面train(data,model,args)訓練出的模型和權重數據,saver.restore(sess,ckpt)恢復模型和權重數據。由于生成歌詞需要一個開始語句,prime就是預熱LSTM的初始短語,對于不同的預熱短語,很顯然會生成不一樣的歌詞樣例。因為神經網絡輸出的是數字編碼,還需要前述的id2char()將數字編碼轉換為字詞。
(6)main(infer)函數
此函數將上述的類和函數結合起來,實現訓練和生成的統一過程。其中輸入參數infer用來判斷是執行訓練還是生成過程。
(7)if__name__=='__main__'
當直接運行本代碼文件時開始執行的部分,相當于C++和Java中的Main()函數。其從用戶輸入接收一個參數infer,其中,infer=0表示進行模型訓練,infer=1表示進行數據推斷,即利用訓練好的模型和權重生成歌詞。
本實驗訓練“迭代”總次數由此公式算出:

總訓練迭代次數將近13000次,在“迭代”僅700次時,暫停查看了歌詞生成效果為類似“單單單單單單途途途途途途途途”等的語句。可見在訓練迭代次數不足時,只能生成重復無意義的詞句。
在完成近13000次迭代訓練后,下面為使用“有何不可”作為預熱詞的生成詞句效果。
煙火綻放的角落
我只是有一種像彩虹折翼的感覺
沒有一次去出現
但不能看到我的心聲
我的想法高遠
我的善良梯田
我們的故事不再安靜
孤獨的我已墜入愛河
我只想給你解憂,兩個人一起
我們的故事不能遺忘
我們的故事感覺永遠都如初見
一個人的旅途
某個晚上像窗簾后你拉著我的手……
由此可見模型已經能生成比較豐富,初具許嵩風格特征的詞句,盡管可能存在部分意義混亂。
訓練的損失值下降過程用tensorboard可視化后,在整個訓練過程中損失值在穩步下降,逐漸收斂。由于本實驗采用AdamOptimizer,因此學習率也在穩步衰減。模型訓練結束后可認為生成了字嵌入向量,用tensorboard的projector.visualize_embeddings進行可視化,其結果如圖5所示,可見意義相近、同時出現概率越高的字在向量空間中距離也越近。

圖5字嵌入可視化
由上述的效果圖我們可以看到,盡管我們的LSTM模型生成的歌詞已比較豐富,初具許嵩歌詞意境悠遠的風格特征,但仔細觀察則會發現仍然存在一些意義不明、上下混亂、邏輯不一致的字詞組合。在某些情況下生成的歌詞甚至會進入無意義的多次循環,導致循環異常。如當使用“曹操”作為預熱詞時,生成的歌詞會進入十幾次“我們的故事”的循環,這明顯不是我們想要的效果。
針對以上問題我們提出下述的未來改進方向:
(1)本實驗采用字作為基本單位,但詞語也許是更合理的基本語義單位,考慮使用著名的結巴分詞,以詞為基本單位進行輸入、訓練及輸出;
(2)實驗采用了序號對字進行編碼,并沒有使用前沿的詞向量,因此考慮使用前沿的其他學者訓練好的詞向量對詞進行編碼;
(3)對多次循環的異常進行判斷并跳出;
(4)“數據集”需要清洗,統一格式標準,去除異常符號,以免“臟數據”誤導模型;
(5)嘗試加入生成對抗學習,看能否生成更逼真的歌詞分布;
(6)對參數進行微調,看是否能改進模型生成歌詞的效果。
本文對循環神經網絡中長短期記憶網絡進行研究,基于Google的Tensorflow深度學習框架設計生成許嵩風格歌詞的網絡模型。使用許嵩以往專輯中自己作詞的歌曲作為訓練數據進行模型的訓練,訓練后的模型能夠較好地模擬生成許嵩風格的歌詞。