我介绍了一些使用的初步工作 生成对抗网络学习文档的分布式表示 在最近的 NIPS关于对抗训练的讲习班 .在这篇文章中,我简要概述了这篇论文,并浏览了其中的一些代码。

学习文档表示

近年来,表示学习一直是一个热门话题,部分原因是人们希望将深度学习模型在监督任务方面的令人印象深刻的结果应用到无监督学习和迁移学习领域。一般来说,表示学习有各种各样的方法,但基本思想是从数据中学习一些特征集,然后将这些特征用于可能只有少量标记示例的其他任务(如分类)。这些特征通常是通过尝试预测底层数据分布的各种属性来学习的,或者通过使用数据来解决一个独立的(可能不相关的)任务,我们确实有大量的标记示例。这种做到这一点的能力是可取的,原因有几个。在许多领域中,可能有大量的未标记数据可供我们使用,而有监督的数据很难和/或获取成本很高。有些人还认为,我们永远不可能使用纯监督学习来构建更普遍的智能机器(这个观点由现在臭名昭著的勒存蛋糕滑).单词(和字符)嵌入 已经成为用于自然语言处理的深度学习模型的标准组成部分,但关于如何学习句子或整个文档的表示,人们还没有达成共识。从文献中学习非监督文档表示的最成熟的技术之一是 潜在狄利克雷分配 (LDA)。后来,在小型新闻语料库上进行评估时,对文档建模的神经方法已被证明优于LDA(下面将讨论)。第一个是 复制Softmax ,它是基于受限玻尔兹曼机的,后来它也被一个神经自回归模型超越,叫做 DocNADE 除了像NADE家族这样的自回归模型,目前还有另外两种构建生成模型的流行方法——变分自编码器和 生成对抗的网络 (甘斯)。这项工作是一个早期的探索,看看GANs是否可以用于学习在无监督环境下的文档表示。

基于生成对抗网络的文档建模

在最初的GAN设置中,a发电机网络学会将样本从(通常是低维)噪声分布映射到数据空间,第二个网络称为鉴频器学会区分真实的数据样本和虚假生成的样本。生成器被训练来欺骗鉴别器,其预期目标是这样一种状态:生成器已经学会了创建代表底层数据分布的样本,而鉴别器不确定它看到的是真实的样本还是假的样本。如果我们想使用这种技术来建模文档,有几个问题需要解决:
  • 在Aylien,我们主要感兴趣的是将学到的表示用于新任务,而不是做某种文本生成。因此,我们需要某种方法从文档映射到潜在空间。这种GAN方法的一个缺点是没有明确的方法来做到这一点——您不能从数据空间返回到低维潜在空间。那么我们的表示是什么?
  • 由于这要求两个步骤都是端到端可微的,那么我们如何表示离散符号的集合呢?
要回答第一个问题,对标准GAN模型的一些扩展训练额外的神经网络来执行映射(就像 而且 ).另一个更简单的想法是使用鉴别器的一些内部部分作为表示(就像在 DCGAN 纸)。我们对两种方法都进行了试验,但到目前为止,使用后者获得了更好的结果。具体来说,我们使用的是 能源甘 模型中,我们的鉴别器是去噪的自动编码器,并使用自动编码器瓶颈作为我们的表示(参见 更多的细节)。至于表示离散符号,我们采取了最过分简化的方法——假设文档只是单词包的二进制向量(即,如果文档中出现了固定词汇表中的某个给定单词,则该向量为1,否则为0)。尽管这实际上仍然是一个离散向量,但我们现在可以将它视为所有元素在[0,1]范围内连续并反向传播整个网络。完整的模型是这样的:adm-large在这里z是通过发电机网络的噪声矢量吗G并产生一个向量,这是词汇表的大小。然后传递这个生成的向量或从数据中采样的单词袋向量(x)到去噪自动编码器鉴别器D.然后用遮蔽噪声破坏矢量C,由编码器映射到低维空间,再由解码器映射回数据空间,最后将损失作为输入到之间的均方误差D和重建。我们还可以提取编码的表示(h),以连结任何输入文件。

TensorFlow代码的概述

这个模型的完整源代码可以在这里找到 https://github.com/AYLIEN/adversarial-document-model ,这里只强调一些更重要的部分。 在TensorFlow中,生成器被写成:
Def生成器(z, size, output_size): h0 = tf.nn.relu(slim。Batch_norm (linear(z, size, 'h0'))Batch_norm (linear(h0, size, 'h1'))返回tf.nn。output_size乙状结肠(线性(h1, h2))
这个函数接受包含噪声向量的参数 z ,生成器隐藏维度的大小和最终输出维度的大小。然后将噪声向量通过两个完全连接的RELU层(带有批处理范数),然后将输出通过最终的sigmoid层。鉴别器同样很简单:
Def鉴别器(x, mask, size): noisy_input = x * mask h0 = leaky_relu(linear(noisy_input, size, 'h0')) h1 = linear(h0, x.get_shape()[1], 'h1') diff = x - h1返回tf.reduce_mean(tf. size, size):Reduce_sum (diff * diff, 1)), h0
它取一个向量 x ,一个噪声向量 面具 以及自动编码器瓶颈的大小。在噪声通过单个泄漏的RELU层并线性映射回输入空间之前,噪声被应用到输入向量上。它返回重构损耗和瓶颈张量。 完整模型为:
与tf.variable_scope(“发电机”):自我。Generator = Generator (z, params.)G_dim, params.vocab_size)与tf.variable_scope('discriminator'): self。d_loss,自我。Rep = discriminator(x, mask, params.z_dim) with tf。variable_scope(鉴别器,重用= True):自我。G_loss, _ = discriminator(self。发电机,面具,params.z_dim) margin = params.vocab_size // 20 self.d_loss += tf.maximum(0.0, margin - self.g_loss) vars = tf.trainable_variables() self.d_params = [v for v in vars if v.name.startswith('discriminator')] self.g_params = [v for v in vars if v.name.startswith('generator')] step = tf.Variable(0, trainable=False) self.d_opt = tf.train.AdamOptimizer( learning_rate=params.learning_rate, beta1=0.5 ) self.g_opt = tf.train.AdamOptimizer( learning_rate=params.learning_rate, beta1=0.5 )
我们首先创建生成器,然后创建鉴别器网络的两个副本(一个将实际样本作为输入,另一个将生成的样本作为输入)。然后,我们通过添加来自生成样本的成本(具有能量裕量)来完成鉴别器损失,并为鉴别器和生成器网络创建单独的亚当优化器。神奇的亚当 beta1 的价值 0.5 来自于 DCGAN 论文,并且似乎在我们的模型中稳定训练。 然后可以对这个模型进行如下训练:
Def更新(model, x, opt, loss, params, session): z = np.random。正常(0 1(参数。Batch_size, params.z_dim)) mask = np.ones((params. z_dim))Batch_size, params.vocab_size))(选择2,参数个数。vocab_size, p =[参数。噪声,1.0 -参数。)丢失,_ = session.run([loss, opt], feed_dict={模型。x: x,模型。z: z,模型。面具: mask }) return loss # … TF training/session boilerplate … for step in range(params.num_steps + 1): _, x = next(training_data) # update discriminator d_losses.append(update( model, x, model.d_opt, model.d_loss, params, session )) # update generator g_losses.append(update( model, x, model.g_opt, model.g_loss, params, session ))
在这里我们得到下一批训练数据,然后分别更新鉴别器和生成器。在每次更新时,我们生成一个传递给生成器的新噪声向量,以及一个用于去噪自动编码器的新噪声掩码(相同的噪声掩码用于批处理中的每个输入)。

实验

为了与之前在这一领域发表的工作(LDA, Replicated Softmax, DocNADE)进行比较,我们用这个对抗模型在 20新闻组 数据集。必须强调的是,按照目前的标准,这是一个相对简单的数据集,由20个不同新闻组的约19000个帖子组成。 生成模型(特别是GANs)的一个开放问题是,您实际使用什么指标来评估它们的表现?如果模型在输入上产生适当的联合概率,一个流行的选择是评估hold out测试集的可能性。不幸的是,这不是GAN模型的选项。 相反,因为我们只对学习过的表示的有用性感兴趣,所以我们也会遵循以前的工作,比较相似的文档在向量空间中具有相近表示的可能性。具体来说,我们为数据集中的每个文档创建向量。然后,我们使用保留测试集向量作为“查询”,对于每个查询,我们找到最接近的查询 N 训练集中的文档(按余弦相似度计算)。然后,我们测量这些检索到的训练文档具有与查询文档相同新闻组标签的百分比。的不同值,我们绘制了检索性能的曲线 N .结果如下所示。 20 ng_results

20新闻组数据集上文档检索任务的精度-召回曲线。ADM是对抗文档模型,ADM (AE)是使用标准自动编码器作为鉴别器的对抗文档模型(因此它类似于基于能量的GAN), DAE是去噪自动编码器。

在这里我们可以看到一些值得注意的要点:
  • 该模型确实学习了有用的表示,但在此任务中仍达不到DocNADE的性能。在较低的回忆值,尽管它比LDA的结果在相同的任务(没有显示在上面,见复制Softmax纸).
  • 通过使用去噪自动编码器作为鉴别器,与仅使用标准自动编码器相比,我们得到了一点提升。
  • 我们得到了相当大的改进,而不仅仅是训练一个去噪自动编码器与该数据集的类似参数。
我们还观察了模型是否产生了容易解释的结果。我们注意到,自动编码器瓶颈有将其连接到词汇表中的每个单词的权重,因此我们查看特定的隐藏单元是否与可以解释为新闻组主题的单词组强烈连接。有趣的是,我们在下表中发现了一些证据,其中我们列出了与三个隐藏单位最密切相关的单词。它们通常属于可理解的主题类别,只有少数例外。然而,我们注意到这些都是精心挑选的例子,而且总体而言,特定隐藏单元的权重并不倾向于与单个主题紧密相关。
计算 体育 宗教
窗户 曲棍球 基督徒
个人电脑 季节 窗户
调制解调器 球员 无神论者
scsi 棒球 韦科
正方形的 游骑兵队 batf
软盘 勇士 基督
xlib 树叶
vga 出售 参数
xterm 手枪 自行车
航运 自行车 游骑兵队

我们还可以在测试集向量的TSNE图(每个主题一种颜色)中看到许多主题的合理聚类,尽管有些显然仍然被混淆:

20 ng_tsne

结论

我们展示了使用GANs对文档建模的一些有趣的第一步,不可否认,可能提出的问题比我们回答的要多。自从这项工作完成以来,已经有许多改进GAN培训的建议(如而且),所以看看最近的进展是否有助于完成这项任务会很有趣。当然,我们仍然需要看看这种方法是否可以扩展到更大的数据集和词汇表。完整的源代码现在可以在Github我们期待看到人们用它做什么。

文本分析API -注册

消息灵通

我们会不时地通过电子邮件与您联系我们的产品和服务。