基于CNN和序列标注的对联机器人

栏目: 编程工具 · 发布时间: 7年前

内容简介:前几天在量子位公众号上看到了“对对联”,我们可以看成是一个句子生成任务,可以用seq2seq完成,跟我之前写的然而,我们再细想一下就会发现,相对于一般的句子生成任务,“对对联”有规律得多:1、上联和下联的字数一样;2、上联和下联的每一个字几乎都有对应关系。如此一来,其实对对联可以直接看成一个序列标注任务,跟分词、命名实体识别等一样的做法即可。这便是本文的出发点。

前几天在量子位公众号上看到了 《这个脑洞清奇的对联AI,大家都玩疯了》 一文,觉得挺有意思,难得的是作者还整理并公开了数据集,所以决定自己尝试一下。

“对对联”,我们可以看成是一个句子生成任务,可以用seq2seq完成,跟我之前写的 《玩转Keras之seq2seq自动生成标题》 一样,稍微修改一下输入即可。上面提到的文章所用的方法也是seq2seq,可见这算是标准做法了。

然而,我们再细想一下就会发现,相对于一般的句子生成任务,“对对联”有规律得多:1、上联和下联的字数一样;2、上联和下联的每一个字几乎都有对应关系。如此一来,其实对对联可以直接看成一个序列标注任务,跟分词、命名实体识别等一样的做法即可。这便是本文的出发点。

说到这,其实本文就没有什么技术含量了,序列标注已经是再普通不过的任务了,远比一般的seq2seq来得简单。本文直接边写代码边介绍模型。如果需要进一步了解背后的基础知识的读者,还可以参考 《【中文分词系列】 4. 基于双向LSTM的seq2seq字标注》《【中文分词系列】 6. 基于全卷积网络的中文分词》《基于CNN和VAE的作诗机器人:随机成诗》

我们所用的模型代码如下:

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 是我定义的门卷积模块:

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])

仅此而已~就这样完了,剩下的都是数据预处理的事情了。当然,读者也可以尝试也可以把 gated_resnet 换成普通的层叠双向LSTM,但我实验中发现层叠双向LSTM并没有层叠 gated_resnet 效果好,而且LSTM相对来说也很慢。

训练的数据集来自: https://github.com/wb14123/couplet-dataset ,感谢作者的整理。

训练过程:

基于CNN和序列标注的对联机器人

对联机器人训练过程

部分效果:

上联:晚风摇树树还挺,下联:夜雨敲花花更香

上联:今天天气不错,下联:昨日人情无明

上联:鱼跃此时海,下联:鸟鸣何日人

上联:只有香如故,下联:不无月若新

上联:科学空间,下联:文明大中

看起来还是有点味道的。注意“晚风摇树树还挺”是训练集的上联,标准下联是“晨露润花花更红”,而模型给出来的是“夜雨敲花花更香”,说明模型并不是单纯地记住训练集的,还是有一定的理解能力;甚至我觉得模型对出来的下联更生动一些。

总的来说,基本的字的对应似乎都能做到,就缺乏一个整体感。总体效果没有下面两个好,但作为一个小玩具,应该能让人满意了。

王斌版AI对联: https://ai.binwang.me/couplet/

微软对联: https://duilian.msra.cn/default.htm

最后,也没有什么好总结的。我就是觉得这个对对联应该算是一个序列标注任务,所以就想着用一个序列标注的模型来试试看,结果感觉还行~当然,要做得更好,需要在模型上做些调整,还可以考虑引入Attention等,然后解码的时候,还需要引入更多的先验知识,保证结果符合我们对对联的要求。这些就留给有兴趣做下去的读者继续了。

转载到请包括本文地址: https://kexue.fm/archives/6270

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎/本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Coding the Matrix

Coding the Matrix

Philip N. Klein / Newtonian Press / 2013-7-26 / $35.00

An engaging introduction to vectors and matrices and the algorithms that operate on them, intended for the student who knows how to program. Mathematical concepts and computational problems are motiva......一起来看看 《Coding the Matrix》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具