指针生成网络的简介

指针生成网络(Pointer-Generator Networks)是一个基于seq2seq+attention的生成模型,相比于seq2seq+attention的生成模型,它能够在一定的程度上解决oov(out of vocab)的问题。

回顾seq2seq+attenion

这一篇博客有比较详述的解析

对于seq2seq+attention,再decoder的每一个时间步的词,都是从词表(一共\large v个)中选择概率最高的一个作为预测结果。

下面概述seq2seq+attenion的过程

encoder的输入:\large x=(x_{1},\cdots ,x_{T_{x}})

decoder的输入: \large y=(y_{1}, \ddots ,y_{T_{y}})

(1) \large h_{t} = LSTM_{enc}(E(x_{t}),h_{t-1}) encoder在时间步\large t上,\large E(x_{t})是第\large x_{t}个词的词向量,\large h_{t-1}\large t-1时刻的隐层,\large h_{t}\large t时刻的隐层

(2)\large s_{t}=LSTM_{dec}(E(\hat{y}_{t-1}),s_{t-1}) decoder在时间步t上,\large E(\hat{y}_{t-1})是decoder在时间步\large t-1上预测的词的词向量,\large s_{t-1}\large t-1时刻的隐层,\large s_t是当前时刻\large t的隐状态输出。

(3) c_{i}=\sum_{j=1}^{T_{x}}\alpha_{ij}h_{j}c_{i}decoder时间步骤为i时的词向量,h_{j}是encoder时间步为j的隐层;\alpha_{ij}h_{j}decoder时间步骤为i时的权重。\small \alpha _{i} =\sum _{j=1}^{T_{x}}\alpha _{ij}=1

(4) \small \alpha _{ij}=\frac{exp(e_{ij})}{\sum_{k=1}^{T_{x}}exp(e_{ik})}     h_{j}decoder时间步骤为i时的权重

(5) \small e_{ij}=score(s_{i},h_{j}),\small s_{i}分别与\small h_{j}做运算,这里有多种计算方式,seq2seq+attention中有讲到。

(6)\small \hat{s}_{t}=tanh(W_{c}[c_{t};s_{t}])将context vec 和 当前隐层的信息结合起来,得到\small \hat{s}_{t}

(7)\small p(y_{t}|y_{<t},x_{1:T_{x}})=softmax(W_{s}\hat{s}_{t})得到在\small t时刻的词的概率分布, \small p(y_{t}|y_{<t},x_{1:T_{x}})\subset \mathbb{R}^{v}

(8) \small word_{t}=argmax(p(y_{t}|y_{<t},x_{1:T_{x}}))\small p(y_{t}|y_{<t},x_{1:T_{x}})选取最大的一个值的索引,作为当前生成的词。

如上图的例子,输入Germany,目标生成beat,可以直观的看到,beat 的词分布(vocabulary distribution)由decoder的隐层和context vector共同得到,而context vector 是由 decoder当前输出和encoder每一个时间步的输出得到。

\small e_{i}^{t}=V^{T}tanh(W_{h}h_{i}+W_{s}s_{t})\cdots \cdots \cdots \cdots \cdots \cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots (1)

\small e_{i}^{t}decoder时间步为\small t时,对encoder时间步骤为\small i的关注度,\small s_{t}decoder时间步为\small t的输出,\small h_{i}encoder时间步为\small i的输出。\small V\small W_{h}\small W_{s}都是可以学习的参数。

\small a^{t}=softmax(e^{t})\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots\cdots\cdots \cdots\cdots\cdots\cdots \cdots \cdots (2)

\small e^{t}=[e_{1}^{t},\cdots ,e_{T_{x}}^{t}]是时间decoder时间步\small t对encoder每一个时间步的得分,进过\small softmax归一化后得到\small a^{t}=[a_{1}^{t},\cdots ,a_{T_{x}}^{t}],\small sum(a^{t})=1

然后再对\small h=[h_{1},\cdots ,h_{T_{x}}]做加权求和:

\small c^{t}=\sum_{i=1}^{T_{x}}a_{i}^{t}h_{i}\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots\cdots\cdots\cdots\cdots\cdots\cdots (3)

\small c^{t}是context vector。

\small P_{t}=softmax(W_{c}[s_{t};c_{t}])\cdots \cdots \cdots \cdots \cdots \cdots \cdots\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots (4)

\small [s_{t};c_{t}]\small s_{t}\small c_{t}的concat,\small W_{c}是可以学习参数。\small P_{t}\subset \mathbb{R}^{v},这样就可以得到decoder时间步为\small t的词分布了。

\small loss_{t}=-log(p_{t}(word_{t}))\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots (5)

\small word_{t}是时间步等于\small t时真实的词索引,\small loss_{t}是时间步等于\small t上的损失。

在decoder序列上的损失:

\small loss = \frac{1}{T_{y}}\sum_{t=1}^{T_{y}}loss_{t}\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots (6)

在式(4)中得到decoder时间步为\small t时在词表上的词分布,但是我们的词表的长度通常是有限的,出现频率过低的词汇,将统一用\small <unk>表示,如果在训练集中,decodertarget的某个词不在词表中,那么它就用\small <unk>表示,如果这样进行训练下去,那么我们可以想象,在生成阶段,也会生成\small <unk>这种特殊字符,这样肯定是不合理的,论文Get To The Point: Summarization with Pointer-Generator Networks在一定程度上可以解决这个问题。

Pointer-Generator Networks

论文地址Pointer-Generator Networks

如下图直观的反映,Argentina的生成,不仅仅是从vocab中得到,以概率\small p_{gen}从词表的分布中生成,以\small (1-p_{gen})从原文的句子中生成。

\small p_{gen}=\sigma (W_{pc}c_{t}+W_{ps}s_{t}+W_{px}x_{t})\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots (7)

\small W_{pc}\small W_{ps}\small W_{px}都是可以学习的参数,\small c_{t}context vector, \small s_{t}decoder当前时刻下输出 ,\small x_{t}是当前decoder的输入向量。

\small P_{t}=p_{gen}P_{t}^{vocab}+ (1-p_{gen})\sum_{i:w_{i}}a_{i}^{t}\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots\cdots \cdots \cdots (8)

这里不是简单的相加,\small p_{t}^{vocab}\subset \mathbb{R}^{v+len(oovs)}\small a^{t}=[a_{1}^{t},\cdots ,a_{T_{x}}^{t}]\subset \mathbb{R}^{T_{x}}

直接看代码吧,这里是如何运算的:

vocab_dist_p = vocab_dist * genera_p
context_dist_p = attention_score * (1 - genera_p)
if oovs_zero is not None:vocab_dist_p = torch.cat([vocab_dist_p,oovs_zero],dim = -1)
final_dist = vocab_dist_p.scatter_add(dim = -1,index=encoder_with_oov,src = context_dist_p)

执行这个加法的就是用scater_add实现的,oovs_zero是对文章中超出词表(out of vocab)范围的词,oovs_zero的长度,等于原文中超出词表的词的个数。初始化的元素全部为0。如果原文中没有oov词汇,那么 oovs_zero is None。

encoder_with_oov是词索引,也是每个词的idcontext_dist_p对原文的关注度,scater_add就会把context_dist_pencoder_with_oov为索引叠加到词表的词分布上面,作为最终的词分布。

汇聚机制 Coverage mechanism

汇聚机制是为了解决对某一个原文中的单词关注度一直过重,导致这个词重复生成的现象,在时间步等于\small t的cov计算如下:

\small cov^{t}=\sum_{t^{'}=1}^{t-1}a^{t^{'}}\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots\cdots\cdots(9)

这时计算对encoder每个时间步的关注度即式(1)的计算方式就要改变了:

\small e_{i}^{t}=V^{T}tanh(W_{h}h_{i}+W_{s}s_{t}+W_{cov}cov_{i}^{t})\cdots \cdots \cdots \cdots \cdots \cdots\cdots\cdots\cdots\cdots\cdots (10)

Coverage 这一部分也产生一个loss:

\small covloss_{t}=\sum_{i=1}^{T_{x}}min(a_{i}^{t},cov_{i}^{t})\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots (11)

最终的loss是两个部分相加:

\small loss_{t}=-log(p_{t}(word_{t}))+\lambda*covloss_{t}\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots (12)

评估准则

评估准则,对于摘要,评估准则通常是ROUGE这个指标,其实就是\small n-gram的召回率。

ROUGE-N=\frac{\sum_{S\subset \{RefSummaries\}}\sum_{n-gram\subset S}Count_{match}(n-gram)}{\sum_{S\subset \{RefSummaries\}}\sum_{n-gram\subset S}Count(n-gram)}

简单的用一句话描述:\small Ref中能够匹配的\small n-gram除以所有的\small n-gram

实验部分

我的github实现

数据一 CNN和dalymail

是CNN和dalymail的数据,cnn一共92579个文件,dailymail一共219506个文件

分词

使用工具stanford-corenlp进行分词(其实分词的质量也一般般,吐槽一下),stanford-corenlp下载地址。如果下载速度不够快,我已经上传至网盘,提取码pnzk。

分词完成后,一共得到三份文件train,test,val,还有词表文件vovab.json

分词后的文件

数据预处理

因为数据量稍大,每次训练如果都做一些重复的操作,比如构建词典,词转换成词索引,这些都是比较浪费时间的。所以把所有的文件都转换完成,储存起来。

数据的信息,文章和摘要的长度分布

文章和摘要的长度分布

文章排序后的长度曲线图

摘要排序后的长度分布

初始文章最大长度定为1500,摘要最大长度是100,并且去训练,发现训练了一天,发现模型训练的很慢,经过多种选择和基于我自身硬件(GPU)的考虑,把文章最大长度定为400(确实是短了点o(╯□╰)o),最大摘要长度是100,词表最大50000。来完成这次训练。将转换完成的数据存入到特征文件夹。features_50000_400_100。其实400长度的文章效果还不错,大胆猜测一下,可能大部分摘要的信息都集中在文章的前半段吧。

feature文件

训练过程

batch_size的说明

考虑到我自己硬件(GPU)的大小问题,我又不想让batch_size过于太小,所以这里用了gradient_accumulation_steps这个方法,令batch_size=16gradient_accumulation_steps=4,这样相当于真实的batch_size=64。具体做法是每loss每求4次导,模型更新一次参数。

超参数的选择

在训练过程中,有些超参数的选择是刚刚训练就可以发现的,有些则不然,比如在选择优化器的问题上,Adagrad你会发现它收敛得很慢,很快就发现它不合适。Adam相比Adagrad较收敛速度就快了很多。在训练过程中为了贪效率,试图将Adam的学习率(lr)设置为\small 1e-2,刚开始确实快了很多,但是训练到1000轮左右,就会发现loss不再收敛了,越来越大,这是在训练中可以发现的超参数问题。但是有一些模型想把模型调到最优(接近于极限),对于深度学习来说可能需要花费巨大的代价,比如尝试对LSTM隐层维度,LSTM的层数,dropour等要验证结果,就需要把模型训练完成,花费的资源代价有点大。

我一共训练了10个epoch,训练集大小287227,batch_size= 64 ,一个epoch更新4488轮,一共更新了4488*10轮,模型每隔500步存储一次,下面是训练集训练过程中的loss的变化情况:

这里有一点看起来奇怪的地方,刚开始\small eval\_loss < train\_loss,这里有两个原因:

1、比如在step=500的loss,对于train,是取得1-500步的平均loss,而对于eval,则是用的500步的那个模型得到的loss。

2、train_loss 是在模型的model.train()模式下计算的,eval_loss是在model.eval()状态下计算的。这两种模式下,同一模型,同一个数据,计算的结果会有不同。

模型预测结果

整个训练下来,花费了将近48个小时(如果可以训练的更久,模型也许还能提升效果),一共存储了89个模型,由于生成摘要其实也挺费时间的,所以从第89个模型开始,使用这些模型开始对测试集生成摘要,最好的模型是第41500次更新的模型,也是第83个模型。评估指标如下:

model step 41500
rouge-1 rouge-2 rouge-L
0.3846 0.1628 0.3517

这个最好的模型也不算特别好,由于我自己的资源限制,跑一组参数需要2天,还只是在一个epoch的条件下,如果寻找相对较优的参数,还需要花费数倍的资源。下面看看它生成的部分摘要。上面是 原文,下面是生成的。

意思跑偏了一部分~

reference:

juan arango escaped punishment from the referee for biting jesus zavela . he could face a retrospective punishment for the incident . arango had earlier scored a free kick in his team 's 4-3 defeat .

hypothesis:

juan arango conjured memories of opponent jesus zavela in a moment of madness . the venezuelan icon sank his teeth into the shoulder of jesus zavela . zavala holds his shoulder after being bitten by arango .


这个总结的还行,后半部分没抓到重点

reference:

current federal government guidelines dictate the people should limit their salt intake to 2,300 milligrams . scientists now believe a typical healthy person can consume as much as 6,000 milligrams per day without significantly raising health risks . the same skeptics also warn of the health risks associated with consuming less than 3,000 milligrams . average american ingests about 3,500 milligrams of salt per day .

hypothesis:

for years medical experts have warned about the dangers of too much salt , but new research is questioning conventional wisdom and warning instead of the dangers of too little salt . both federal government regulations and the american heart association have for decades warned that excess salt contributes to the deaths of tens of thousands of americans each year .

但是还是会出现少量的<unk> token,一方面指针生成网络并不能完全解决OOV的问题,另一方面,跟分词也有很大的关系。在test数据集中。一共11490个文章,只有两个摘要中出现了<unk>,当然对于<unk>也可以,在预测解码(decoder)阶段使用beam seach的方式时,直接过滤掉。

例如:下面时其中的一个带有<unk>的摘要(意思完全跑偏了)

reference:

a magnitude-7.8 earthquake struck near kathmandu , nepal . carolyn miles : many survivors will have nowhere to go .

hypothesis:

annette <unk> : nepal has also made some of the most remarkable progress on maternal and child health in the last few years . in fact , i remember a time just last may when i sat with a group of mothers and their tiny babies as they told me how proud they were that they now understood how important it was to make sure they prioritized breastfeeding and nutritious foods .

对于这个看似完全跑偏预测结果,我去看了一遍原文,大概是因为截断造成的,文章中有提到大部分篇幅在说地震,但是前半部分在说母婴问题健康问题,看似“跑偏”,实则“正常”。

数据集二

数据来源链接,具体的数据集链接news_2016zh,提取码k265。训练集一共有2430752个新闻和它的标题,我的做法是,从中得到前30万个作为训练集,然后1.2万个作为验证集,然后再用1.2万个作为测试集。

分词

分词使用jieba,结巴分词的质量也一般般,不太好,有一些词分的明显有问题。例如:这一句这么分更合理:

[高开高走,涨逾,2%],结果确这样子分词

jieba不合理的分词

还有,这个名字,把名字"张增田"分开了

jieba分词姓名分开

分词完成后,得到train,test,dev 和 vocab.json

分词完成后文件

预处理

预处理主要是形成词表,词与索引的对照,将train,test,dev的词,映射成词索引,并以二进制文件存储。这里词表大小是5万,train,test,dev原本数量是30万,1.2万,1.2万,但是做了些过滤后,数量大概在27万+,1.1万+,1.1万+。这里的过滤,要去掉文章内容为空,标题为空的错误样本。还要去掉标题长度小于内容长度的样本。

下面来看内容(content)和标题(title)的最长度分布情况:

content和title长度分布

样本的content长度变化曲线

样本title长度变化曲线

综合考虑下来,content的最大长度选为500,title最大长度选为40。然后生成相应的二进制文件

生成的二进制文件,词表大小50000,content_len=500,title_len=40

这样分词出现了一些问题

那就每个样本的OOV的词汇都很大,对于OOV,我是这样理解的,OOV的词汇本身不被编码,是通过被编码的词汇去“猜”未被编码的OOV的词汇,如果OOV的词汇,太多了,那还是会影响模型。

OOV词汇量过大,过多,有一部分是jieba分词的原因,但是这不是主要的。下面展示前五个样本的OOV的词汇列表:

oovs :[UKOG 地底 桑德森 储有 石油资源 推测储量 762 914 肯特郡 赛克斯 萨里郡 汉普郡 地质勘探 局曾 便士 3.25 261.99% 1822]

oovs:[金殿 jindvip 填完 88006HUI 信息点 账号密码 走涨 涨多 跌少 千股 3048.14 43.44 1.45% 10741.69 174.11 1.65% 2208.47 58.57 2.72% 1755.2 2788.7 4543.9 IF1610 23700 3396840733]

oovs:[运动队 学类 信息学 科学实践 复测]

oovs:[正通 龙抬头 千店 豪礼惠 正通店 德胜 0951 8987888 特批 持此 现只 机不可失 速来]

oovs:[爱儿 名店 许根茂 尹镛 张文 十杰 严励 每家店 影棚 花园式 内景]

可以看到,除了一些数字、地名、人名等等不太常见,有一些词还是挺常见的,把它们划归到OOV,从人类的认识角度,是不太合理的。

训练过程

超参数选择

参考数据一。

一共10个epoch,训练更新并且记录了44500步骤,每隔500词评估一次模型,train和eval的loss如下图所示:

可以看出,在3万多步之后,train_loss还是在下降,但是对于eval_loss却变化不大。

预测结果

得分

在所有的模型中,挑选了5个,在验证集上eval_loss最低的5个模型,这5个模型的得分如下:

update_step rouge-1 rouge-2 rouge-L
step_25500

0.3300

0.1885

0.3112

step_26500

0.3307

0.1892

0.3124

step_29500

0.3361

0.1927

0.3170

step_31000

0.3295

0.1869

0.3112

step_33500

0.3340

0.1906

0.3151

avg 0.3321 0.1896 0.3134

比实验一英文数据集差了5个点左右,当然这个比较意义不大,数据集都不一样。

部分生成的标题

这个标题起得还是那么回事,真唬人

哈哈哈,颇有标题党的嫌疑

大概意思完全正确✔

也有一些不好的,里面含有<unk>(其实可以被手动过滤掉,但是这里没有做),重复生成等问题。:

在测试集中,一共11438个样本,<unk>出现了2432次(不等于2432个样本出现<unk>),我觉得这里跟前面提到的OOV词汇过多很大的关系。总的来说,分词不恰当!!!

数据集三

数据集三和数据集二属于同一数据集,但是处理的方式不同,数据三将源数据按照来切分。

并且对模型进行了更改,图只表达了更改部分,其他部分未改动,所以没有画全

模型embedding层的更改

主要是考虑到按照词来分,从一开始就引入了字与字之间的关系特征(组词),而如果按照字来分,则模型会缺失这个特征,所以加一层transformer来让模型自己学会捕捉到字与字之间的关系。

按照字进行分词

按照字进行分词,这里面有一些处理方式与使用jieba分词的细节有所不同,下面说明不同之处,和超参数选择的理由。

词表大小,从50000变小到20000。

下图是使用jieba分词,按照词频倒序后的,50000-50100的词和150000-150100的词:

jieba (50000-50100)

jieba (150000-150100)

可以看到,vocab_size=50000时,还是会有很多看起来有意义的词汇被<unk>这个特殊的token替代了,即使vocab_size=150000,还是有一部分比较有意义的词,被<unk>这个特殊的token替代了。这在一定的程度上是不合理的,并且如果<unk>过多,在生成摘要时,也会生成带有<unk> (在不进行过滤的情况下)。

如果按照字来进行分词,当vocab_size=20000时,如下图所示

字分词 20000-20100

这时已经可以清晰的看出来,20000之外的除了一些不常见的繁体字,生僻字,其他的都是英文,数字代码等等意义不大的词汇。

因此,如果按照字来分,vocab_size=20000就足够了,可以覆盖大绝大部分常见的词汇信息。

预处理

预处理的目的和数据集二相同,

content和title长度分布

content长度变化

title长度变化

综合考虑下来,content的最大长度选为512,title最大长度选为50。然后生成相应的二进制文件

之前使用jieba分词,出现了一些问题,按照“字”分词,这些问题得到了非常大的改善。样本中的oovs词汇数量都非常少,甚至为0,前5个样本的oovs:

oovs:[ukog]

oovs:[jindvip 88006hui 10741 2788 4543 23700]

oovs:[]

oovs:[8987888]

oovs:[]

由此,可以不严谨的推测,整体的样本上,oovs词汇的数量都少了许多。

训练过程

由于模型整体做了较大的更改,所以超参数也做了一些调整。

部分超参数选择(更改)
vocab_size 20000
embedding_dim 256
hidden_dim 256
epoch_size 15
batch_size 16
gradient_accumulation_steps 4
一共训练了15个epoch,值得说明的是,更改后的模型相比于之前的模型,参数量上小了很多,所以训练起来比较容易,15个epoch和之前10个epoch时间相当。

训练更新并且记录了64500步骤,每隔500次评估并且保存一次模型,train和eval的loss如下图所示:

这个模型的相比于数据二的模型,eval的loss更小了,初步看起来是个好消息。

结果的预测

得分

在所有的模型中,挑选了5个,在验证集上eval_loss最低的5个模型,这5个模型的得分如下:

update_step rouge-1 rouge-2 rouge-L
step_59500

0.3066

0.2086

0.2888

step_60000

0.3083

0.2096

0.2900

step_60500

0.3124

0.2120

0.2935

step_63000

0.3068

0.2081

0.2888

step_64500

0.3129

0.2123

0.2943

avg 0.3094 0.2101 0.2911

单纯的从数学上,召唤率的衡量标准来看,数据二的结果要优于数据三。

部分标题的生成

先看看效果比较好的标题

完全正确,可以打82分,剩下的18分给个666吧。

说的大概意思,也相差不远。

这是模型自己生成的,可不是我说的啊。

这个也不错

再看一些效果比较差的:

跟原标题的,沾边了一点

跑偏了

这个生成的都不怎么通顺

其实,在数据三这个一部分,我在生成标题时,多写了这一部分代码,用来过滤掉生成的<unk>和<pad>:

for j in range(beam_size*2):if topk_ids[i,j] in [self.config.pad_idx,self.config.unk_idx]:continue

在数据三使用按照字分,从数学上看,效果略低于jieba分词的方式,但是从人类的角度讲,我个人觉得效果要远远好于数据二的jieba分词方式

数据集二,数据集三的对比

上面说到,从人类的角度,数据三的结果比数据二要优秀,但是在评估准则上,要逊于数据集二。其实也不尽然,在评估准则那一部分,说到用的是召回率,但是说到召回率,其实就有准确率f1

对于数据集二,五个最优秀的模型的召回率,准确率,和f1如下:

数据二【召回率,准确率,f1】
update_step rouge_1_f1 rouge_1_p rouge_1_r rouge_2_f1 rouge_2_p rouge_2_r rouge_L_f1 rouge_L_p rouge_L_r
step_25500

0.2898

0.2711

0.3300

0.1596

0.1459

0.1885

0.2594

0.2552

0.3112

step_26500

0.2892

0.2698

0.3307

0.1592 0.1452 0.1892 0.2591 0.2546 0.3124
step_29500 0.2947 0.2758 0.3361 0.1623 0.1483 0.1927 0.2636 0.2597 0.3170
step_31000 0.2880 0.2693 0.3295 0.1575 0.1439 0.1868 0.2576 0.2540 0.3112
step_33500 0.2909 0.2703 0.3340 0.1600 0.1455 0.1906 0.2601 0.2547 0.3151
avg 0.2905 0.2713 0.3321 0.1597 0.1458 0.1896 0.2600 0.2556 0.3134

对于数据集三,五个最优秀的模型的召回率,准确率,和f1如下:

数据三【召回率,准确率,f1】
update_step rouge_1_f1 rouge_1_p rouge_1_r rouge_2_f1 rouge_2_p rouge_2_r rouge_L_f1 rouge_L_p rouge_L_r
step_59500 0.3377 0.3944 0.3066 0.2309 0.2732 0.2086 0.3002 0.3704 0.2888
step_60000 0.3376 0.3915 0.3083 0.2305 0.2701 0.2096 0.3004 0.3672 0.2900
step_60500 0.3404 0.3924 0.3124 0.3211 0.2709 0.2120 0.3030 0.3678 0.2935
step_63000 0.3392 0.3977 0.3068 0.2315 0.2754 0.2081 0.3011 0.3734 0.2888
step_64500 0.3399 0.3902 0.3129 0.2317 0.2692 0.2123 0.3033 0.3661 0.2943
avg 0.3390 0.3932 0.3094 0.2491 0.2718 0.2101 0.3106 0.3690 0.2911

把最后两行平均值,取出来对比

数据集二,数据集三【召回率,准确率,f1】均值对比
数据集 rouge_1_f1 rouge_1_p rouge_1_r rouge_2_f1 rouge_2_p rouge_2_r rouge_L_f1 rouge_L_p rouge_L_r
数据集二 0.2905 0.2713 0.3321 0.1597 0.1458 0.1896 0.2600 0.2556 0.3134
数据集三 0.3390 0.3932 0.3094 0.2491 0.2718 0.2101 0.3106 0.3690 0.2911

可以很明显看出,数据集三相比于数据集二,在召回率上有些逊色,但是在准确率上有很大幅度的领先,以至于,数据集在f1上也有较大幅度的优势,所以说,人类觉得数据三更好,在数学上也是有迹可循的。

总结

数据集一是使用的英文数据,把相当于把论文的方法实现出来,结果与原论文有所差距,原因可能是因为训练的轮数太少了。

数据集二,将模型直接套用在使用jieba分词中文的数据集上,从数学的角度是要比英文的差的很多,但是数据集不同,比较的意义不大。

数据集三,将数据集二分词方式改为按照“单个字”来分,并对模型进行一定的更改,效果相对于数据集二,结果各有优劣。

指针生成网络(Pointer-Generator Networks)的实现相关推荐

  1. PGN: 指针生成网络(Get To The Point: Summarization with Pointer-Generator Networks)

    文章目录 1 引言 2 本文模型 2.1 Seq2Seq 注意力模型 2.2 指针生成网络 2.3 覆盖机制(Coverage mechanism) [Reference] 1. Get To The ...

  2. 深度之眼Paper带读笔记NLP.19:指针生成网络

    文章目录 前言 第一课 论文导读 摘要简介 抽取式文本摘要 基于TextRank的抽取式摘要 基于聚类的抽取式摘要 基于序列标注的抽取式摘要 文本摘要发展历史 生成式摘要 序列到序列结构 两类方法对比 ...

  3. 论文浅尝 | 利用指针生成网络的知识图谱自然语言生成

    论文笔记整理:谭亦鸣,东南大学博士,研究方向为知识图谱问答. 来源:Neurocomputing 382: 174-187 (2020) 链接:https://www.sciencedirect.co ...

  4. 指针生成网络(PGN)的简单总结

    基于RNN的seq2seq: 好处: 用于文本生成,可以用于抽象总结. 坏处: 不准确的复制事实细节:无法处理OOV:生成文本有重复倾向:长文本下效果效果倾向于language model PGN分析 ...

  5. 【Keras+计算机视觉+Tensorflow】DCGAN对抗生成网络在MNIST手写数据集上实战(附源码和数据集 超详细)

    需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一.生成对抗网络的概念 生成对抗网络(GANs,Generative Adversarial Nets),由Ian Goodfellow在2014 ...

  6. 文本生成任务之营销文本生成(Seq2seq+attention、Pointer Generator Network、Converage、Beam Search、优化技巧、文本增强)

    文章目录 引言 项目任务简介 0. 数据预处理 0.1 将json文件转化成txt文件 0.2 词典处理 0.3 自定义数据集SampleDataset(Dataset类) 0.4 生成Dataloa ...

  7. 生成对抗网络 – Generative Adversarial Networks | GAN

    生成对抗网络 – Generative Adversarial Networks | GAN 生成对抗网络 – GAN 是最近2年很热门的一种无监督算法,他能生成出非常逼真的照片,图像甚至视频.我们手 ...

  8. 生成对抗网络(Generative Adversarial Networks)

    参考  生成对抗网络(Generative Adversarial Networks) - 云+社区 - 腾讯云 目录 一.生成对抗网络原理 1.模型的起源 2.模型的结构和损失函数 二.对GAN的改 ...

  9. CVPR2021(Oral) 商汤、港中文实现单目人脸重建新突破: 基于生成网络的渲染器!几何形状更精准!渲染效果更真实!...

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 近日,商汤-港中文联合实验室提出基于风格化对抗生成器的人脸渲染器,用于取代传统图形学基于栅格化的渲染器 ...

  10. 图像生成对抗生成网络gan_GAN生成汽车图像

    图像生成对抗生成网络gan Hello there! This is my story of making a GAN that would generate images of cars, with ...

最新文章

  1. linux中awk下 gsub函数用法
  2. 回车的ascii码_ASCII码表
  3. R语言parse函数、deparse函数、expression函数实现字符串和表达式的转换实战
  4. STL 容器 与 数据结构
  5. javascript面向对象编程实现[定义(静态)属性方法--继承]
  6. java多选代码_[一天一点java web]复选框全选代码
  7. Windows 新漏洞可被用于强制服务器以攻击者身份认证,官方缓解措施已发布
  8. OpenCV-Python实战(番外篇)——OpenCV、NumPy和Matplotlib直方图比较
  9. 高德发布十一出行预测:全国高速流量增长7%
  10. 2018DeeCamp面试问答
  11. 饿了么api接口 php,饿了么美团开放平台接入
  12. 想起某个人,想到某些事
  13. 程序员必知的 89 个操作系统核心概念
  14. 黑科技新添成员, 小米mix5再次创新, 但这些真的只是黑科技的全部吗?
  15. Incorrect number of arguments for FUNCTION XXX
  16. 35岁以后找工作难,只能熬到65岁才能退休,太惨 了!
  17. Android常用设计模式之Builder模式理解
  18. 从游戏开发到web前端——仅仅只是开始
  19. 欧瑞变频器故障码表_欧瑞变频器故障代码
  20. 找工作的“金三银四”,如何准备一份独特的“简历”

热门文章

  1. 【SpringCloudAlibaba】微服务组件Dubbo
  2. Ubuntu Linux
  3. 下城投 × 奇点云 |「数智城投驾驶舱」,打造转型示范新样板
  4. java 异步网络编程_java网络编程实战 - 基于BIO的伪异步、高并发、全双工、长链接持续消息IO的网络编程...
  5. java的serialization_Java序列化(Serialization) 机制
  6. 任天堂游戏 html5,明年的预备阵容!任天堂承诺却还没出的作品
  7. 程序员必读书籍排行榜,看看你读过的是否榜上有名
  8. 论文笔记(三):DAML: Dual Attention Mutual Learning between Ratings and Reviews for Item Recommendation
  9. 零基础使用vscode实现python爬取高德地铁数据
  10. 团队作业8----第二次项目冲刺(Beta阶段) 第二天