keras基於CNN和序列標註的對聯機器人

動手 #
「對對聯」,咱們能夠當作是一個句子生成任務,能夠用seq2seq完成
分析 #
然而,咱們再細想一下就會發現,相對於通常的句子生成任務,「對對聯」有規律得多:一、上聯和下聯的字數同樣;二、上聯和下聯的每個字幾乎都有對應關係。如此一來,其實對對聯能夠直接當作一個序列標註任務,跟分詞、命名實體識別等同樣的作法便可。這即是本文的出發點。python

說到這,其實本文就沒有什麼技術含量了,序列標註已是再普通不過的任務了,遠比通常的seq2seq來得簡單。所謂序列標註,就是指輸入一個向量序列,而後輸出另一個一般長度的向量序列,最後對這個序列的「每一幀」進行分類。相關概念來能夠在《簡明條件隨機場CRF介紹(附帶純Keras實現)》一文進一步瞭解。git

模型 #
本文直接邊寫代碼邊介紹模型。若是須要進一步瞭解背後的基礎知識的讀者,還能夠參考《【中文分詞系列】 4. 基於雙向LSTM的seq2seq字標註》、《【中文分詞系列】 6. 基於全卷積網絡的中文分詞》、《基於CNN和VAE的做詩機器人:隨機成詩》。github

咱們所用的模型代碼以下:網絡

x_in = Input(shape=(None,))
x = x_in
x = Embedding(len(chars)+1, char_size)(x)
x = Dropout(0.25)(x)

x = gated_resnet(x)
x = gated_resnet(x)
x = gated_resnet(x)
x = gated_resnet(x)
x = gated_resnet(x)
x = gated_resnet(x)

x = Dense(len(chars)+1, activation='softmax')(x)

model = Model(x_in, x)
model.compile(loss='sparse_categorical_crossentropy',
              optimizer='adam')

其中gated_resnet是筆者定義的門卷積模塊(在《基於CNN的閱讀理解式問答模型:DGCNN》一文也介紹過這個模塊):app

def gated_resnet(x, ksize=3):
    # 門卷積 + 殘差
    x_dim = K.int_shape(x)[-1]
    xo = Conv1D(x_dim*2, ksize, padding='same')(x)
    return Lambda(lambda x: x[0] * K.sigmoid(x[1][..., :x_dim]) \
                            + x[1][..., x_dim:] * K.sigmoid(-x[1][..., :x_dim]))([x, xo])

僅此而已~ide

就這樣完了,剩下的都是數據預處理的事情了。固然,讀者也能夠嘗試也能夠把gated_resnet換成普通的雙向LSTM,但我實驗中發現雙向LSTM並無gated_resnet效果好,並且LSTM相對來講也更慢,因此LSTM在這裏就被拋棄了。ui

效果 #
訓練的數據集來自:https://github.com/wb14123/couplet-dataset,感謝做者的整理spa

完整代碼:
https://github.com/bojone/seq2seq/blob/master/couplet_by_seq_tagging.pycode

訓練過程:
對聯機器人訓練過程
對聯機器人訓練過程get

部分效果:

上聯:晚風搖樹樹還挺,下聯:夜雨敲花花更香

上聯:今每天氣不錯,下聯:昨日人情無明

上聯:魚躍此時海,下聯:鳥鳴何日人

上聯:只有香如故,下聯:不無月若新

上聯:科學空間,下聯:文明大中

看起來仍是有點味道的。注意「晚風搖樹樹還挺」是訓練集的上聯,標準下聯是「晨露潤花花更紅」,而模型給出來的是「夜雨敲花花更香」,說明模型並非單純地記住訓練集的,仍是有必定的理解能力;甚至我以爲模型對出來的下聯更生動一些。

總的來講,基本的字的對應彷佛都能作到,就缺少一個總體感。整體效果沒有下面兩個好,但做爲一個小玩具,應該能讓人滿意了。

微軟對聯:http://duilian.msra.cn/app/couplet.aspx

結語 #

改動後的python3 代碼以下:
https://github.com/PDDsa/py3-couplet_by_seq_tagging
歡迎star~~
cpu版TensorFlow 跑了2.5小時。結果還不錯。

最後,也沒有什麼好總結的。我就是以爲這個對對聯應該算是一個序列標註任務,因此就想着用一個序列標註的模型來試試看,結果感受還行~固然,要作得更好,須要在模型上作些調整,還能夠考慮引入Attention等,而後解碼的時候,還須要引入更多的先驗知識,保證結果符合咱們對對聯的要求。這些就留給有興趣作下去的讀者繼續了。

本文轉載自 : 地址:https://kexue.fm/archives/6270

相關文章
相關標籤/搜索