天天看點

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

目錄

seq2seq模型核心思想

遞歸神經網絡RNN

解碼和編碼過程

模型擴充

模型應用領域

搭建自己的模型

春節貼春聯是中國人慶祝春節(過年)的特有習俗。但我真正對對聯有些認識和喜歡,不是從年年貼春聯開始的,而是從《唐伯虎點秋香》那段經典的對對子開始的。那工整又有韻律和意境的對子,配上有節奏的配樂讀出來着實讓人熱血沸騰,大呼過瘾。

先來回味一下這段台詞吧,你的耳邊是否響起了對對子的節奏。。。

對穿腸:一鄉二裡共三夫子,不識四書五經六義,竟敢教七八九子,十分大膽!

甯王:對啊,怎麼不對呢?你不給我面子,我可真的要發飙了!

唐伯虎:讓我來試試! 十室九貧,湊得八兩七錢六分五毫四厘,尚且三心二意,一等下流!

對穿腸:好工整啊!
華太師:華安,你來的正是時候。
唐伯虎:沒事,沒事,沒事。
對穿腸:在下是七省文狀元兼參謀将軍,綽号對王之王的對穿腸。閣下是?
唐伯虎:小弟讀過兩年書,塵世中一個迷途小書僮,華安。
對穿腸:好!我就來會一會你!
(兩人互相凝視,蓄勢待發,突然......親了一下......衆人跌倒在地!)
唐伯虎:對不起,我倆惺惺相惜,情不自禁。
對穿腸:言歸正傳,我們開始了。
圖書裡,龍不吟虎不嘯,小小書僮可笑可笑。
唐伯虎:棋盤裡,車無輪馬無韁,叫聲将軍提防提防。
衆 人:對得好!對得好!
對穿腸:莺莺燕燕翠翠紅紅處處融融洽洽。
唐伯虎:雨雨風風花花葉葉年年暮暮朝朝。
衆 人:華安真行啊!對得好!
甯 王:快出對子對死他,對死他!
對穿腸:十口心思,思君思國思社稷。
唐伯虎:八目共賞,賞花賞月賞秋香。
對穿腸:我上等威風,顯現一身虎膽。
唐伯虎:你下流賤格,露出半個龜頭。
對穿腸:我堂堂參謀将軍會輸給你個書僮? 你家墳頭來種樹。
唐伯虎:汝家澡盆雜配魚。
對穿腸:魚肥果熟入我肚。
唐伯虎:你老娘來親下廚!
(對穿腸倒地噴血)
唐伯虎:對對本為消遣作樂,今曰穿腸兄居然對到嘔出幾十兩血,可謂空前絕後,小弟佩服佩服!      

十年前,微軟亞洲研究院推出了一個對聯生成引擎,可以根據使用者輸入的上聯自動生成下聯,當時火了一把。那時候覺得這個好神奇啊。

十年後,人工智能的風已經熱吹了幾年。随着硬體GPU計算能力的提升,和深度學習架構(TensorFlow,PyTorch,MxNet等等)的推出和發展,人工智能(其實就是更深層的機器學習)首先在圖像處理領域大放異彩,人臉識别、物體檢測等技術應用廣泛。然而,在自然語言處理處理方面,深度學習的應用還沒有圖像處理那麼成熟。不過,人工智能作古詩,對對子應用的看起來還不錯。

快過年了,貼對聯是必不可少的傳統風俗。不知道各位小夥伴有沒有自己寫過對聯呢?寫對聯可不是一件簡單的事情,如果不是滿腹經綸絕難出口成章啊。最近我就發現了一個對對聯的開源項目,絕對有才。

将試用網站分享給各位小夥伴,可以線上感受下AI機智對對聯(建議用Google浏覽器):

https://ai.binwang.me/couplet/

效果圖如下:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

怎麼樣,對的還算工整吧,就是在專業領域不具有專業特色。

AI對對聯項目,使用seq2seq模型,基于深度學習架構Tensorflow使用Python 3.6開發,作者是王斌一位軟體工程師,一位極具才情的程式員。下面咱們就解析seq2seq模型原理機制。

對于一些自然語言處理任務,比如聊天機器人,機器翻譯,自動文摘等,傳統的方法都是從候選集中選出答案,這對素材的完善程度要求很高,随着最近幾年深度學習的興起,國外學者将深度學習技術應用與自然語言的生成和自然語言的了解的方面的研究,并取得了一些突破性的成果,比如,Sequence-to-sequence (seq2seq) 模型,它是目前自然語言處理技術中非常重要而且非常流行的一個模型,該技術突破了傳統的固定大小輸入問題架構,開通了将經典深度神經網絡模型運用于翻譯與職能問答這一類序列型任務的先河,并且被證明在各主流語言之間的互相翻譯以及語音助手中人機短問快答的應用中有着非常好的表現,下面給大家簡要介紹一下關于seq2seq模型的一些細節。

seq2seq模型是在2014年,是由Google Brain團隊和Yoshua Bengio 兩個團隊各自獨立的提出來[1] 和 [2],他們發表的文章主要關注的是機器翻譯相關的問題。而seq2seq模型,簡單來說就是一個翻譯模型,把一個語言序列翻譯成另一種語言序列,整個處理過程是通過使用深度神經網絡( LSTM (長短記憶網絡),或者RNN (遞歸神經網絡)前面的文章已經詳細的介紹過,這裡就不再詳細介紹) 将一個序列作為輸入影射為另外一個輸出序列,如下圖所示:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

上圖已經是在時間次元上進行了展開,對于沒有展開的情況下,一般左邊使用一個神經網絡,接收輸入序列"A B C EOS ( EOS=End of Sentence,句末标記)", 在這個過程中每一個時間點接收一個詞或者字,并在讀取的EOS時終止接受輸入,最後輸出一個向量作為輸入序列的語義表示向量,這一過程也被稱為編碼(Encoder)過程,而第二個神經網絡接收到第一個神經網絡産生的輸出向量後輸出相應的輸出語義向量,并且在這個時候每一個時刻輸出詞的機率都與前一個時刻的輸出有關系,模型會将這些序列一次映射為"W X Y Z EOS",這一過程也被稱為解碼 (Decoder)過程,這樣就實作了句子的翻譯過程。整個過程的結構就像下圖一樣:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

下面以文章[1]的内容為主介紹一下該過程中相關的一些數學公式和結果。

在Yoshua Bengio文章中使用的是RNN網絡作為基本的神經網絡對輸入序列和輸出序列進行學習。這裡給一個基本的介紹,如下圖所示:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

其中h是隐藏層,y是輸出層,輸入是一個時間序列x = (x1, x2, ..., xT), 對于每一個時間t,RNN中隐藏層的h的更新由下面的表達式決定:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

f是一個非線性的激活函數,f可以是tanh或者sigmoid函數。

RNN網絡可以通過學習整個輸入序列的機率分布來對下一個字或者詞進行預測,在這種情況下,對于時間t時,其機率分布為P(xt| xt-1, ...., x1), 之後再根據其分布去推測新的字或者詞的機率,比如說對于最後使用softmax函數對輸出進行變換之後,得到如下表達式:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

對j周遊詞袋中可能的值,這一就就可以得到每個字或者詞在下一個時間出現的是機率值。

在文章中整個模型圖為如下圖所示:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

整個模型和第一部分介紹的類似,整個模型分為解碼和編碼的過程,編碼的過程結束後悔輸出一個語義向量c,之後整個解碼過程根據c進行相應的學習輸出。

對于整個編碼的過程就是上面第二部分介紹的RNN網絡學習的的過程,最後輸出一個向量c。而對于解碼過程,對應的是另外一個RNN網絡,其隐藏層狀态在t時刻的更新根據如下方程進行更新:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

除了新加了c變量以外,其它和RNN原本的函數關系是一樣的。類似的條件機率公式可以寫為:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

對于整個輸入編碼和解碼的過程中,文行中使用梯度優化算法以及最大似然條件機率為損失函數去進行模型的訓練和優化:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

其中sita為相應模型中的參數,(xn, yn)是相應的輸入和輸出的序列。

總的來說,上面介紹的模型是最簡單的模型,對于解碼和編碼的過程使用的是一層的RNN,Google 團隊[1]使用的起初也是一層的LSTM模型,後面有一篇文章提出的對Encoder和Decoder部分使用多層的LSTM,其原理和1層的RNN是一樣的。如下圖所示:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

其實對于這種encoder和decoder的模型,有一個問題是:起始的時間序列被編碼轉化成語義向量c,之後再被解碼,那麼一開始的資訊經過長時間的從左往右傳播已經丢失了很多,而最後編碼的資訊也是在最後解碼,是以文章[3]中提出,在對輸入的序列編碼時,使用倒序輸入,也就是原始的輸入順序為"A B C"的,那麼新的方式編碼的輸入方式為 "C B A" ,這樣A編碼成c之後,就會馬上進行解碼,這樣丢失的資訊就沒有之前那麼多,經過這樣的處理之後,取得了很大的提升,而且這樣處理使得模型能夠很好的處理長句子。

上面的方法雖然有一定的改善,但是對于輸入詞C來講,資訊丢失的依舊很厲害,是以未來解決這一缺點,Bahdanu等人提出在Encoder和Decoder的基礎上提出了注意力機制。在上面的模型結構中,每次預測都是從語義向量c中進行資訊提取,在含有注意力機制的模型結構中,除了對最後的語義向量進行提取資訊,還會對每一時刻的ht輸出的結果進行資訊的提取,這樣Encoder過程中的隐藏狀态都被利用上了。如下圖所示:

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

其中ct和at為注意力層,對每一個隐藏層的狀态都提取相應的資訊,之後再将整體的資訊給編碼層。

上面基本上已經介紹完了seq2seq模型,接下來看看該模型可以在那些領域應用。首先作為為機器翻譯問題為出發點提出來的seq2seq模型,機器翻譯的準确率因為該模型的提出而有了較大的提升。

作為seq2seq模型研發團隊,Google Brain團隊在2014年的文章[5]的應用案例中對LSTm的隐藏結點做了主成分分析,如下圖所示,從圖中可以看出,模型中的語境向量很明顯包涵了輸入序列的語言意義,後溝将不同次序所産的的不同意思的語句劃分開,這對于提升機器翻譯的準确率很有幫助。

自然語言處理seq2seq模型實作人工智能對對聯(基于TensorFlow架構)

其次seq2seq模型因為突破了傳統的固定大小輸入問題架構,因而除了翻譯場景,還被用于智能對話與問答的實作以及微網誌的自動回複,2015年華為團隊,通過seq2seq為基礎設計的模型實作了計算機對微網誌的自動回複,并通過模型間的對比得到了一系列有意思的結果。

搭建自己的對對聯模型

了解原理後,小夥伴們可以在GitHub下載下傳、編譯運作并訓練該項目:

https://github.com/wb14123/seq2seq-couplet

這個作者提供了70萬條對聯的資料,有了這個資料就可以訓練我們自己的模型了。

做深度學習訓練是最考驗硬體的,必須上GPU,不然訓練可能要一兩個月才能完成。通常深度學習的系統環境是這樣的:

CPU:現在正常的已經足夠,計算主要靠GPU;

記憶體:至少16GB,越多越好;

GPU: NVIDIA,至少是gtx-1060吧。目前最具成本效益的是gtx-1080 Ti

OS: Ubuntu 16.04 (普遍使用的版本)

Python: Python 3.6 版 (2.x的版本用的很少了)

深度學習架構: TensorFlow、PyTorch和MxNet最流行

訓練的過程很漫長...最終訓練了一周。搞人工智能的活兒沒點兒像樣的硬體,還真耗不起青春啊。訓練期間,有足夠的時間去完成其它的功能。

使用GitHub中的Server.py程式即可實作模型訓練。

from flask import Flask, jsonify, request
from flask_cors import CORS, cross_origin
from model import Model
from gevent.wsgi import WSGIServer
import logging
app = Flask(__name__)
CORS(app)
vocab_file = '/data/dl-data/couplet/vocabs'
model_dir = '/data/dl-data/models/tf-lib/output_couplet_prod'
m = Model(
        None, None, None, None, vocab_file,
        num_units=1024, layers=4, dropout=0.2,
        batch_size=32, learning_rate=0.0001,
        output_dir=model_dir,
        restore_model=True, init_train=False, init_infer=True)
@app.route('/chat/couplet/<in_str>')
def chat_couplet(in_str):
    if len(in_str) == 0 or len(in_str) > 50:
        output = u'您的輸入太長了'
    else:
        output = m.infer(' '.join(in_str))
        output = ''.join(output.split(' '))
    print('上聯:%s;下聯:%s' % (in_str, output))
    return jsonify({'output': output})
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()      

給小夥伴們分享一個拓展項目,用Python進行詩歌接龍:

https://blog.csdn.net/m0_38106923/article/details/87873666

繼續閱讀