创作能手——LSTM“诗人”

寸先生的AI道路 2018-01-25

摘要: 本文作者介绍了她的一个小实验:创建一个会写诗歌的LSTM网络。

代码是诗歌,这是WordPress的哲学的一部分,作为一名程序猿和一位诗人的我一直喜欢这句话。我一直有一个疑问:可以做一个可以写出原创诗歌的机器人吗?

带着这个疑问我一直思考,我知道如果我的机器人学习写诗,首先必须先会读诗。在2017年,有人使用WordPress发布了超过五十万个标签为诗歌的帖子。我向一些多产的诗人询问,问他们是否愿意和我一起进行有趣的实验:他们是否允许我的机器人阅读他们的作品,以便学习诗歌的形式和结构,以至于学会写自己的诗歌?特别感谢这些为科学而合作的勇敢的作家们!

什么是LSTM,它是如何生成文本的?

我在实验中使用了一种称为LSTM或长短期记忆网络的神经网络来构建我的机器人。

神经网络通过使用图层将问题分解成一系列较小的问题:例如,假设你正在训练一个神经网络来识别一个正方形。一层可能负责识别直角,另一层可能识别平行线,这些特征都必须存在才能使图像成为正方形。神经网络通过训练数以百万计的正方形图像来学习所需的特征。

现在假设你正在使用一个神经网络来预测这个序列中的下一个字母:

th_

对于一个人来说,这个任务是非常简单的,你会猜e。如果你是一个说英文的人,你不会猜测是q,那是因为你已经学会了它后面没有q存在的情况。LSTM可以“记住”以前的状态来通知其当前的决定。

像许多LSTM文本生成示例一样,我的机器人也是一次生成一个字符来生成文本。所以要想以任何有意义的方式把话汇集起来,首先要学会如何说话。为了实现这一点,它需要数百万个包含有效单词的示例序列。WordPress.com有我们需要的材料。

准备数据集

我从Elasticsearch索引中抽出了上面列出的所有诗歌。根据每个字符的字数,我用一个非常简单的规则去除了诗歌的所有内容。如果一个文本块包含许多单词,但很少字符,这可能是一个或多个段落的集合。然而,一段文字与文字散布在许多行中更可能是一首诗。为了达到这个实验的目的,我特别感兴趣的是LSTM是否可以学习结构,如断行和节,以及其他诗歌装置,如押韵,声调,和声和合并。所以,把训练数据限制在比较结构化的诗里是有道理的。

一旦一段文字被确定为一首诗,我就把它写到一个文本文件中,并在其前加上一个字++++来表示一首新诗的开始。通过这种方式,我得到了大约500KB的训练数据。通常我会尝试用至少1MB的文字来训练LSTM,所以我需要找到更多的诗歌!

训练LSTM网络

找到足够的数据集后,我开始建立一个LSTM网络。我使用Python库keras来满足我所有的神经网络需求,而keras的GitHub库有几十个示例脚本来帮助你学习使用几种不同类型的神经网络,包括使用LSTM的文本生成。在此示例之后,我运行了我的代码,并开始尝试不同的模型配置。这个模式的目标是制作原创诗歌。在这种情况下,过度拟合可能导致生成与输入文本非常相似的文本。(这就像剽窃,没有诗人喜欢!)防止过度拟合的一种方法是添加丢失到你的网络。这迫使每个步骤的权重的随机子集降到零。这就像是迫使网络“忘记”一些刚刚学到的东西。

我使用FloydHub的GPU来训练我的网络,这使我能够像使用笔记本电脑一样快速地训练网络。我的第一个网络有一个LSTM层,后面是一个dropout层。它有断行和节,几乎所有的字符组合都是真正的单词。事实上,第一次迭代产生了这个:

创作能手——LSTM“诗人”

我添加了LSTM层,试验每个图层中的dropout级别,直到确定使用下面的最终模型。我选择在三个LSTM层,因为在这一点上训练时间开始变得不合理,但结果相当不错。

model = Sequential()model.add(LSTM(300, input_shape=(maxlen, len(chars)), return_sequences=True, dropout=.20, recurrent_dropout=.20))model.add(LSTM(300, return_sequences=True, dropout=.20, recurrent_dropout=.20))model.add(LSTM(300, dropout=.20, recurrent_dropout=.20))model.add(Dropout(.20))model.add(Dense(len(chars)))model.add(Activation('softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam')

这是一个模型之间比较后得到的损失曲线:

创作能手——LSTM“诗人”

事实证明,使用adam优化器时,这种情况非常普遍。请注意,当我将LSTM层添加到网络中时,模型的验证损失总体上继续下降,速度也更快。这意味着在更短的时期内可以获得可行的结果,但是额外的层次增加了每个时期的训练时间。一个LSTM层训练每个epoch大约需要600秒,然而,三层LSTM每个epoch需要7000秒,需要几天才能完成训练。所以,验证丢失速度的下降实际上并不意味着更快的结果。尽管训练花费的时间较长,但我完全主观认为,三层LSTM网络所产生的诗歌更好。

生成诗歌

为了产生完整的原始文本,我还需要改变文本的生成方式。在keras库中,脚本从训练数据中选择一个随机的字符序列作为训练网络的输入。我从开始在训练集中的每首诗都用++++区分,我认为这足以创造出完整的原始输出。但结果是荒谬的组合,_,.,和&。经过一些试验和错误之后,我发现种子序列需要与训练序列具有相同数量的字符。最终,我使用了300个字符的序列,所以我通过重复++++ 刚好300个字符来生成一代。

产生新一轮诗歌后,我进行了最后的抄袭检查。为此,我首先在训练集中创建了所有独特的4-gram(包含4个词的短语)的集合,并且为我的机器人诗歌创作了同样的东西,然后我计算了这两个集合的交集。通常情况下,这个交集包含如下内容:

·i don’t want

·i can not be

·i want to be

·the sound of the

诗歌!

每个输出模型权重意味着我们可以在训练期间的几个点上加载模型。在设计上,训练数据最显着的特征是每行几个字符,下面是一个训练结束后生成的诗歌的例子:

The pare of frowning the wand the sallt a merien.

You will we mece wore and and the bite.

in is what to call stor the mathing all your bray.

它已经学到了一些使用的词语,模仿了每一行之间空白空间的惯例。从远处看,那看起来像是一首诗!在单个LSTM模型的损失收敛之后,模型学习了节和线断。

The and the beautiful specting

The flight of how the way

I am the room of the words.

I have seen to see

But your heart will see the face

除了标题行之外,我最喜欢的另一个是:

the wind is only for me

而单一的LSTM模型在一首诗中并没有很好地掌握主题,而在它所产生的全部工作中似乎都有一个共同的线索。这是由单一LSTM模型生成的所有诗歌的词云:

创作能手——LSTM“诗人”

如果sun是训练数据中最普遍的词汇,这并不令人惊讶,但事实并非如此!这是一个由训练数据生成的文字云:

创作能手——LSTM“诗人”

艾米莉·狄金森(Emily Dickinson)写了关于自然和死亡的诗歌,而我的机器人写关于天体的诗:

Seen will be found

Mere seeds smiles

I red my the day

the day of the way

the kind be the end

添加第二个LSTM层后,我们开始看到其他诗歌特征,如头韵和韵律。

它也开始产生一些非常有诗意的短语。例如:

there’s a part of the world.

between the darkness.

the shadows stay the day.

到目前为止,我们已经看到了节,韵(内部和行结尾),重复和头韵。但是,偶尔有戏剧性的天赋,这个机器人在这个时候产生的诗歌通常是不连贯的词汇集。它的废话绝大部分都没有语法结构。

然而,这开始改变,增加了第三个LSTM层。这种模式更有可能产生语法上合理的线条,即使仍然是荒谬的。例如:

The father of the light is not a fist of the bones

这个句子没有意义,但是正确地放置了词性。它也具有一致性,并且对名词从句具有一般的诗意。

创作能手——LSTM“诗人”

但三层LSTM模式的最高成就就是这首完整的诗:

From your heart of the darkness

I stay

and struggle on the soul

本文由阿里云云栖社区组织翻译。

文章原标题:《to-a-poem-is-a-bott-the-stranger》,

作者:卡莉Stambaugh 数据科学家

译者:虎说八道,审阅。

相关推荐