教你用机器学习生成披头士的歌词

点击上方关注,All in AI 中国

教你用机器学习生成披头士的歌词

披头士是一个巨大的文化现象。他们永恒的音乐至今仍与人们产生共鸣,无论是年轻人还是老年人。就我个人而言,我是他们的超级粉丝。依我拙见,他们是很棒的摇滚乐队。他们的歌曲充满了有趣的歌词和深刻的思想。例如:

教你用机器学习生成披头士的歌词

然而,披头士乐队之所以伟大,是因为他们多才多艺。他们的一些歌曲深沉而有思想,而另一些则有趣而轻松。毫无疑问,贯穿他们歌词的最大主题是爱。这里有这样一句词:

教你用机器学习生成披头士的歌词

事实上,这些歌词并不是你所知道的披头士写的。不是约翰·列侬、 保罗·麦卡特尼、乔治·哈里森、甚至也不是林戈·斯塔尔。它们实际上是由机器学习模型生成的,即OpenAI的GPT-2。尽管这使用了他们最小的模型,结果却相当惊人。

但在我们过于超前之前,让我们后退一步,看看这一切是如何运作的。和往常一样,我的Github上有完整的可用代码。GitHub - EugenHotaj/beatles: Automatic Beatles lyrics generation.

语言建模

语言模型试图学习语言的结构(例如英语或披头士的歌词)。它们是使用监督学习训练的生成模型。与其他监督学习任务一样,语言模型试图预测给定某些特征的标签。然而,与大多数有监督的学习任务不同,它没有明确的标签,而是语言本身就具有一定的特征和标签。

在更高的层次上,语言模型所要做的是根据前面的单词序列预测下一个单词。例如,一个好的语言模型可以预测"milk"是"to buy a gallon of ____."这一短语的逻辑结论。

通过猜测下一个出现的单词,我们真正要做的是学习一个基于我们目前所见词语的词汇概率分布。也就是说,我们想要学习

教你用机器学习生成披头士的歌词

其中w_i是我们词汇表中的单词。

因为我们明确地为这个分布建模,我们可以用它做一些很酷的事情,比如用它生成我们以前没有见过的单词。我们可以做到这一点的方法是从这个分布中反复采样下一个单词,然后当我们采样下一个单词时,用它作为条件,以此类推。为了让它更加具体,让我们看看这在Python中可能是什么样子。如果我们有一个带有样本方法的模型对象,那么我们可以通过这样做来生成新的样本:

教你用机器学习生成披头士的歌词

如何从语言模型中生成句子。

当然,我跳过了一些细节,但希望随着时间的推移,这些会变得更加清晰。现在,让我们看一下世界上最简单的语言模型unigram。

unigram模型忽略任何条件,只是从训练数据中随机选择一个单词。这相当于把我们的训练数据扔进搅拌机,搅拌10分钟后就把里面的内容倒出来。有人说,我们不会创造出任何类似英语的东西(当然,除非我们有足够的机会和条件)。「链接」

Bigram模型

在一元模型之上的一个步骤是二元模型。正如你可能从名称中猜到的那样,bigram模型学习的分布仅受前一个单词的限制,即

教你用机器学习生成披头士的歌词

由于bigram模型非常简单,所以很容易在Python中实现,这将使我们更深入地理解语言模型的工作原理。

收集数据

在开始实现之前,我们首先需要一些数据。我们的最终目标是创作出让披头士引以为豪的歌曲,所以让我们从收集他们所有已知的歌词开始。

我发现这个网站收录了他们曾经发行的每首歌的歌词。它还有一个有用的索引页,其中有指向各个歌曲的链接,我们可以用它来抓取网站。我编写了一个简单的脚本来方便浏览歌曲,解析其HTML以提取歌词,并将歌词转储到一个文件中,每行一首歌曲。如果你打算跟着做,或者你自己只想要披头士的歌词,我强烈建议你使用它,因为抓取HTML是非常繁琐的,即使使用像Beautiful Soup这样的工具。

一旦我们有了一个漂亮的、干净的格式的数据,剩下的就很简单了。但不要只相信我的话,从这张图表中可以看出:

教你用机器学习生成披头士的歌词

数据清理和组织占了数据科学项目的最大一块。

建筑模型

如上所述,bigram模型只是根据前一个单词对下一个单词进行采样。我们可以做到这一点的一个简单方法是跟踪当前单词后面的单词,以及它们的出现频率。也就是说,我们在训练数据中为每个单词current_word保存一个字典,然后每次看到一个next_word,我们就更新current_word[next_word] += 1。然后,为了生成单词,我们只需在current_word字典中查找所有单词和计数,并对一个与计数成正比的单词进行采样。 这是一个完整模型在Python中的样子:

教你用机器学习生成披头士的歌词

bigram语言模型的草图。

最后要注意的是,我们可能想通过添加一些特殊的标记来对歌词进行预处理,以表示行和歌曲的开始/结束。这是为了迫使我们的模型在生成新歌词时维护一些歌曲结构,否则模型只会吐出大量没有结尾的文本。在我的代码中,我使用XXSL、XXEL、XXSS和XXES分别表示起始行,结束行,开始歌曲和结束歌曲。

最后,要生成歌曲,我们可以从XXSS令牌开始,并一直调用model.predict(),直到遇到XXES令牌为止。

教你用机器学习生成披头士的歌词

使用bigram模型生成一首歌。

从理论上讲,一旦循环停止,我们将产生一首从未见过的披头士歌曲。但这有什么好处吗?

一首前所未有的披头士的歌曲

下面是bigram模型生成的歌曲的一小段:

教你用机器学习生成披头士的歌词

生成的样本似乎不是很契合实际,但只有感同身受的人才觉得有意义。

我们可以继续扩展bigram模型来考虑前面两个单词。这就是所谓的 trigram模型。你可能会发现, trigram模型实际上可以产生更好的歌词。这是因为三个单词组合较少,因此模型在每个步骤中的选择较少,而在某些步骤中它只有一个选择。通常,我们可以通过考虑前面的n个单词来创建一个任意的n-gram模型。当n等于整首歌的长度时,你可能会发现这个模型在生成披头士的歌曲方面是完美的。不幸的是,它生成的歌曲已经存在。

走向更好的模式

bigram模型最突出的问题之一是,它只使用在训练数据中看到的单词和短语。虽然我们想要创作出听起来像披头士乐队写的歌词,但我们不想只局限于他们使用的词。例如,如果披头士从未使用过单词"parade",那么bigram模型将不会生成任何关于"parade"的歌曲。当然,由于我们只是在训练披头士的歌词,我们不可能指望我们的模型使用从未见过的单词。我们需要的是对大量的语料库进行训练,比如维基百科或Reddit。

然而,即使我们对所有的维基百科都进行了训练,并且看到了英语中的每一个单词,我们的bigram模型仍然过于死板。例如,以短语"高个的男人"为例。每个对英语有基本了解的人都会认识到,"tall"只是"man"的修饰语,与之无关。相反,"tall"可以用来修饰无数的其他事物,比如"woman"、"boy"、"building"、"giraffe"等等。然而,我们的bigram模型不能学习这个,它必须在使用"tall"之前至少看到一次"tall"的用法。所以如果模型只看到过"高个男人"、"高个男孩"、"高个女人",而没有看到过"高个女孩",那么就连"高个女孩"这个词都不存在。

因此,我们想要的是一个拥有更丰富的词汇量和更深入理解词汇中词汇之间关系的模型。幸运的是,聪明的研究人员已经发明了如此强大的模型,我们可以用它们来创作更好的歌曲。

GPT-2模型

OpenAI的GPT-2模型,最近因为"太危险而不能发布"而成为头条新闻。"模型生成这样的令人信服的文本,作者认为这可能是用于恶意用途。相反,他们发布了两个更小的版本供人们玩耍和实验。我们将使用其中最小的一个来生成披头士的歌词。

GPT-2是一个基于transformer的模型。在训练期间,它能够学习一个非常好的英语模型(或者至少是Reddit上使用的英语版本)。这意味着它能够理解像"高"这样的东西,它可以适用于人类、建筑物或长颈鹿。此外,由于它在Reddit上的训练占很大一部分,它很可能看到了99.9%的英语单词和短语。这对我们来说是个好消息,因为这正是我们一直在寻找的:一个庞大的词汇表和对如何使用这个词汇的深刻理解。

然而,如果我们打开这个模型,让它生成一些东西,它几乎不可能产生类似披头士的歌词。这是因为模型不知道我们所倾向的是生成披头士的歌词,毕竟这不是它被训的方向。相反,我们需要推动模型去做我们想让它做的事情。我们可以通过迁移学习来做到这一点。

迁移学习

迁移学习是指我们可以通过做一件事来利用我们所学到的信息,并将其应用于解决相关的问题。例如,当你开始阅读这篇文章时,你不需要重新学习单词是什么,哪些单词跟在哪些单词后面,或者它们是如何组合成句子的。想象一下那将是多么乏味。相反,你利用了所有阅读的文学书籍的时间来理解我现在所谈论的内容(我想 Huck Fin毕竟派上了用场)。

以类似的方式,我们可以利用GPT-2通过阅读Reddit上数百小时的帖子所学到的知识,并将其迁移到生成披头士歌词的任务中。高层次的想法是采用预先训练的模型,并将其训练更长时间。不过,我们将只使用披头士的歌词,而不是Reddit上的帖子。这将使模型严重偏向于生成类似披头士的歌曲。

我将跳过如何做这个,因为它将采取另一个类似长度的帖子来解释一切。

新的披头士乐队

就像所有优秀的深度学习成果一样,我在引言中发布的歌词也是精心挑选的。生成的歌曲并不都是那么的好,它们的质量取决于微调阶段的位置。当模型仍然严重不适合训练数据时,对大约100个小批量进行微调后,你可能会得到以下结果:

教你用机器学习生成披头士的歌词

这样再写10-15行。至少比Lil'Pump还要好。

说正经的,我最感兴趣的是前两行。在训练数据中,每首歌的开头第一行是标题,第二行是作者,下面几行是歌词。即使在这个早期阶段,该模型也设法了解了我们数据的结构:第一行和第二行是特殊的;在第二行中,可能出现的单词组合很少,最有可能出现的是列侬和麦卡特尼。

如果我们微调约350个小批量,模型开始产生更可信的歌词,如在介绍,或这一个:

教你用机器学习生成披头士的歌词

不完美,但还不错。最后,如果我们进行太长时间的微调,会发生以下情况:

教你用机器学习生成披头士的歌词

模型开始过度拟合,生成的样本很可能出现在训练数据中,如重复的"列侬&麦卡特尼"台词、"黄色潜水艇"等。我发现大约300-500步的微调能产生最好的歌词。

结论

希望你现在对语言模型的工作原理有了更好的了解,并且了解我们如何利用最先进的模型来尽力的改进后续任务。

话虽如此,GPT-2模型还有很多值得探索的地方。我生成的示例使用默认的suboptimal hyperparameters。如果把更多的时间花在正确的微调上,看看生成的歌词能有多好会很有趣。我也只使用了发布的最小型号,因为我是用笔记本电脑训练的。我相信更大的模型会产生更美好的结果。最后,OpenAI最近发布了MuseNet,它能够生成非常逼真的音乐。如果将GPT-2和MuseNet放在一起(它们基本上是相同的模型),并生成歌词和伴奏音乐,那该有多棒?如果我有更多的时间、金钱,或者对我正在做的事情有任何想法,我愿意用机器学习来创作一首成熟的歌曲,然后让真正有天赋的人来表演。

相关推荐