为了写春联,我用 Transformer 训练了一个 “对穿肠”

栏目: 数据库 · 发布时间: 5年前

内容简介:微软对联:http://duilian.msra.cn/百度对联(用手机打开哟):

为了写春联,我用 Transformer 训练了一个 “对穿肠”

大数据文摘 出品

作者:Andy、蒋宝尚

今天是腊月二十九,按照黄历,是解除、破屋、坏垣的好日子。

中国人的传统也是在这一天贴对联,准确来说是春联。

对联来源于对偶句和骈俪句,讲究工整对仗,充分展现了我们中国人独特精致的艺术美感。

古人常以“吟诗作对”交友比试,但到了今天, 为了让写出的对联“出奇不意”,文摘菌决定用最近NLP领域大火的Transfomer模型,训练一个聪明的AI, 我出上联,它对下联, 将这个“对穿肠”的任务交给它。

模型介绍

为了写春联,我用 Transformer 训练了一个 “对穿肠”

关于对春联这个任务,可以明显看出是一个序列到序列的任务。于是就得祭出现在自然语言处理里面的大杀器了,Seq2Seq + Attention!

于是,文摘菌便采用了 Transformer 序列到序列模型。Transformer由论文《Attention is All You Need》提出,渐渐有取代RNN成为NLP中主流模型的趋势,现在更是谷歌云TPU推荐的参考模型,包括谷歌给自己TPU打广告的 Bert 就是Transformer模型。

Transformer架构完全舍弃了深度学习里经典的RNN和CNN结构,而只用注意力机制还搭建。最早在机器翻译任务上进行测试就超越 RNN,达到了当时SOTA的效果。Transformer 不光像 CNN 一样克服了 RNN 最被人诟病的训练慢问题,利用self-attention 机制实现快速并行,层数还可以增加到比较深,充分发掘DNN模型的特性,提升模型准确率。同时,在NLP任务上,还比CNN和RNN的性能都普遍要好,它不为王,谁为王。

大数据文摘之前与百度NLP联合出品了一篇文章:BERT大火却不懂 Transformer?读这一篇就够了。对Transformer不熟悉的同学可以点击超链接阅读文章,保你理解的透透的。

这里我们用6层Transformer单元,里面的Self-Attention的头数为8,隐单元数512个。模型采用 tensorflow 框架,GPU 则用深度学习标配的 Tesla K80。

好了,下面先介绍一下数据集。

数据集

文摘菌所使用的数据集来自一位名为冯重朴_梨味斋散叶的博主的新浪博客,总共包含超过70万副对联。

然而,由于未知的原因,这位博主的博客已经无法访问了……

为了写春联,我用 Transformer 训练了一个 “对穿肠”

但是,这一珍贵的数据集却在GitHub上广为流传。

github地址(脚本已无法使用,可以用我们上传的couplets,google drive需科学翻墙):

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

google drive:

https://drive.google.com/file/d/13cJWWp_ST2Xqt76pEr5ZWa6LVJwGYC4-/view?usp=sharing

整个数据集解压过后总共56.9兆,其中训练数据集56.4兆,测试数据集400多KB。另外,数据是以TXT格式储存的。全文不含标点15,153,840字,如果每天看100条的话,20多年都看不完。而文摘菌采用Tesla K80,2个小时就能来一个Epoch。

数据预处理

首先进行数据预处理,因为拿到的数据比较干净,所以这任务主要就是创建词表。值得一提的是,数据集的压缩文件中存在着一个创建好的词表。你也可以用数据集给出的词表。因为对联任务并不难,所以我们直接使用字粒度来作为输入,也就是像“我们”这样的词,我们是把其当做两个单元进行输入,而不是一个。

关键代码如下:

defmake_vocab(fpaths, out):
     '''Constructs vocabulary.      Args:        fpaths: Astring. Input file path.        fname: Astring. Output file name.      '''  
     char2cnt = Counter()
     for path in fpaths:
         for line inopen(path, 'r'):
             line = line.strip()
             ifnot line: *# detect the empty line*
                 continue
             chars = line.split()
            char2cnt.update(chars)
     withopen(out, 'w') as fout:
        fout.write("{}\t1000000000\n{}\t1000000000\n{}\t1000000000\n{}\t1000000000\n".format("<PAD>", "<UNK>", "<S>", "</S>")) # special tokens
         for word, cnt in char2cnt.most_common(len(char2cnt)):
            fout.write(u"{}\t{}\n".format(word, cnt))
         print("%d chars written!"% (len(char2cnt)))

建立完词表之后,所有单个汉字加上一些特殊字符,总共9126个字符。其实我们看看频率为1的字符就会发现,好像都不认识。一般来说,在序列到序列任务里面,我们会在词表里面忽略频率小不常用的字词。但是因为这里我们词表并不大,所以就全部采用了。

为了写春联,我用 Transformer 训练了一个 “对穿肠”

之后,我们对训练数据的字长进行统计,来决定训练时句子的最大长度。统计后发现,对联数据中单句的长度大部分集中在5-10字之间,最长大概30字左右,所以训练的最大长度文摘菌选的也是30。这个长度并不长,所以之后整个 Transformer 的大小都不是很大。

模型编写与训练

这里我们首先搭建好模型,之后通过数据将模型中的参数训练成我们所希望的,之后存储起来。这里便是一个epoch存储一个模型。而测试的时候,就可以直接读入参数获得一个训练好的模型来使用。

此外,我们也可以将保存的模型分享给别人,让其他人也可以直接利用我们的训练结果。

模型和训练的代码太多,这里就全不放出来了,感兴趣的读者可以去github上下载完整代码,也可以在大数据微信公众号后台回复“对联”下载完整代码以及数据集。

github地址:

https://github.com/andy-yangz/coupletsseq2seqtransformer

于是整个模型的训练过程主要分为四个步骤:

第一步,先下载对联数据 couplets, 然后解压到 data 里去

第二步,调整超参数

第三步,运行 prepro.py预处理数据,产生词表,也可以用提供的词表

第四步,运行 train.py 训练模型

评估

训练完之后,保存模型,评估脚本会自动读入最新模型来进行评估。

评估的主要步骤包括:

  • 建立模型

  • 读入训练好的参数

  • 读入测试数据

  • 将数据喂入模型

  • 编码解码获得结果

最主要代码应该是解码这一块:

### Autoregressive inference
                    preds = np.zeros((hp.batch_size, hp.maxlen), np.int32)
                    for j in range(hp.maxlen):
                        _preds = sess.run(g.preds, {g.x: x, g.y: preds})
                        preds[:, j] = _preds[:, j]

最开始喂入x,还有一个空的preds,然后获得一个预测的字,将这个字放在preds相应的位置,之后循环,不断将preds填满。最后就能获得完整的预测结果。

这里每次预测的字,取得都是预测概率最大的那个字,这叫做 greedy decoding(贪婪搜寻解码),因为每次都是选最大的。这样虽然快,但是也会出现陷入局部最优解的情况。更好些解码方法,可以使用Beam search(束搜索)。

训练结果

最后,来看看文摘菌的训练结果如何。

先皮一下!

话说改革开放四十周年,当然首先要响应一下我们的改革开放。先来段霸榜b站数月,念诗之王的作品。

接招,我出上联:

上联: 改革春风吹满地,中国人民真争气

AI 对:

下联: 和谐时雨润千山,小康社稷好生活

好湿好湿,充分说明了改革开放带给我们的美好生活。似乎还不错,我们系统的觉悟非常高啊。

再来考考它,博大精深的六学知识吧:

上联: 文体两开花

下联: 武功一代人

emmm,比较微妙,还行吧。

看到武功一代人,文摘菌突然想到了金庸先生。先生为我们创造了一个庞大的武学世界,为了纪念先生,就以下面两句为上联吧:

上联:飞雪连天射白鹿

下联:落花遍地戏黄蜂

嗯,确实有点世外桃源桃花岛的味道。

上联:笑书神侠倚碧鸳

下联:闲看仙女下红尘

这就有意思了,金庸武侠世界里的女子确实都是洒脱般的人物,尤其是小龙女和它的后辈黄衫女子活脱脱的一尘不染。

上联: 盘他

下联: 还我

好像有点都对不上了。

再来考考我们机器人2018年热点。

上联: 小猪佩奇社会人

下联: 大圣传世文明家

居然对上了。

再来,今年最火剧。

上联: 延禧攻略

下联: 棣华家声

莫非 AI 在暗示我们下一个会火的电视剧吗,根据名字,似乎是讲一个家族中两兄弟的故事,有意思有意思。

再看看,综艺节目:

上联: 创造一零一

下联: 和谐万事兴

嗯,嗯,非常和谐。

上联:锦鲤

下联:银蛇

普普通通。

再看看美国领导人们。

上联:特朗普

下联:小康庄

上联:奥巴马

下联:罗汉松

没想到虽然都身为世界领导人,对出来的东西都这么朴素。

好,那在看看贸易战:

上联:中美贸易战

下联:大中华国风

对的好,对的好,思想很正确。

好了不玩了。再来看几个正经点的对联吧。

我们从测试集里面挑几个,这里上联和下联是正确的,模型是机器人给出的下联:

上联: 腾飞上铁,锐意改革谋发展,勇当千里马
下联: 和谐南供,安全送电保畅通,争做领头羊
模型: 奋进开篇,激情发展促和谐,更上一层楼

还有:

上联: 一句相思吟岁月
下联: 千杯美酒醉风情
模型: 几杯寂寞醉春秋

看上去对的还算挺工整。

当然我们也看到了一些问题。比如说模型学到的都是一些和宽泛的对应,名词动词相对应做到了,也能保证通顺,但是却在一些需要典故和外界知识的例子中,无法做出合适的回应。有时就会出现,不知道“上铁”和“南供”这俩典故,或者出现所谓无情对,上下联字词对仗工整但是意思毫不相关。

这是我们训练了6个epoch,也就是模型将数据看了六遍的结果。这次我们总共保存了7个模型,从Epoch1到Epoch7模型,其实要说那个好只能是见仁见智了,比如说我就觉得6个Epoch会好些。但是可以确认的是随着Epoch增加模型就越能学到对联数据里的模式。

是不是还挺好玩,感兴趣的同学,也跟我们一起训练一个自己的“对穿肠”吧。

其他模型

关于AI写对联,其实之前已经有了基于深度学习seq2seq的模型,同样其用到的也是TensorFlow和那位冯重朴_梨味斋散叶的博主提供的数据集。

目前,代码已经开源,你可以在下面的github中找到:

为了写春联,我用 Transformer 训练了一个 “对穿肠”

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

当然,除了模型代码之外,你也可以打开作者给出的网址,随意的出对子。

为了写春联,我用 Transformer 训练了一个 “对穿肠”

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

对了,上面那个AI创作者名叫王斌,英国莱斯特大学读计算机硕士,现在是一名软件工程师。

微软对联与百度对联

除了单打独斗的程序员,尝试了对联AI的科技巨头也不少,文摘菌这里介绍两个最有名的项目,不想自己训练模型的同学,可以直接取用。

比较早出现的对联AI来自微软亚洲研究院,自然语言计算组研究开发,沈向洋主导的研究项目。

微软的对联AI要谨慎且复杂一点,如果以“改革春风吹满地”作为上联,它也会给你许多个下联作为备选。

为了写春联,我用 Transformer 训练了一个 “对穿肠”

最令人感动的是,如果你不喜欢,还可以换一种方式!

为了让对联更加对仗工整,你可以选择分词的方式。如果你仍然不满意,可以点击反馈意见按钮告诉它“家长”。最后,还能生成横批。

为了写春联,我用 Transformer 训练了一个 “对穿肠”

除了微软这个老前辈,还有一个江湖新秀,那就是今年百度联合央视网、网易推出的智能春联。据说,他能根据每个人的五官特性生成专属于你的春联。

嗯,也就是刷脸写对联。

文摘菌用李彦宏的大头像试了试,可以感受一下这魔幻的过程:

为了写春联,我用 Transformer 训练了一个 “对穿肠” 为了写春联,我用 Transformer 训练了一个 “对穿肠”

微软对联:

http://duilian.msra.cn/

百度对联(用手机打开哟):

https://chunlian.news.cntv.cn/

好了,文摘菌要去贴春联啦, 就到这里吧

志愿者介绍

后台回复 志愿者 ”加入我们

为了写春联,我用 Transformer 训练了一个 “对穿肠”

听说点了「好看」的人都变好看了哦


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

查看所有标签

猜你喜欢:

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

Linux内核完全剖析

Linux内核完全剖析

赵炯 / 机械工业出版社 / 2008.10 / 99.00元

本书对早期Linux内核(v0.12)全部代码文件进行了详细、全面的注释和说明,旨在帮助读者用较短的时间对Linux的工作机理获得全面而深刻的理解,为进一步学习和研究Linux打下坚实的基础。虽然选择的版本较低,但该内核已能够正常编译运行,并且其中已包括了Linux工作原理的精髓。书中首先以Linux源代码版本的变迁为主线,介绍了Linux的历史,同时着重说明了各个内核版本的主要区别和改进,给出了......一起来看看 《Linux内核完全剖析》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换