精华内容
下载资源
问答
  • 自回归文本生成模型通常侧重于局部的流畅性,在长文本生成过程中可能导致语义不一致。此外,自动生成具有相似语义的单词是具有挑战性的,而且手工编写的语言规则很难应用。
  • 使用pytorch生成文本:使用pytorch GRU构建文本生成模型
  • 文本生成的目标是让机器用人类语言表达。它是自然语言处理(NLP)中最重要也是最具挑战性的任务之一。自2014年以来,各种由Seq2Seq首创的神经编解码器模型被提出,通过学习将输入文本映射到输出文本来实现这一目标。
  • 研究基于场景描述文本生成对应图像的方法,针对生成图像常常出现的对象重叠和缺失问题,提出了一种结合场景描述的生成对抗网络模型。首先,利用掩模生成网络对数据集进行预处理,为数据集中的对象提供分割掩模向量。然后...
  • 文本生成前沿综述

    2018-11-06 00:37:49
    文本生成就是指期待未来有一天计算机能够像人类一样会表达,能够撰写出 高质量的自然语言文本。
  • 马尔可夫链 描述 使用马尔可夫链的英文文本生成器。 受到这个视频的启发,我做了这个: : 你可以在这里看到一个演示: :
  • TextGAN是用于基于生成对抗网络(GAN)的文本生成模型的PyTorch框架,包括常规文本生成模型和类别文本生成模型。 TextGAN是一个基准测试平台,可支持基于GAN的文本生成模型的研究。 由于大多数基于GAN的文本生成...
  • 主要介绍了java根据富文本生成pdf文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • T5Transformer_text_gen 利用Google T5文本生成功能,几乎没有文字生成功能。
  • 马尔可夫链 简单的Markov链文本生成
  • RNN实现文本生成

    2018-12-21 13:03:13
    用RNN实现的一个语言模型(实现的是可以自主生成歌词,用的是周杰伦的一些歌词,但由于是自己从网上下来的,前期预处理不是很好,每个人也可以用诗歌等训练,来生成诗歌)
  • TextBox是基于Python和PyTorch开发的,用于在统一,全面,高效的框架中复制和开发文本生成算法,以用于研究目的。 我们的库包含21种文本生成算法,涵盖两项主要任务: 无条件(无输入)生成 有条件的(Seq2Seq)...
  • 大一数据结构课程大作业,使用马尔可夫链生成随机文本,OJ测试时间大约3到5秒
  • 该代码是CVPR2018一篇关于文本到图像合成的文章,经过测试可以使用
  • LSTM文本生成 使用LSTM生成单词级文本。 体系结构:-预训练的嵌入-2 lstm层
  • 因个人需要开发的小工具,可支持两个变量的批量文本生成器,可用来产生大量不重复的数据,C#开发,win7运行环境(.net4.0以上)。
  • 利用LSTM自动生成文本,可根据不同的文本生成不同风格的文章
  • 主要就是python使用jieba分词统计词频然后生成标签云。
  • 文本生成领域的深度强化学习研究进展.pdf
  • 文本生成 只需几行代码,即可在任何文本数据集上轻松训练您自己的任意大小和复杂度的文本生成神经网络,或者使用预先训练的模型快速训练文本。 textgenrnn是上的顶部一个Python 3模块 / 用于创建 S,与许多凉爽...
  • 本文实例分享了Python文本生成二维码的详细代码,供大家参考,具体内容如下 测试一:将文本生成白底黑字的二维码图片 测试二:将文本生成带logo的二维码图片 #coding:utf-8 ''' Python生成二维码 v1.0 主要将文本...
  • Python-XLNet文本生成

    2019-08-10 06:24:40
    XLNet文本生成
  • 基于结构化数据生成文本(data-to-text)的任务旨在生成人类可读的文本来直观地描述给定的结构化数据。然而,目前主流任务设定所基于的数据集有较好的对齐 (well-aligned)关系,即输入(i.e. 结构化数据)和输出...

    摘要

    基于结构化数据生成文本(data-to-text)的任务旨在生成人类可读的文本来直观地描述给定的结构化数据。然而,目前主流任务设定所基于的数据集有较好的对齐 (well-aligned)关系,即输入(i.e. 结构化数据)和输出(i.e. 文本)具有相同或很接近的信息量,比如 WebNLG 当中的输入 triple set 和输出文本所描述的知识完全匹配。但是,这样的训练数据制作困难且成本很高,现有的数据集只限于少数几个特定的领域,基于此训练的模型在现实应用中存在较大的局限性。

    因此,我们提出了基于部分对齐(partially-aligned)样本的文本生成任务。部分对齐数据的优势在于获取门槛低,可以用自动或半自动方式构造,因而更容易拓展到更多的领域。我们考虑了两个对偶的部分对齐场景,即输入数据多于文本描述和文本描述多于输入数据。

    对于数据多于文本的情况,我们发布了 ENT-DESC 数据集 [1],并且针对数据中存在冗余信息的问题,我们提出了多图卷积神经网络 (Multi-Graph Convolutional Network)模型来抽取重要信息,生成更为凝练的文本描述。

    对于文本多于数据的情况,我们发布了 WITA 数据集 [2],并且针对训练样本中文本的多余信息,提出了远程监督生成(Distant Supervision Generation)框架,以确保基于非严格对齐样本训练的模型,在应用中能够如实地生成给定数据的描述。

    基础模型层面,本文将介绍我们提出的轻量、动态图卷积网络 (Lightweight, Dynamic Graph Convolutional Networks),简称 LDGCN [3],可以有效的融合图结构中来自不同阶节点的信息,进而学习更优的图表示,并提升下游文本生成的效果。

    参考文献

    [1] ENT-DESC: Entity Description Generation by Exploring Knowledge Graph. Liying Cheng, Dekun Wu, Lidong Bing, Yan Zhang, Zhanming Jie, Wei Lu, Luo Si. EMNLP, 2020.

    [2] Partially-Aligned Data-to-Text Generation with Distant Supervision. Zihao Fu, Bei Shi, Wai Lam, Lidong Bing, Zhiyuan Liu. EMNLP, 2020.

    [3] Lightweight, Dynamic Graph Convolutional Networks for AMR-to-Text Generation. Yan Zhang, Zhijiang Guo, Zhiyang Teng, Wei Lu, Shay B. Cohen, Zuozhu Liu, Lidong Bing. EMNLP, 2020.

    一、非严格对齐的文本生成:输入数据多于文本描述

    图片

    论文标题:

    ENT-DESC: Entity Description Generation by Exploring Knowledge Graph

    论文链接:

    https://www.aclweb.org/anthology/2020.emnlp-main.90.pdf

    数据代码连接:

    https://github.com/LiyingCheng95/EntityDescriptionGeneration

    1.1 任务设置

    本篇论文的基本出发点是提出一个实用的主题化文本生成任务设定,而这个设定下构造的数据集具有输入数据多于生成文本的特点。现有结构化数据到文本生成的任务要求输出的信息在输入的结构化数据中有很充分的体现,比如 WebNLG 数据集 [1] 等。

    这样的任务设定和数据准备在实际应用中均有一定的局限性。而本篇论文所提出的主题化实体描述生成,是在给定一个主实体(main entity)的前提下,通过利用该实体的多个附属主题实体(topic-related entity),对生成的主实体描述进行一定的导向和限制,使其符合某一主题。

    图片

    上图例子中,红色框内是输入的主实体(Bruno Mars)和多个附属主题实体(funk, rock, R&B 等),目标是生成符合这一特定主题的文本描述,如蓝色方框所示,来介绍 Bruno Mars 其人以及其音乐风格等。为了使生成的描述符合现实世界的知识,我们依据输入实体,有选择性地利用知识图谱中关于这些实体的知识,如绿色方框所示,辅助生成该实体的主题化描述。本任务相较于现有的生成任务更具有实用性和挑战性。

    1.2 ENT-DESC数据集

    基于这样的任务设定,本篇论文提出了一个新的数据集 ENT-DESC。此数据集采用了较为普遍和常规的维基百科数据集和 WikiData 知识图谱。

    首先,我们用 Nayuki 的工具(https://www.nayuki.io/page/computing-wikipedias-internal-pageranks)去给超过 990 万维基百科页面计算 PageRank。然后我们根据 PageRank 排名,选用了来自于四种主要领域的 11 万主实体名词,以及维基百科第一段文本中带有超链接的名词作为附属主题实体。

    我们即用每个维基百科页面的第一段文本作为输出。另外我们利用已有知识图谱 Wikidata,选取了主实体的相邻实体,以及主实体和附属主题实体间的 1 跳和 2 跳路径。据我们所知,ENT-DESC 是现有知识图谱生成文本的类似数据集中规模最大的。其与部分现有数据集的比较如下图所示。

    图片

    此数据集的一大特性为输入中包含输出内容以外的信息,因此要求模型可以有效选取输入中更为有用的信息去做生成。有关 ENT-DESC 数据集以及其更详细的准备和处理步骤可参阅:

    https://github.com/LiyingCheng95/EntityDescriptionGeneration/tree/master/sockeye/data/ENT-DESC%20dataset

    1.3 MGCN模型

    在模型层面,现有序列到序列的文本生成模型不能够很好地利用图的结构与信息,而图到序列模型 [2] 将图中实体间的关系变为实体的参数,此类模型遇到信息丢失和参数过多的问题。有论文提出了 Levi 图转换方法 [3],即将原始图中的关系转化成点,以用于解决前面提到的问题。但是 Levi 图转化仍然有它自己的缺陷。

    在 Levi 图中,我们不能很好的区分哪些点是原始图中的实体或关系,并且实体间的直接联系在 Levi 图中被忽略。另外,不同类型的边被融合在 Levi 图中一起学习,不能很好地区分不同类型边的不同重要性。

    为了解决现有模型在本篇论文提出的知识图谱驱动实体文本描述生成的任务上的缺陷,本篇论文采用了编码-解码架构(encoder-decoder),提出了一种基于多图卷积神经网络(Multi-Graph Convolutional Network)的文本生成模型。

    图片

    在多图编码器(Multi-Graph Encoder)中,不同于传统的图编码器,我们叠加了多层多图卷积神经网络。每层多图卷积神经网络的结构如左图所示。我们先将输入图嵌入转化为 6 个不同图的邻接矩阵,分别放入 6 个图编码器,以此得到 6 个包含不同类型信息的图嵌入。继而将这些图嵌入进行聚合运算,得到下一层的图嵌入。

    解码器(decoder)是一个基于标准的长短时记忆网络(LSTM)的文本生成模型。本篇论文中的解码器对于在编码过程中学习到的隐藏子图的特征与结构信息进行解码,并生成相应的描述文本。此模型结构有效避免了信息丢失和参数过多的问题,有选择性地捕捉了多图中的重要信息并进行了有效聚合。

    图片

    上图展示了多图转化的过程。类似于 Levi 图转化的过程,我们将原始图中的边转化为点。

    (1)在 g1:self 图中,我们给所有的点加一条自循环的边。(2)在 g2:default1 图中,我们把点和边按原始图中的默认顺序进行连接。(3)在 g3:reverse1 中,我们将 g2 中的边进行反向连接。(4)在 g4:default2 中,我们将点和点之间按默认顺序连接。(5)类似地,在 g5:reverse2 中,我们将点和点之间的边反向相连。(6)最后,我们额外加了全局点(gnode),并把它与图中其他所有点按图中方向相连。

    它的创新之处在于将原始图中的点到点、点到边的正向与反向信息明确地表示在不同图中,这样简单明了的转化过程对多图卷积神经网络中的学习起到了巨大的帮助作用。

    1.4 主要实验结果

    我们在本篇论文所提出的 ENT-DESC 数据集和 WebNLG 数据集上均实验了提出的模型。下图是我们在 ENT-DESC 数据集上的主要实验结果。

    图片

    我们与序列到序列生成模型及多种图到序列生成模型在多种评测标准上均做了比较。从表格和图中,我们可以观察到,现有图到序列模型可以达到 BLEU 值 24.8,现有深层图到序列模型[4] 的 BLEU 值为 24.9。而我们的多图神经网络结构在 6 层时可以达到 25.7 的 BLEU 值,加上聚合运算后可以达到 26.4。

    由此可见,我们提出的多图卷机神经网络的模型有效地捕捉了知识图谱中的重要信息并进行了有效聚合。我们进一步对数据进行了归一化处理(delexicalization),实验结果均有更进一步的提升。

    另外,此模型在 ENT-DESC 数据集以及现有数据集上(如:WebNLG)相对于多个基准模型在多个评测标准上均显示明显提升,同时其可被扩展应用于其他图相关的自然语言处理研究中。

    上图展示了知识驱动文本生成的例子。红色高亮文本是主要实体,蓝色高亮文本是附属主题实体。与维基百科的参考文本相比,我们提出的多图卷积神经网络与聚合运算能够准确捕捉到主要实体以及大部分附属主题实体。而传统的图到序列生成模型未能识别出主要实体。这进一步体现了传统图到序列模型会造成信息丢失的情况,同时也体现了多图卷积神经网络对于提取重要信息的有效性。

     

    参考文献

    [1] Claire Gardent, Anastasia Shimorina, Shashi Narayan, and Laura Perez-Beltrachini. 2017. The webnlg challenge: Generating text from rdf data. In Proceedings of INLG.

    [2] Diego Marcheggiani and Ivan Titov. 2017. Encoding sentences with graph convolutional networks for semantic role labeling. In Proceedings of EMNLP.

    [3] Daniel Beck, Gholamreza Haffari, and Trevor Cohn. 2018. Graph-to-sequence learning using gated graph neural networks. In Proceedings of ACL.

    [4] Zhijiang Guo, Yan Zhang, Zhiyang Teng, and Wei Lu. 2019. Densely connected graph convolutional networks for graph-to-sequence learning. TACL

    非严格对齐的文本生成:文本描述多于输入数据

    图片

    论文标题:

    Partially-Aligned Data-to-Text Generation with Distant Supervision

    论文链接:

    https://www.aclweb.org/anthology/2020.emnlp-main.738.pdf

    数据代码链接:

    https://github.com/fuzihaofzh/distant_supervision_nlg

    2.1 简介

    在基于结构化数据生成文本(data-to-text)[1,2] 任务中,现有的模型要求训练的数据和文本是严格对齐的(well-aligned),导致可以用于训练的数据非常稀少且标注代价高昂,因此,现有的经典生成任务只限于少数几个特定的领域。

    本文旨在探索使用部分对齐(partially-aligned)的数据来解决数据稀缺的问题。部分对齐的数据可以自动爬取、标注,从而能将文本生成任务推广到更多的数据稀缺的领域。但是,直接使用此类数据来训练现有的模型会导致过度生成的问题(over-generation),即在生成的句子中添加与输入无关的内容

    为了使模型能够利用这样的数据集来训练,我们将传统的生成任务扩展为“部分对齐的数据到文本生成的任务”(partially-aligned data-to-text generation task),因为它利用自动标注的部分对齐数据进行训练,因此可以很好地被应用到数据稀缺领域。

    为了解决这一任务,我们提出了一种新的远程监督(distant supervision)训练框架,通过估计输入数据对每个目标词的支持度,来自动调节相应的损失权重,从而控制过度生成的问题。我们通过从 Wikipedia 中抽取句子并自动提取相应的知识图谱三元组的方式制作了部分对齐的 WITA 数据集。

    实验结果表明,相较于以往的模型,我们的框架能更好地使用部分对齐的数据,缓解了过度生成问题,从而验证了使用部分对齐的数据来训练生成模型的可行性。本文的数据和源代码可以从下方链接获取

    https://github.com/fuzihaofzh/distant_supervision_nlg

    2.2 WITA数据集

    我们通过抽取 Wikipedia 句子中的三元组来自动构建部分对齐的数据集。整个抽取框架如图所示。

    图片

    首先,我们提取出 Wikipedia 每篇文章的第一个句子,随后,我们用实体检测器(Entity Detector)来抽取出每个句子所包含的所有实体,该实体检测器包含三个部分,分别是链接检测,NER 检测以及名词检测,其中 NER 检测和名词检测通过 spaCy 实现。接着,这些名词经过一些规则过滤后,两两组合(笛卡尔积)得到了实体对(Entity Pair)的列表。

    另一方面,我们将 Wikidata 导入到 ElasticSearch,Wikidata 是一个知识图谱的库,包含了很多客观信息的三元组描述。

    我们用每个三元组的头尾实体对做索引,用整个三元组做值,这样一旦给定一个实体对,我们就能方便地通过查询 ElasticSearch 得到他们之间的三元组关系。我们将笛卡尔积中的每个实体对输入到 ElasticSearch 中查询他们的关系,通过一些规则过滤,得到最终句子对应的三元组。

    下表是我们的新的数据集(WITA)和现有的数据集 WebNLG [1] 的对比。我们发现,我们的数据集比 WebNLG 大,同时包含的关系种类(Relation Type)是 WebNLG 的两倍,含有的实体种类是 WebNLG 的 40 倍,而包含的词典大小也是 WebNLG 的 12 倍。因此 WITA 数据集包含有更广阔领域的信息。

    图片

    然而,这种自动标注的数据并不是严格对齐的,如图所示,因为很多信息 Wikidata 中并不包含,所以文本会包含比三元组多的信息。直接使用此类数据来训练现有的模型会导致过度生成的问题(over-generation)。

    在图中,文本中红色的部分是三元组中未包含的信息,普通的生成模型会错误地认为这些信息是由给定三元组的某些部分给出的,因此,在使用训练好的模型做生成时,给定一些数据,它会生成额外的未提及的信息。

    以下图为例,训练数据中“develpoed in Canada”就没有对应的三元组描述,模型会错误地将其绑定到给定的 genre 三元组中,因此,在生成关于另一个 genre 三元组的描述时,就可能会加上这个冗余的信息。我们提出了远程监督生成框架(Distant Supervision Generation)来解决这个问题。

    图片

    2.3 模型框架

    如图所示,我们的远程监督生成框架(Distant Supervision Generation framework)包含了四个模块:

    1)支持度估计器(Supportiveness Estimator,SE);2)序列到序列生成器(Sequence-to-Sequence Generator,S2SG);3)支持度适配器(Supportiveness Adaptor,SA);4)重平衡集束搜索(Rebalanced Beam Search,RBS)。下面我们分别来看每个模块的作用。

    图片

    这项损失防止三元组中的某个词支持太多的目标文本词。最后,总体的优化目标是以上损失的加权组合:

    图片

     

    图片

    S2SG 模块主要负责文本生成,我们通过 Transformer [3] 来实现。

    SA 模块将 SE 模块得出的支持度适配到 S2SG 的每个词的损失上

    图片

    2.4 主要实验结果

    下表是主要实验结果,我们对比了一些常见的生成模型,其中 S2S [4] 采用基于 LSTM 的 sequence-to-sequence 模型,而 S2ST [3,5] 则是基于 Transformer 的生成模型,DSG-A 和 DSG-H 则是分别采用 Attention Adaptor 和 Hard Adaptor。

    通过对比,我们发现,加入 Supportiveness Adaptor 之后,系统的性能都有所提升,而我们提出支持度计算和适配的方法取得了最好的效果。通过消融实验,我们可以观察到 RBS 和 SA 都明显地提升了模型效果。

    图片

    下图是对比了我们的支持度和传统注意力值的热力图。我们可以看到,因为注意力机制本身有归一化的约束,导致了一个词的支持度之和是固定的,这样,如果有很多词支持,就会分散支持的权重,因而我们的支持度计算方法比直接用注意力当支持度能更好地反应支持度的强弱。

    图片

    为了更直观地展示 DSG 模型能很好地解决过度生成问题。我们采样了一些输出结果作对比,通过把和输入不相关的生成部分用红字标出,可以发现,如果直接用 WITA 数据来训练传统的 S2ST 模型,生成的时候会产生很严重的过度生成的问题,而我们提出的 DSG 模型则能很好地解决这个问题,取得好的生成效果

    图片

     

    参考文献

     

    [1] Claire Gardent, Anastasia Shimorina, Shashi Narayan, and Laura Perez-Beltrachini. 2017. Creating training corpora for nlg micro-planners. ACL.

    [2] Remi Lebret, David Grangier, and Michael Auli. 2016. Neural text generation from structured data with applicationthe biography domain. EMNLP.

    [3] Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez, Łukasz Kaiser, and Illia Polosukhin. 2017. Attention is all you need. NIPS.

    [4] Anastasia Shimorina and Claire Gardent. 2018. Handling rare items in data-to-text generation. INLG.

    [5] Myle Ott, Sergey Edunov, Alexei Baevski, Angela Fan, Sam Gross, Nathan Ng, David Grangier, and Michael Auli. 2019. fairseq: A fast, extensible toolkit for sequence modeling. NAACL.

    三、轻量、动态图卷积网络及其在文本生成中的应用

    图片

    论文标题:

    Lightweight, Dynamic Graph Convolutional Networks for AMR-to-Text Generation.

    论文链接:

    https://www.aclweb.org/anthology/2020.emnlp-main.169.pdf

    代码链接:

    https://github.com/yanzhangnlp/LDGCNs

    3.1 简介

    图神经网络(Graph Neural Networks)是学习图表示的一类强大方法,已应用于许多自然语言处理任务中,例如信息抽取,情感识别和文本生成。图卷积网络(Graph Convolutional Networks),是图神经网络中的一种。

    相比于图循环网络(Graph Recurrent Networks) 以及最近的图变换网络(Graph Transformer Networks),  图卷积网络具有更好的计算效率。但由于图卷积网络遵循邻接信息(First-order)传递机制,对高阶信息的融合不如图循环网络和图变换网络。

    为此,我们提出了一种动态融合机制,可以有效的融合图结构中来自不同阶节点的信息。具体地,我们利用了门控机制动态接受图结构中不同阶节点的信息流,从而可以同时融合低阶和高阶的信息。例外,我们还提出了两种参数共享机制,减少了模型的复杂度,提高了模型的效率。

    结合动态融合机制和参数共享机制的图卷积网络,我们称之为轻量、动态图卷积网络(Lightweight, Dynamic Graph Convolutional Networks),简称 LDGCN。

    我们在 AMR-to-Text Generation 这一类文本生成任务中进行了实验。AMR(Abstract Meaning Representation)是一种将句子的语义抽象表示的有根有向图(rooted directed graph),其中节点(nodes)是概念(concept),边(edges)是语义关系(semantic relations)。

    AMR-to-Text Generation 是将 AMR 图编码并解码成表达其含义的文本。这个任务的关键挑战在于如何有效捕获基于图的数据中存储的复杂结构信息。实验结果表明,我们的模型 LDGCN, 不仅性能优于其他图神经网络模型,而且模型十分轻便,参数量远少于性能最好的图变换网络模型。

    3.2 模型框架

    3.2.1 动态融合机制

    图片

    传统的图卷积网络受限于邻接信息传递机制,忽略了高阶有效信息,受门控线性单元(Gated Linear Units)的启发 [1],我们提出了动态融合机制。该机制可以让图卷积网络融合来自不同阶节点的信息同时保留模型的非线性特性。如上图所示,模型工作流程如下。每一个图卷积层均以 k 个 k 阶邻接矩阵为输入(这里 k=3),  动态融合机制,利用门控方式,整合从 1 到 k 跳邻居的信息,其函数表示如下:

    图片

    其中, G 是一个基于高阶邻接矩阵信息的门控矩阵,表示为:

    图片

    3.2.2 参数共享机制

    深度图卷积网络一般能够表现出更好的性能,但越深的网络也会导致更多的参数,从而增加了计算上的复杂度。为了提高模型的效率,我们提出了图分组卷积(Group Graph Convolution)和权重绑定卷积(Weight Tied Convolutions)两种参数共享机制。其中,图分组卷积用于减少每一层图卷积网络的参数而权重绑定卷积则用于层与层之间参数的共享。

    受分组卷积 [2] 的启发,我们提出了两种在图卷积网络上的拓展,即深度图分组卷积(Deepthwise Group Graph Convolution)和层级图分组卷积(Layerwise Group Graph Convolution).

    图片

    如上图所示,对于深度图分组卷积,输入表示和输出表示被分成了不相交的 n 组(这里 n=3)进行计算。将三组表示拼接则为输出层表示。这样每一层的参数可以减少 n 倍。

    图片

    层级图分组卷积是基于最近的密集连接图卷积网络 [3] 提出的。如上图所示,在密集连接图卷积中,每一层的输入来自于之前所有卷积层输出拼接而成。而层级图分组卷积在此基础之上,还将输入表示分成了 n 组(这里 n=3)进行计算。

    图片

     

    启发于最近的权重绑定自注意力网络 [4],我们提出了权重绑定图卷积。如上图所示,在权重绑定图卷积中,每一层都使用相同的参数。从而较大地节省了模型的参数。

    3.3 主要实验结果

    图片

    图片

    基于不同的参数共享机制,我们分别命名为 LDGCN_WT(Weight Tied)和LDGCN_GC(Group Convolution)。我们主要在两个标准的 AMR 数据集上进行了实验, 即 AMR2015(LDC2015E86)和 AMR2017(LDC2017T10)。

    上面表 1 展示了两个数据集上的结果(B, C, M 和 #P 分别代表 BLEU, CHRF++, METEOR 和模型的参数量)。我们的模型 LDGCN_GC 在两个数据集上都取得了最好的结果。而且相比当前最好的图变换网络模型 GT_SAN,我们的模型只需要大约五分之一的参数。而相比于其他图卷积网络,我们的模型也都远远强于当前最好的模型 DCGCN 以及 DualGraph。

    表 2 展示了模型在大规模数据集上的结果。可以看到,我们模型 LDGCN_WT,优于当前最好的 Transformer 模型,且只使用了其四分之一数据(0.5M)。而与表1结果不同的是,在使用较大数据的情况下,LDGCN_WT 效果优于 LDGCN_GC。我们推测,足够的数据可以提供足够的正则化来减少震荡,稳定 LDGCN_WT 的训练过程。

     

    参考文献

    [1] Yann Dauphin, Angela Fan, Michael Auli, and David Grangier. 2016. Language modeling with gated convolutional networks. In Proc. of ICML.

    [2] Andrew G. Howard, Menglong Zhu, Bo Chen, Dmitry Kalenichenko, Weijun Wang, Tobias Weyand, Marco Andreetto, and Hartwig Adam. 2017. Mobilenets: Efficient convolutional neural networks for mobile vision applications. ArXiv, abs/1704.04861.

    [3] Zhijiang Guo, Yan Zhang, Zhiyang Teng, and Wei Lu. 2019b. Densely connected graph convolutional networks for graph-to-sequence learning. Transactions of the Association for Computational Linguistics, 7:297–312.

    [4] Shaojie Bai, J. Zico Kolter, and Vladlen Koltun. 2019a. Deep equilibrium models. In Proc. of NeurIPS.

    四、总结

    文本生成作为近年来引起广泛关注的研究课题,有着丰富的应用场景。基于结构化数据和知识的文本生成是一个重要的研究方向。本文探索的非严格对齐的文本生成任务设定,给基于知识的文本生成任务引入了更实用化的新发展,我们公布了两个新数据集以支持这方面的研究。另外,本文介绍的轻量、动态 GCN 模型 LDGCN,不但可以有效的融合图结构中来自不同阶节点的信息,还可以通过参数共享机制,提高 GCN 模型的效率。

    展开全文
  • 文本生成:基于GPT-2的中文新闻文本生成

    万次阅读 多人点赞 2020-03-07 00:42:27
    文本生成一直是NLP领域内研究特别活跃的一个任务,应用前景特别广泛。BERT类预训练模型基于MLM,融合了双向上下文信息,不是天然匹配文本生成类任务(也有针对BERT模型进行改进的多种方式完善了BERT的这个缺点,如...

    文本生成一直是NLP领域内研究特别活跃的一个任务,应用前景特别广泛。BERT类预训练模型基于MLM,融合了双向上下文信息,不是天然匹配文本生成类任务(也有针对BERT模型进行改进的多种方式完善了BERT的这个缺点,如UniLM)。openAI的GPT-2模型天然适合文本生成类任务,因此使用GPT-2模型来完成中文新闻文本生成任务。
    代码及数据、模型下载链接:网盘链接,提取码:8goz

    数据集

    数据集是THUCnews的,清华大学根据新浪新闻RSS订阅频道2005-2011年间的历史数据筛选过滤生成。总共有体育、财经等共10个类别新闻,筛选出其中的财经类新闻作为训练语料。使用BERT的tokenizer,可以分词也可以不分词。选择分词的话最好根据训练语料提取一份词表,不分词的话可以直接使用原BERT模型提供的词表。GPT-2模型训练要求语料连续,最好是段落或者大文档类不能太短,否则影响模型表现。训练前将语料预处理切分。勾选raw,自动处理语料。

    def build_files(data_path, tokenized_data_path, num_pieces, full_tokenizer, min_length):
        with open(data_path, 'r', encoding='utf8') as f:
            print('reading lines')
            lines = json.load(f)
            lines = [line.replace('\n', ' [SEP] ') for line in lines]  # 用[SEP]表示换行, 段落之间使用SEP表示段落结束
    
        all_len = len(lines)
        if not os.path.exists(tokenized_data_path):
            os.makedirs(tokenized_data_path)
        for i in tqdm(range(num_pieces)):
            sublines = lines[all_len // num_pieces * i: all_len // num_pieces * (i + 1)]
            if i == num_pieces - 1:
                sublines.extend(lines[all_len // num_pieces * (i + 1):])  # 把尾部例子添加到最后一个piece
            sublines = [full_tokenizer.tokenize(line) for line in sublines if
                        len(line) > min_length]  # 只考虑长度超过min_length的句子
            sublines = [full_tokenizer.convert_tokens_to_ids(line) for line in sublines]
            full_line = []
            for subline in sublines:
                full_line.append(full_tokenizer.convert_tokens_to_ids('[MASK]'))  # 文章开头添加MASK表示文章开始
                full_line.extend(subline)
                full_line.append(full_tokenizer.convert_tokens_to_ids('[CLS]'))  # 文章之间添加CLS表示文章结束
            with open(tokenized_data_path + 'tokenized_train_{}.txt'.format(i), 'w') as f:
                for id in full_line:
                    f.write(str(id) + ' ')
        print('finish')
    

    模型训练

    模型代码使用huggingface提供的GPT-2 model,使用AdamW优化器,warmup2000个step,使用线性衰减,初始学习率设置为1.5e-4,总共训练了5个epoch,大概35K个iteration。

    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument('--device', default='0,1,2,3', type=str, required=False, help='设置使用哪些显卡')
        parser.add_argument('--model_config', default='models/model_config.json', type=str, required=False,
                            help='选择模型参数')
        parser.add_argument('--tokenizer_path', default='models/vocab.txt', type=str, required=False, help='选择词库')
        parser.add_argument('--raw_data_path', default='./data/cnews.json', type=str, required=False, help='原始训练语料')
        parser.add_argument('--tokenized_data_path', default='data/tokenized/', type=str, required=False,
                            help='tokenized语料存放位置')
        parser.add_argument('--raw', action='store_true', help='是否先做tokenize')
        parser.add_argument('--epochs', default=5, type=int, required=False, help='训练循环')
        parser.add_argument('--batch_size', default=1, type=int, required=False, help='训练batch size')
        parser.add_argument('--lr', default=1.5e-4, type=float, required=False, help='学习率')
        parser.add_argument('--warmup_steps', default=2000, type=int, required=False, help='warm up步数')
        parser.add_argument('--log_step', default=10, type=int, required=False, help='多少步汇报一次loss,设置为gradient accumulation的整数倍')
        parser.add_argument('--stride', default=768, type=int, required=False, help='训练时取训练数据的窗口步长')
        parser.add_argument('--gradient_accumulation', default=1, type=int, required=False, help='梯度积累')
        parser.add_argument('--fp16', action='store_true', help='混合精度')
        parser.add_argument('--fp16_opt_level', default='O1', type=str, required=False)
        parser.add_argument('--max_grad_norm', default=1.0, type=float, required=False)
        parser.add_argument('--num_pieces', default=50, type=int, required=False, help='将训练语料分成多少份')
        parser.add_argument('--min_length', default=128, type=int, required=False, help='最短收录文章长度')
        parser.add_argument('--output_dir', default='models/cnews', type=str, required=False, help='模型输出路径')
        parser.add_argument('--pretrained_model', default='', type=str, required=False, help='模型训练起点路径')
        parser.add_argument('--writer_dir', default='runs/', type=str, required=False, help='Tensorboard路径')
        parser.add_argument('--segment', action='store_true', help='中文以词为单位')
    
        args = parser.parse_args()
        print('args:\n' + args.__repr__())
    
        if args.segment:
            from tokenization import tokenization_bert_word_level as tokenization_bert
        else:
            from tokenization import tokenization_bert
    
        os.environ["CUDA_VISIBLE_DEVICES"] = args.device  # 此处设置程序使用哪些显卡
    
        model_config = GPT2Config.from_json_file(args.model_config)
        print('config:\n' + model_config.to_json_string())
    
        n_ctx = model_config.n_ctx
    
        full_tokenizer = tokenization_bert.BertTokenizer(vocab_file=args.tokenizer_path)
        full_tokenizer.max_len = 999999
        device = 'cuda' if torch.cuda.is_available() else 'cpu'
        print('using device:', device)
    
        raw_data_path = args.raw_data_path
        tokenized_data_path = args.tokenized_data_path
        raw = args.raw  # 选择是否从零开始构建数据集
        epochs = args.epochs
        batch_size = args.batch_size
        lr = args.lr
        warmup_steps = args.warmup_steps
        log_step = args.log_step
        stride = args.stride
        gradient_accumulation = args.gradient_accumulation
        fp16 = args.fp16  # 不支持半精度的显卡请勿打开
        fp16_opt_level = args.fp16_opt_level
        max_grad_norm = args.max_grad_norm
        num_pieces = args.num_pieces
        min_length = args.min_length
        output_dir = args.output_dir
    
        assert log_step % gradient_accumulation == 0
    
        if not os.path.exists(output_dir):
            os.mkdir(output_dir)
    
        if raw:
            print('building files')
            build_files(data_path=raw_data_path, tokenized_data_path=tokenized_data_path, num_pieces=num_pieces,
                        full_tokenizer=full_tokenizer, min_length=min_length)
            print('files built')
    
        if not args.pretrained_model:
            model = GPT2LMHeadModel(config=model_config)
        else:
            model = GPT2LMHeadModel.from_pretrained(args.pretrained_model)
        model.train()
        model.to(device)
    
        num_parameters = 0
        parameters = model.parameters()
        for parameter in parameters:
            num_parameters += parameter.numel()
        print('number of parameters: {}'.format(num_parameters))
    
        multi_gpu = False
        full_len = 0
        print('calculating total steps')
        for i in tqdm(range(num_pieces)):
            with open(tokenized_data_path + 'tokenized_train_{}.txt'.format(i), 'r') as f:
                full_len += len([int(item) for item in f.read().strip().split()])
        total_steps = int(full_len / stride * epochs / batch_size / gradient_accumulation)
        print('total steps = {}'.format(total_steps))
    
        optimizer = AdamW(model.parameters(), lr=lr, correct_bias=True)
        scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=warmup_steps,
                                                              num_training_steps=total_steps)
        if fp16:
            try:
                from apex import amp
            except ImportError:
                raise ImportError("Please install apex from https://www.github.com/nvidia/apex to use fp16 training.")
            model, optimizer = amp.initialize(model, optimizer, opt_level=fp16_opt_level)
    
        if torch.cuda.device_count() > 1:
            print("Let's use", torch.cuda.device_count(), "GPUs!")
            model = DataParallel(model, device_ids=[int(i) for i in args.device.split(',')])
            multi_gpu = True
        print('starting training')
        overall_step = 0
        total_loss = 0
        logging_loss = 0
        tb_writer = SummaryWriter(log_dir=args.writer_dir)
        for epoch in trange(epochs):
            print('epoch {}'.format(epoch + 1))
            now = datetime.now()
            print('time: {}'.format(now))
            x = np.linspace(0, num_pieces - 1, num_pieces, dtype=np.int32)
            random.shuffle(x)
            for i in x:
                with open(tokenized_data_path + 'tokenized_train_{}.txt'.format(i), 'r') as f:
                    line = f.read().strip()
                tokens = line.split()
                tokens = [int(token) for token in tokens]
                start_point = 0
                samples = []
                while start_point < len(tokens) - n_ctx:
                    samples.append(tokens[start_point: start_point + n_ctx])
                    start_point += stride
                if start_point < len(tokens):
                    samples.append(tokens[len(tokens)-n_ctx:])
                random.shuffle(samples)
                for step in range(len(samples) // batch_size):  # drop last
    
                    #  prepare data
                    batch = samples[step * batch_size: (step + 1) * batch_size]
                    batch_inputs = []
                    for ids in batch:
                        int_ids = [int(x) for x in ids]
                        batch_inputs.append(int_ids)
                    batch_inputs = torch.tensor(batch_inputs).long().to(device)
    
                    #  forward pass
                    outputs = model.forward(input_ids=batch_inputs, labels=batch_inputs)
                    loss, logits = outputs[:2]
    
                    #  get loss
                    if multi_gpu:
                        loss = loss.mean()
                    if gradient_accumulation > 1:
                        loss = loss / gradient_accumulation
    
                    #  loss backward
                    if fp16:
                        with amp.scale_loss(loss, optimizer) as scaled_loss:
                            scaled_loss.backward()
                            torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), max_grad_norm)
                    else:
                        loss.backward()
                        torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)
    
                    total_loss += loss.item()
                    #  optimizer step
                    if (overall_step + 1) % gradient_accumulation == 0:
                        optimizer.step()
                        optimizer.zero_grad()
                        scheduler.step()
                    if (overall_step + 1) % log_step == 0:
                        scale_loss = (total_loss - logging_loss) / log_step
                        tb_writer.add_scalar('loss', scale_loss, overall_step)
                        tb_writer.add_scalar('lr',scheduler.get_lr()[0],overall_step)
                        print('Step {} epoch {}, loss {}'.format(
                            overall_step + 1,
                            epoch + 1,
                            scale_loss))
                        logging_loss = total_loss
                    overall_step += 1
    
            print('saving model for epoch {}'.format(epoch + 1))
            if not os.path.exists(os.path.join(output_dir, 'model_epoch{}'.format(epoch + 1))):
                os.makedirs(os.path.join(output_dir, 'model_epoch{}'.format(epoch + 1)))
            model_to_save = model.module if hasattr(model, 'module') else model
            model_to_save.save_pretrained(os.path.join(output_dir, 'model_epoch{}'.format(epoch + 1)))
            # torch.save(scheduler.state_dict(), output_dir + 'model_epoch{}/scheduler.pt'.format(epoch + 1))
            # torch.save(optimizer.state_dict(), output_dir + 'model_epoch{}/optimizer.pt'.format(epoch + 1))
            print('epoch {} finished'.format(epoch + 1))
    
            then = datetime.now()
            print('time: {}'.format(then))
            print('time for one epoch: {}'.format(then - now))
    
        print('training finished')
        model_to_save = model.module if hasattr(model, 'module') else model
        model_to_save.save_pretrained(output_dir)
    

    模型结果评估

    模型loss曲线如下:
    在这里插入图片描述模型生成时提供了top-k以及top-p选择,temperature可调以及repetition_penalty,针对生成时解码较慢的情况,huggingface还贴心的提供了past回传。运行generation.py文件,即可查看模型生成效果:
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

    分析

    基于GPT-2的中文文本生成还有很大很广阔的发展研究空间以及很多任务待解决,其应用领域也很多。

    展开全文
  • 文本生成keras 使用CNN和GRU层的Keras文本生成实现
  • VAE for 文本生成

    千次阅读 2020-03-22 14:24:15
    变分自编码器(Variational auto-encoder,VAE)是一类重要的生成模型(generative model),它于2013年由Diederik P.Kingma和Max Welling提出[1]。2016年Carl Doersch写了一篇VAEs的tutorial[2],对VAEs做...

    VAE详解:https://spaces.ac.cn/archives/5253

          变分自编码器(Variational auto-encoder,VAE)是一类重要的生成模型(generative model),它于2013年由Diederik P.Kingma和Max Welling提出[1]。2016年Carl Doersch写了一篇VAEs的tutorial[2],对VAEs做了更详细的介绍,比文献[1]更易懂。
          VAE的总体目标和GAN基本一致,都是希望通过构建一个从隐变量Z生成目标数据X的模型,他们假设Z服从某种常见分布(比如正态分布),然后训练一个模型X=g(Z),这个模型能够将原来的概率分布映射到训练集的概率分布,这样我们就通过这边模型生成与符合训练数据概率分布的新的数据了。
             
    与自编码对比:
          自编码通过编码器将输入x进行编码成z,然后通过解码器将z解码成x`,使得x`与x一样。缺陷:1.需要有原始输入,是有监督的;2.生成的结果是使得x`与原始输入一样,不能泛化生成多样的结果。3.主要用于获取输入的隐藏表示。
         变分自编码结构与自编码类似,也是由编码器和解码器构成,不同的是在编码的目标是生成一个概率分布 q(z|x)代替确定性z来重建输入,强制模型将输入映射到空间的区域而不是单个点,。在这种情况下,实现良好重构误差的最直接方法是预测非常潜在的概率分布,有效地对应于潜在空间中的单个点(Raiko等人2014)。引入 KL divergence 让后验 q(z|x) 接近先验 p(z).
     

    VAE在文本生成领域的应用:

      
      实质:以自编码框架为基础,通过分层编码和解码的方式将词与句子信息综合考虑。如下图,虚线部分为attention
              
     
    【  Generating Sentences from a Continuous Space】-第20届计算自然语言学习大会 2016
     
         作者为了弥补传统的 RNNLM 结构缺少的一些全局特征(其实可以理解为想要 sentence representation)。其实抛开 generative model,之前也有一些比较成功的 non-generative 的方法,比如 sequence autoencoders[1],skip-thought[2] 和 paragraph vector[3]。但随着 VAE 的加入,generative model 也开始在文本上有更多 的可能性。

          Loss 的组成还是和 VAE 一样。具体模型上,encoder 和 decoder 都采用单层的 LSTM,decoder 可以看做是特殊的 RNNLM,其 initial state 是这个 hidden code z(latent variable),z 采样自 Gaussian 分布 G,G 的参数由 encoder 后面加的一层 linear layer 得到。这里的 z 就是作者想要的 global latent sentence representation,被赋予了先验diagonal Gaussians,同时 G 就是学到的后验。
           模型很简单,但实际训练时有一个很严重的问题:KL 会迅速降到0,后验失效了。原因在于,由于 RNN-based 的 decoder 有着非常强的 modeling power,直接导致即使依赖很少的 history 信息也可以让 reconstruction errors 降得很低,换句话说,decoder 不依赖 encoder 提供的这个 z 了,模型等同于退化成 RNNLM 。
     
    这篇 paper 提出的解决方法:KL cost annealing 和 Word dropout。
    1) KL cost annealing

           作者引入一个权重 w 来控制这个 KL 项,并让 w 从 0 开始随着训练逐渐慢慢增大。作者的意思是一开始让模型学会 encode 更多信息到 z 里,然后随着 w 增大再 smooth encodings。其实从工程/代码的角度看,因为 KL 这项更容易降低,模型会优先去优化 KL,于是 KL 很快就降成 0。但如果我们乘以一开始很小的 w,模型就会选择忽视 KL(这项整体很小不用降低了),选择优先去降低 reconstruction errors。当 w 慢慢增大,模型也慢慢开始关注降低 KL 这项了。这个技巧在调参中其实也非常实用。 KL项退火可以看作是从传统确定性自动编码器到完整VAE的逐步过渡。
    2) Word dropout

           既然问题是 RNN-based 的 decoder 能力太强,那我们就来弱化它好了。具体方法是把 input 的词替换成 UNK(我可能是个假的 decoder),模型被迫只能去多多依赖 z。当然保留多少 input 也需要尝试,我们把全都不保留的叫做inputless decoder,实验表明,inputless VAE 比起 inputless RNN language model 不知道好到哪里去了。
    受到 GAN 的启发,作者还提出了一个 Adversarial evaluation,用一半真一半假的数据作为样本训练出一个分类器,再对比不同模型生成的句子有多少能骗过这个分类器,这个 evaluation 被用在 Imputing missing words 这个任务上,VAE 的表现同样比 RNNLM 出色。
         最后,作者展示模型的确学到了平滑的 sentence representation。选取两个sentence 的code z1和z2,z1 和 z2 可以看做向量空间的两个点,这两个点连线之间的点对应的句子也都符合语法且 high-level 的信息也保持局部一致。
     
     
          与以前引入的文本 vae 模型相比, 编码器和解码器都是 rnn 的 vae 模型, 我们提出了一种新的混合体系结构, 将完全前馈卷积和去卷积组件与重复语言模型融合在一起。我们的体系结构具有几个有吸引力的特性, 如更快的运行时间和收敛性, 能够更好地处理长序列, 更重要的是, 它有助于避免在文本数据上训练 vae 模型所带来的一些主要困难。
          训练VAE模型的核心困难是潜在损失(以KL散度项表示)崩溃为零。 在这种情况下,生成器倾向于完全忽略潜在表示,而简化为标准语言模型。 这主要是由于基于RNN的解码器具有很高的建模能力,其历史记录非常短,可以在不依赖编码器提供的潜矢量的情况下实现较低的重构误差。
         在本文中,我们提出了一种新颖的文本VAE模型,该模型可以更有效地迫使解码器使用潜在矢量。与既有编码器层又有解码器层均为LSTM的现有工作相反,我们模型的核心是由一维卷积和反卷积层组成的前馈体系结构(Zeiler等,2010)。这种架构选择有助于更好地控制KL术语,这对于训练VAE模型至关重要。鉴于很难以完全前馈的方式生成长序列,我们在网络上增加了RNN语言模型层。据我们所知,本文是在自然文本的潜在变量生成模型的解码器中成功应用反卷积的第一篇论文。我们凭经验证明,与完全循环的替代方法相比,我们的模型更易于训练,而在我们的实验中,该方法无法收敛于较长的文本。为了更好地理解为什么很难为文本训练VAE,我们进行了详细的实验,讨论了优化难题,并提出了解决这些难题的有效方法。最后,我们证明从我们的模型中采样可以得出真实的文本。
     

          我们的模型由两个相对独立的模块组成。 第一个组件是标准VAE,其中编码器和解码器模块分别由卷积和反卷积层参数化(请参见图2(a))。 这种体系结构因其计算效率高和训练简单而具有吸引力。
            另一个组件是循环语言模型,它消耗来自与前一个输出字符连接的反卷积解码器的激活。我们考虑了两种递归函数:传统的LSTM网络(图2(b))和一堆屏蔽卷积,也被Kalchbrenner等人称为ByteNet解码器。 (2016)(图2(c))。在解码器中具有循环组件的主要原因是捕获文本序列元素之间的依赖性,这对于完全前馈架构而言是一项艰巨的任务。实际上,生成的句子的条件分布P(x | z)= P(x1,…,xn | z)不能用前馈网络来丰富地表示。 相反,它的大小为:

         其中组件彼此独立并且仅以z为条件。为了最小化重建成本,模型被迫对文本片段的每个细节进行编码。相反,循环语言模型对输出序列的完整联合分布进行建模,而不必进行独立性假设P(x1,…,xn | z)=

          因此,在我们的完全前馈编码器-解码器体系结构之上添加循环层,可以避免将文本片段的各个方面编码为潜在向量,并使其专注于更高级的语义和样式特征。
       
          我们发现以下启发式方法可以很好地起作用:首先运行KL权重固定为0的模型,以找到需要收敛的迭代次数。 然后,我们将退火时间表配置为在非正规模型收敛之后开始,并且持续时间不少于该数量的20%。

     
     
         现有的文本生成神经模型在解码阶段都依赖softmax层来选择合适的单词embedding。现在大多数方法都是在softmax层采取一个单词一一映射一个embedding的方式。然而,同样的单词在不同的上下文会有不同的语义。在本文作者提出了核化贝叶斯方法KerBS,他能够更好的学习文本生成中的embedding。KerBS的优势如下:它采用了embedding的贝叶斯组合来表征具有不同语义的单词;KerBS适用于解决一词多义带来的语义差异问题,并且通过核学习在embedding空间中捕捉语义的紧密程度,KerBS对极少出现的句子也能保持较高的鲁棒性。研究表明,KerBS显著提高几大文本生成任务的性能。
     
           本文提出了一种基于主题指导的VAE模型(topic-guided variational autoencoder, TGVAE),它不再是从标准高斯分布中进行采样,而是将每一个主题模块都看作是一个高斯混合模型,即每一个混合成分都表示了一个对应的latent topic。那么直接从中进行采样,decoder在 解码的过程中过程中就会利用到latent code所表示的主题信息。另外,作者还采用了Householder Transformation 操作,使得latent code的近似后验具有较高的灵活性。实验证明TGVAE在无条件文本生成和条件文本生成任务中都可以取得更好的效果,并且模型可以生成不同主题下语义更加丰富的句子。而且通过主题信息的指导,使得模型在文本生成阶段所依赖的词汇表变小,从而减少解码过程的计算量。

          本文利用multi-level structures 学习VAE模型以生成长文本。主要目的是利用长文本的高级抽象特征(如主题、情感等)和低级细粒度细节(如特定的词选择)来做长文本的生成。本文所做的改进:
    1.      1.在编码器和解码器之间采用了一个随机层结构来抽象出更多的语义丰富的隐含编码
    2.      2.利用一个多级解码器结构通过生成句子高层次的中间表示来捕获长文本中固有的长期结构

     
          现有的数据到文本生成的神经方法仍然难以生成长而多样的文本: 它们不足以在生成过程中对输入数据进行动态建模、捕捉句子间的连贯性或生成多样化的表达式 为了解决这些问题,我们提出了一种基于规划的层次变分模型(PHVM)。 我们的模型首先规划一个组序列 (每个组是一个句子所涵盖的输入项的子集) ,然后根据规划结果和前面生成的上下文实现每个句子,从而将长文本生成分解为依赖的句子生成子任务。 为了捕获表达的多样性,我们设计了一个层次潜结构,其中全局规划潜变量对合理规划的多样性进行建模,局部潜变量序列控制句子的实现。
        给定输入数据x = {d1, d2,…}其中每个di可以是一个属性-值对或一个关键字,我们的任务是生成一个长而多样的文本y = s1 s2…sT (sT是第t个句子)表示尽可能多地表示x。
    生成过程概述:   
       1.根据输入生成一组规划,g1,g2,..;gt是输入中的子项
        2.结合规划子项,输入编码,生成子句编码
        3.结合子项,子句编码进行子句的单词级生成,生成子句si
        4.根据时间步,结合上步隐层信息,重复1-3步,生成其余的子句si+1,si+2
        5.拼接所以子句si-N,形成最终的长句。
     
         Syntax-Infused VAE顾名思义就是结合了语法信息的VAE文本生成,结合输入文本的语法树,可以提升生成句子的语法信息。作者分别为句子和语法树生成了隐变量,并且重写了变分下界的目标函数,以此优化2者的联合分布。

    展开全文
  • 通过短文本生成图像

    千次阅读 2021-08-13 08:37:50
    人类可以在图像中构建知识。 每次我们看到一个想法或经验时,大脑都会立即对其进行视觉表示。... 最近来自微软的 AI 研究人员发表了一篇论文,提出了一种基于短文本生成图像的方法。 我们从声音或文字描述中产

    人类可以在图像中构建知识。 每次我们看到一个想法或经验时,大脑都会立即对其进行视觉表示。 同样,我们的大脑也在不断地在声音或纹理等感官信号与其视觉表现之间切换上下文。 我们在视觉表示中思考的能力还没有完全扩展到人工智能 (AI) 算法。大多数 AI 模型都高度专业化于一种数据表示形式,例如图像、文本或声音。 而我们研究的最终目的是将开始看到可以在不同数据格式之间有效转换以优化知识创造的人工智能形式。 最近来自微软的 AI 研究人员发表了一篇论文,提出了一种基于短文本生成图像的方法。

    我们从声音或文字描述中产生视觉表征的能力是人类认知的神奇元素之一。如果你被要求画一幅篮球比赛的图像,你可能会从三到四名球员的轮廓开始。即使没有直接指定,您也可以添加一些细节,如乌鸦、裁判或处于特定位置的球员。所有这些细节都丰富了基本的文本描述,以实现我们对篮球比赛的视觉版本。如果人工智能模型也能做到这一点,那不是很好吗?文本到图像(Text-to-Image, TTI)是深度学习的新兴学科之一,专注于从基本文本表示生成图像。虽然TTI领域还处于非常早期的阶段,但我们已经看到了一些切实的进展,一些模型已经在非常具体的场景中被证明是熟练的。然而,这些都是TTI模型中仍然需要解决的非常具体的挑战。

    从文本生成图像:挑战和注意事项

    有几个相关的挑战传统上阻碍了TTI模型的发展,但它们中的大多数可以归类为以下类别之一?

    1)挑战:TTI模型高度依赖文本和可视化分析技术,尽管近年来它们取得了很大进展,但要实现主流方法,仍有很多工作要做。从这个角度来看,TTI模型的功能通常会受到底层文本分析和图像生成模型的具体限制。

    2)概念-对象关系:TTI模型中难以解决的一个问题是从文本描述中提取的概念与其对应的可视对象之间的关系。实际上,可以有一个不定式数量的对象匹配一个特定的文本描述。确定概念和对象之间的正确匹配仍然是TTI模型的关键挑战。

    3)物物关系:任何图像都是以视觉的形式表达物体之间的关系。为了反映给定的叙述,TTI模型不仅要生成正确的对象,还要生成它们之间的关系。在文本到图像的生成技术中,生成包含多个具有语义意义的对象的更复杂的场景仍然是一个重大的挑战。

    Object-Driven Attentive GAN

    为了解决TTI模型的一些传统挑战,微软研究院依赖于日益流行的生成对抗网络(gan)技术。gan通常由两种机器学习模型组成——一个生成器从文本描述生成图像,另一个判别器使用文本描述判断生成图像的真实性。生成器试图让假照片通过鉴别器;另一方面,辨别器不希望被愚弄。通过共同努力,鉴别器将生成器推向完美。微软在传统的GAN模型上进行了创新,引入了自下而上的注意力机制。Obj-GAN模型开发了一个对象驱动的注意力生成器和一个面向对象的识别器,使gan能够合成复杂场景的高质量图像。

    Obj-GAN的核心架构通过两个步骤进行TTI合成:

    1)生成语义布局:这个阶段包括生成类标签、包围框、突出物体的形状等元素。这个功能由两个主要组件完成:Box Generator和Shape Generator。

    2)生成最终图像:这个功能是由一个多级图像生成器和一个鉴别器完成的。

    下图提供了Obj-GAN模型的高级架构。该模型接收一个带有一组标记的句子作为输入,然后将其编码为单词向量。在此之后,输入经过三个主要阶段进行处理:框生成、形状生成和图像生成。

    Obj-GAN模型的第一步以句子为输入,生成语义布局,即由其边界框指定的对象序列。模型的边框生成器负责生成一个包围边框序列,然后由形状生成器使用。给定一组边界框作为输入,形状生成器预测相应框中每个对象的形状。由形状生成器产生的形状被图像生成器GAN模型使用。

    Obj-GAN包括一个基于两个主生成器的多级图像生成神经网络。基生成器首先根据全局句子向量和预先生成的语义布局生成低分辨率图像。第二个生成器通过关注最相关的单词和预生成的类标签来细化不同区域的细节,并生成更高的分辨率。

    到目前为止,您可能想知道架构的对抗性组件在哪里发挥作用?这就是对象鉴别器的作用。该组件的作用是充当训练图像生成器的对手。Obj-GAN模型包括两个主要鉴别器:

    ·Patch-Wise Discriminator:这个Discriminator用于训练盒子和形状生成器。第一个鉴别器尝试评估生成的边界框是否与给定的句子相对应,而第二个鉴别器做同样的工作来评估边界框与形状之间的对应关系。

    ·object - wise Discriminator:该Discriminator使用一组边界框和对象标签作为输入,并尝试确定生成的图像是否与原始描述相对应。

    对抗式生成器-鉴别器组合用于边框、形状和图像的生成,使Obj-GAN优于其他传统TTI方法。微软对Obj-GAN与最先进的TTI模型进行了评估,结果非常显著。只要看看生成的图像的质量和它们与原始句子的对应关系就知道了。

    创建给定叙述的视觉表示的能力将是下一代文本和图像分析深度学习模型的一个重要重点。Obj-GAN等理念无疑为这一深度学习领域带来了相关创新。

    微软论文地址:

    https://www.microsoft.com/en-us/research/publication/object-driven-text-to-image-synthesis-via-adversarial-training/

    本文作者:Jesus Rodriguez

    展开全文
  • 针对有监督的深度神经网络文本生成模型容易造成错误累积的问题,提出一种基于强化对抗思想训练的文本生成模型。通过将生成对抗网络鉴别器作为强化学习的奖励函数及时指导生成模型优化,尽量避免错误累积;通过在生成...
  • 文本生成任务常见评估指标

    千次阅读 2019-05-16 15:40:55
        在传统的文本生成任务中,对于模型生成的文本,往往很难评估他们的质量,一般会采用人工投票的形式,来比较生成的文本和真实的参考文本之间的优劣或接近程度,因此,其评估过程是非常昂贵和耗时的,并且该...
  • 来自:贝壳智搜 本文章对文本生成领域一些常见的模型进行了梳理和介绍。Seq2Seq 是一个经典的文本生成框架,其中的Encoder-Decoder思想贯彻文本生成领域的整个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,009,154
精华内容 403,661
关键字:

文本生成