设计一个基于深度学习的对联生成系统。最终结果可以是一个简单的界面,在界面中,我输入一句上联,通过点击相应按钮,系统生成相应下联并显示出来。
对联是属于我们中华民族独有的一种文学形式,国外研究甚少,所以在此主要阐述一下国内的研究情况。
我以“对联深度学习”和“couplet”为关键词分别在中国知网和DBLP中检索了从18年至今的文献,中国知网有3篇硕士论文,DBLP有10篇英文文献(但仅有2篇可以SCI检索下载)。在我搜集到的5篇文献中,朱媛媛等人(2018,2021,吉林大学),卫万成等人(2019,桂林电子科技大学),Shengqiong Yuan等人(2019,武汉理工大学)都是基于Encoder-Decoder框架和Attention机制进行研究;张江等人(2020,南京邮电大学)基于transformer模型进行研究。
朱媛媛等人在2018年基于编码器-解码器模型进行研究,在词向量的预训练方法上进行了创新,提出不仅考虑序列中前后字的上下文关系,还同时考虑上下联之间对应字的相关性;紧接着,他们在2021年提出了“Trapezoidal Context’字符向量(从摘要看,还是18年的内容)。
卫万成等人在2019年同样采用编码器—解码器模型进行,但他是做的基于多任务学习模型生成诗歌和对联;编码器参数共享,解码器参数不共享。
张江等人主要是对基于注意力机制搭建的transformer模型进行改进,提出三种改进策略:(1)提出融合词性特征信息的词向量训练方法(2)提出一种低频词处理方法(3)提出对联生成的润色机制。
本项目一个人独自完成,工作大体可分为:
数据集来源:https://github.com/wb14123/couplet-dataset 此数据集包含了五个文件,将文件按照(test+train)的顺序进行合并。之后发现有14条数据有问题,索引为:badid=[103807, 176565, 257631,265657, 358953, 489089, 558495, 561447, 707870, 710226, 236151,517221,549031,707322](索引从0开始)。其中前10个问题为上联,后4个问题为下联。我把处理之后的数据集分享在:https://aistudio.baidu.com/aistudio/datasetdetail/110057
经过上述处理,最终获得744915条对联数据。
需要注意的是:(1)一般的NLP任务都会设置一个< pad>字段表示填充,这里我们使用< end>表示;(2)我们并没有设置< unk> 标志来表示未登录词汇,根据我们的统计,本词汇共9017个,数量相对较小,可全部使用。 我们把每个字符(汉字或者标点)看作一个词汇。
在字典的创建过程中,主要先用一个辅助字典,存储每个词汇出现的频率,然后根据频率排序辅助字典。然后初始化两个字典,遍历辅助字典,可用当前字典(非辅助字典)的长度作为词汇数字标识。 在该过程中,我们还可以根据频率筛选出频率大于一定阈值的词汇,即抛弃低频词汇。
根据前一步中创建的“词汇–>向量”字典将所有数据向量化。
我们总的数据为744915条,按照8:1:1的方式划分训练集,验证集,测试集。
数据集的封装主要使用paddlepaddle以及paddlenlp提供的一套方法,写法较固定,其中paddlenlp主要是进行每个minibath数据的padding操作,统一长度。详情可见代码或者官网讲解:
paddlepaddle数据集封装:https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/02_paddle2.0_develop/02_data_load_cn.html
paddlenlp数据padding:
https://paddlenlp.readthedocs.io/zh/latest/data_prepare/data_preprocess.html
最终我们得到封装好的训练集、验证集,测试集。以训练集为例,每个元素包括五部分:
训练模型使用Encoder-Decoder框架(Seq2Seq模型)。
encoder模块内部由一个embedding层和一个LSTM层顺序连接。
deocder模块内部由一个embedding嵌入层和一个“LSTM+注意力”单元以及一个全连接层组成。
模型的预测使用了beam search(束搜索)。常规的搜索方法有greedy search(贪心搜索)和exhaustive search(穷举搜索)。
展示界面我主要使用Python自带的TKinter包进行搭建,主要包括两个文本框和两个动作按钮。
用户输入对联的上联,然后点击相应按钮,系统会提取用户的输入,将其向量化,然后送入训练好的模型中,产生输出,然后显示在另一个文本框中。
系统主要模块流程如下图:
loss曲线数据由PaddlePaddle提供的接口在训练时保存在log文件中,之后通过可视化工具进行展示。横轴表示训练的minibatch,纵轴表示loss值。
通过训练集与验证集的lossqu曲线可以看出,训练在前期收敛较快,训练集后期有波动,但是验证集后期仍为缓慢下降趋势,说明模型的训练效果是不错的。
困惑度数据的获取方式同loss。通过训练集与验证集的困惑度曲线,我们也可任务模型训练效果可以。但是训练集的困惑度后期呈现为直线,这应该是存在问题的,有待分析解决。
我们在测试集上进行了困惑度分析,每个batch的数据困惑度基本一致,说明模型波动较小,效果理想。
与张江等人使用transformer模型的困惑度比较,我们的结果还算可以。但是张江等人使用的数据集没有明确,可能是因为不同数据集造成的差异。然后,通过人工判定:生成几个例子,邀请舍友评价,总的结论是还可以。
我们使用搭建好的简易界面进行对联自动生成模型的成果展示:
与张江等人使用transformer模型的困惑度比较,我们的结果还算可以。但是张江等人使用的数据集没有明确,可能是因为不同数据集造成的差异。然后,通过人工判定:生成几个例子,邀请舍友评价,总的结论是还可以。