基于深度学习的对联自动生成系统

对联自动生成系统

1.项目目标

设计一个基于深度学习的对联生成系统。最终结果可以是一个简单的界面,在界面中,我输入一句上联,通过点击相应按钮,系统生成相应下联并显示出来。

2.国内外相关工作

对联是属于我们中华民族独有的一种文学形式,国外研究甚少,所以在此主要阐述一下国内的研究情况。

我以“对联深度学习”和“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)提出对联生成的润色机制。

3.自己在本项目中承担工作

本项目一个人独自完成,工作大体可分为:

  1. 数据集搜集及整理,预处理
  2. 模型搭建训练及模型预测
  3. 最终展示界面搭建
  4. 报告撰写

4.实现系统(或模块)的核心思想和算法描述

4.1 数据处理部分:

4.1.1 噪声数据摘除:

数据集来源: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

问题数据展示如下:
基于深度学习的对联自动生成系统_第1张图片

经过上述处理,最终获得744915条对联数据。

4.1.2 添加输入开始与结束标志

  • < start> 表示一个输入的开始
  • < end> 表示一个输入的结束

需要注意的是:(1)一般的NLP任务都会设置一个< pad>字段表示填充,这里我们使用< end>表示;(2)我们并没有设置< unk> 标志来表示未登录词汇,根据我们的统计,本词汇共9017个,数量相对较小,可全部使用。 我们把每个字符(汉字或者标点)看作一个词汇。

4.1.3 建立词库与字典

  • 词库:由上下联所有字符,可用列表表示
  • 字典:建立词汇–>向量,向量–>词汇两个字典。向量在这里可以理解为数字化,最终的目的是向量化。

在字典的创建过程中,主要先用一个辅助字典,存储每个词汇出现的频率,然后根据频率排序辅助字典。然后初始化两个字典,遍历辅助字典,可用当前字典(非辅助字典)的长度作为词汇数字标识。 在该过程中,我们还可以根据频率筛选出频率大于一定阈值的词汇,即抛弃低频词汇。

4.1.4 数据向量化

根据前一步中创建的“词汇–>向量”字典将所有数据向量化。

向量化示意图:
基于深度学习的对联自动生成系统_第2张图片

4.1.5 数据集划分及封装

我们总的数据为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

最终我们得到封装好的训练集、验证集,测试集。以训练集为例,每个元素包括五部分:

  1. 上联输入向量
  2. 输入向量未填充前的长度,用于控制LSTM的隐藏状态是否更新填充位置
  3. 下联输入向量,不包含最后一个位置的元素
  4. 下联输入向量,不包含第一个元素,然后在最后一个扩维,用于loss计算
  5. 下联输入向量的mask向量

在这里插入图片描述

4.2 模型搭建及预测

4.2.1 训练模型

训练模型使用Encoder-Decoder框架(Seq2Seq模型)。

4.2.1.1 Encoder

encoder模块内部由一个embedding层和一个LSTM层顺序连接。

  • embedding层需要指定使用的词汇量和编码维度,词汇量我们使用全部的9017,编码维度我们使用的256
  • LSTM层,指定输入的维度,隐藏层的大小,以及LSTM的层数。
4.2.1.2 Decoder

deocder模块内部由一个embedding嵌入层和一个“LSTM+注意力”单元以及一个全连接层组成。

  • embedding层需要指定使用的词汇量和编码维度,词汇量我们使用全部的9017,编码维度我们使用的256
  • LSTM+注意力:在该单元,我们将encoder的输出和decoder中lstm的输出作为注意力机制的输入,将注意力机制的输出作为最终的结果。
  • 全连接层:指定输入维度和输出维度。输入维度为隐藏层的大小,输入维度应为词汇量的大小,将输出映射到词汇量大小的空间。
4.2.1.3 参数设定
  • num_layers=2:LSTM的层数
  • hidden_size=128:隐藏层的状态数
  • embedding_dim=256:嵌入层的维度
  • lr=0.001:学习率
  • log_freq=200:每200个batch输入一次日志信息
  • max_grad_norm=5:梯度裁剪
  • optimizer=Adam():优化器,严格的说,优化器不是参数,在这里我们把他看作一个参数。
  • loss=CrossEntropy():损失函数,使用的是带掩码的交叉熵,基于框架自带的交叉熵损失函数实现。
  • metrics=Preplexity():评价准则,我们使用的是困惑度,框架自带。
4.2.1.4 模型训练及验证
  • epcohs=20
  • 使用model.fit()函数进行训练及验证。模型提供的高阶接口。
  • 我们使用训练好的模型,直接在测试集上进行验证,结果截图如下:基于深度学习的对联自动生成系统_第3张图片

4.2.2 模型预测

模型的预测使用了beam search(束搜索)。常规的搜索方法有greedy search(贪心搜索)和exhaustive search(穷举搜索)。

  • 穷举搜索:穷举所有可能的输出结果。例如输出序列长度为3,候选项为4,那么就有444=64种可能,当输出序列长度为10时,就会有4**10种可能,这种幂级增长对于计算机性能的要求是极高的,耗时耗力。
  • 贪心搜索:每次选择概率最大的候选者作为输出。搜索空间小,以局部最优解期望全局最优解,无法保证最终结果是做优的,但是效率高。
  • 束搜索:束搜索可以看作是穷举搜索和贪心搜索的折中方案。需要设定一个beam size(束宽),当设为1时即为贪心搜索,当设为候选项的数量时即为穷举搜索。

4.3 展示界面搭建

4.3.1 Tkinter

展示界面我主要使用Python自带的TKinter包进行搭建,主要包括两个文本框和两个动作按钮。

4.3.2 内部流程

用户输入对联的上联,然后点击相应按钮,系统会提取用户的输入,将其向量化,然后送入训练好的模型中,产生输出,然后显示在另一个文本框中。

5.系统主要模块流程

系统主要模块流程如下图:

基于深度学习的对联自动生成系统_第4张图片

6.实验结果及分析

6.1 loss

loss曲线数据由PaddlePaddle提供的接口在训练时保存在log文件中,之后通过可视化工具进行展示。横轴表示训练的minibatch,纵轴表示loss值。

通过训练集与验证集的lossqu曲线可以看出,训练在前期收敛较快,训练集后期有波动,但是验证集后期仍为缓慢下降趋势,说明模型的训练效果是不错的。

训练集loss曲线:
基于深度学习的对联自动生成系统_第5张图片

验证集loss曲线:
基于深度学习的对联自动生成系统_第6张图片

6.2 困惑度

困惑度数据的获取方式同loss。通过训练集与验证集的困惑度曲线,我们也可任务模型训练效果可以。但是训练集的困惑度后期呈现为直线,这应该是存在问题的,有待分析解决。

我们在测试集上进行了困惑度分析,每个batch的数据困惑度基本一致,说明模型波动较小,效果理想。

训练集困惑度变化曲线:
基于深度学习的对联自动生成系统_第7张图片

验证集困惑度变化曲线:
基于深度学习的对联自动生成系统_第8张图片

我们使用训练好的模型,在测试集上进行验证,结果如下:
基于深度学习的对联自动生成系统_第9张图片

与张江等人使用transformer模型的困惑度比较,我们的结果还算可以。但是张江等人使用的数据集没有明确,可能是因为不同数据集造成的差异。然后,通过人工判定:生成几个例子,邀请舍友评价,总的结论是还可以。

6.3 界面展示

我们使用搭建好的简易界面进行对联自动生成模型的成果展示:

与张江等人使用transformer模型的困惑度比较,我们的结果还算可以。但是张江等人使用的数据集没有明确,可能是因为不同数据集造成的差异。然后,通过人工判定:生成几个例子,邀请舍友评价,总的结论是还可以。

你可能感兴趣的:(深度学习,深度学习,自然语言处理,paddlepaddle)