生成模型 用自己的风格教AI说话 语言生成模型可以这样学

生成模型 用自己的风格教AI说话 语言生成模型可以这样学

国内新闻2021-09-27 13:42:36

选自towardsdatascience

机器心脏编译

参与:熊猫

许多研究人员和开发人员认为学习神经网络的最好方法是自己训练一个模型。机器心也推荐了很多不同开发者写的动手教程。这篇文章也是其中之一。数据科学家马介绍了如何利用自己的博文训练出一个与自己风格相同的简单语言生成模型。

在过去的几个月里,我在个人博客上写了100多篇文章。数量依然可观。然后我有了一个想法:

培养一个和我说话方式相似的语言生成模型。

更确切地说,是像我这样写的。这种方式可以完美地解释语言生成的主要概念、使用Keras的实现以及我的模型的局限性。

本文的完整代码可以在以下代码库中找到:

https://github.com/maelfabien/Machine_Learning_Tutorials

在开始之前,我推荐一个我发现的有用的Kaggle Kernel资源,可以帮助我们理解语言生成算法的结构:https://www。ka ggle . com/Shivamb/初学者-文本生成指南-使用-lstms

语言生成

自然语言生成是一个旨在生成有意义的自然语言的领域。

在大多数情况下,内容是以单个单词序列的形式生成的。这是一个非常宽泛的想法,一般的工作方法如下:

训练一个模型来预测序列中的下一个单词

为训练好的模型提供输入

迭代n次,生成下n个单词

序列预测过程

1.创建数据集

第一步是建立一个数据集,这样我们以后就可以基于它建立一个网络,所以这个数据集需要构建成一个网络可以理解的形式。首先导入以下包:

A.加载数据

我写的每篇文章的标题都使用了以下模板:

这是我们通常不希望出现在最终数据集中的内容。我们要关注的是文本本身。

每篇文章都是一个单独的标记文件。文件头基本包含标题、标题图片等信息。

B.象征句

然后,打开每篇文章,将每篇文章的内容附在一个列表中。但是,因为我们的目标是生成句子,而不是整篇文章,所以我们需要将每篇文章分成一个句子列表,并将每个句子附加到列表“all _句子”中。

总的来说,我们得到了6800多个训练句子。迄今为止的过程如下:

句子分段

C.创建n-gram

然后,创建一起出现的n-gram单词。为了实现这一目标,我们需要:

使用语料库上的标记化程序,每个标记都与一个索引相关联

语料库中的每个句子都被分解成一个标记序列

保存一起出现的令牌序列

下图显示了这一过程:

创建一个氮克

让我们实现它。我们首先需要令牌使用令牌化程序:

变量total_words包含使用的不同单词的总数。这是8976。然后,对于每个句子,获取相应的标记并生成n-gram:

token_list变量包含令牌序列形式的句子:

然后,n_gram_sequences创建一个n-gram。它从前两个单词开始,然后逐渐添加单词:

D.填充物

现在我们面临这样一个问题:不是所有的序列都是一样长的!如何才能解决这个问题?

我们将使用填充。填充是在变量input _ series的每一行前加上0形成的序列,这样每一行的长度就和最长的一行一样了。

填充的图形表示

为了将所有句子都填充到一个句子的最大长度,我们必须首先找到最长的句子:

在我的例子中,最大序列长度是792。嗯,单就一句话来说,这句话真的挺长的!因为我的博客里有一些代码和教程,我猜这句话其实是Python代码。让我们画一个序列长度的直方图来看看:

序列长度

的确,只有极少数样本的单个序列超过200个单词。把最大序列长度设为200怎么样?

这将返回如下结果:

E.划分x和y

现在我们有了固定长度的数组,其中大部分在实际序列之前用零填充。那么,我们如何把它变成一个训练集呢?我们需要分开x和y!记住,我们的目标是预测序列中的下一个单词。因此,我们必须将除最新令牌之外的所有令牌视为x,并将该最新令牌视为Y..

拆分x和y

用Python做这件事非常简单:

现在我们可以把这个问题看作一个多类分类任务。首先,我们必须对Y进行一热编码,得到一个稀疏矩阵,该矩阵在对应于令牌的一列中包含1,在其他地方包含0。

在Python中,使用Keras Utils的to _ category:

y = ku . to _ classic

现在,x的形状是,y的形状是。

现在我们有大约165000个训练样本。x的列宽是199,因为它对应于我们允许的最长序列长度。y有8976列,对应于词汇表中所有单词的稀疏矩阵。现在,数据集准备好了!

2.建立模型

我们将使用长期和短期记忆网络。LSTM有一个重要的优势,那就是它能理解对整个序列的依赖,所以一个句子的开头可能会影响到第15个要预测的词。另一方面,循环神经网络只涉及对网络前一状态的依赖,只有前一个词才有助于预测下一个词。如果我们选择RNN,我们将很快失去背景,所以选择LSTM似乎是正确的。

A.模型架构

因为培训需要非常非常非常长的时间,所以我们创建了一个简单的“1个嵌入式层+1个LSTM层+1个密集层”网络:

首先,我们添加一个嵌入层。我们把它转移到一个有100个神经元的LSTM,加上一个辍学生来控制神经元的共适应,最后加上一个密集层来完成。请注意,我们只在最后一层应用一个softmax激活函数,以获得输出属于每个类别的概率。这里使用的损失是类交叉熵,因为它是一个多类分类问题。

下面总结了模型的情况:

模型情况概述

B.培训模式

现在我们终于准备好训练模型了!

然后模型的训练开始了:

在一个CPU上,单个纪元大约需要8分钟。在GPU上,你应该修改Keras LSTM网络,因为它不能在GPU上使用。你需要的是这个:

经过几个训练步骤后,我会停下来对预测结果进行采样,并根据交叉熵的不同值来控制模型的质量。

以下是我观察到的结果:

3.生成句子

看完这个,下一步可以期待了:生成新句子!为了生成新的句子,我们需要对输入文本应用相同的转换。我们构建一个循环来迭代生成下一个单词一定次数:

当损失约为3.1时,使用“Google”作为输入生成以下句子:

谷歌是世界范围内产生的大量数据

这并不意味着什么,但它成功地将谷歌与海量数据的概念联系了起来。这是值得注意的,因为它只依赖于单词的共现,而不整合任何语法概念。

如果模型的训练时间更长,损失减少到2.5,给定输入“Random Forest”,您将得到:

Random Forest是一个完全托管的分布式服务,旨在支持大量初创公司的视觉基础设施

同样,生成的东西是没有意义的,但它的语法结构是相当正确的。

损失在大约50个纪元后收敛,从未低于2.5。

我认为这是由于这里开发的方法的局限性:

模型仍然非常简单

训练数据并不像它应该的那样整洁

数据量非常有限

话虽如此,我认为结果相当有趣,例如,训练好的模型可以很容易地部署到Flask WebApp中。

摘要

希望这篇文章有用。我试图解释语言生成的主要概念、问题和局限性。与本文讨论的方法相比,更大的网络和更好的数据肯定有助于提高结果。

这篇文章是为机器的心脏编写的。请联系本微信官方账号进行授权。

-

点击展开全文

Copyright @ 2011-2020 达卡新闻网 All Rights Reserved. 版权所有 备案号:京ICP备123412341号-1