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

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

教你用机械进修生成披头士的歌词 休闲娱乐

事实上,这些歌词并不是你所知道的披头士写的。
不是约翰·列侬、 保罗·麦卡特尼、乔治·哈里森、乃至也不是林戈·斯塔尔。
它们实际上是由机器学习模型天生的,即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放在一起(它们基本上是相同的模型),并天生歌词和伴奏音乐,那该有多棒?如果我有更多的韶光、金钱,或者对我正在做的事情有任何想法,我乐意用机器学习来创作一首成熟的歌曲,然后让真正有天赋的人来演出。