论文阅读 - Jukebox: A Generative Model for Music

文章目录

  • 1 概述
  • 2 什么是VQ-VAE
    • 2.1 Auto-encoder(AE)
    • 2.2 Variational AutoEncoder(VAE)
    • 2.3 Vector-Quantized Variational AutoEncoder(VQ-VAE)
    • 2.4 VQ-VAE-2
  • 3 Music VQ-VAE
  • 4 Prior and upsamplers
  • 5 Lyrics Conditioning
  • 参考文献

By learning to produce the data, we can learn the best features of the data.
— OpenAI

1 概述

音乐生成一直是一个很有意思的话题,之前看过一些音乐生成的方式,都是将midi格式的音乐进行结构化之后,把这些midi音乐当作文本放到NLP的模型里去训练生成任务。然后输出也是一堆midi,再用其他的软件渲染出来。这样出来的音乐虽然还可以,但是把音乐限制在了某些固定的乐器当中,如果要想这样的音乐有人声是别想了。

Jukebox从raw audio入手,让模型直接生成音频信号。最终的模型可以控制演唱者,音乐风格,以及唱的歌词,效果很惊艳!

本文的目的是让读者对Jukebox有个直观上的了解,其中很多细节不回去深究。

2 什么是VQ-VAE

如果知道VQ-VAE的,本节可跳过。知道了VQ-VAE,也就知道了Jukebox的一半,因此花些篇幅来讲这个。

VQ-VAE(Vector-Quantized Variational AutoEncoder)不是这篇文章当中提出来的一种方法,而是生成任务中已有的一种方法,下面来说下什么是VQ-VAE,说的顺序是AE -> VAE -> VQ-VAE -> VQ-VAE-2。这里不会设计数学公式的推导,只是直观上的理解,要看公式推导的可以参看最下面的参考文献。

2.1 Auto-encoder(AE)

如下图1所示,自编码器是很早就已经提出来的一种抽取特征的方法,它有一个Encoder和一个Decoder。以输入图片为例,Encoder会把图片压缩成一个指定维度的向量,这个向量当中包含了用于重建图片的重要特征,Decoder会把这个特征重建成和输入尽可能接近的图片。这是一种无监督或者说自监督的学习方法,loss就是输入和输出图片的距离,被叫做reconstruction loss。

可想而知,若要重构的图片尽可能接近输入图片,Encoder输出的特征就必须要包含输入图片尽可能多的信息,也就是这是一个可以表达输入图片的特征。

这本质上和PCA很像,就是给图片降维。
auto-encoder

图1 Auto-encoder示意图[1]

AE的Decoder部分可以当作一个生成模型,但是有很大的问题。对于生成模型,我们希望输入稍微变化后,输出的图片变化不会太大。但是AE没有办法保证这一点。比如下图2所示,红色的code线是在code特征空间上的一条线,线上每个点都是一个特征,一个code,一个decoder的输入。假设在训练过程中,模型知道了左边这个点对应满月,右边这个点对应上弦月。那么我们希望把这两个点的中点输入给decoder之后,得到的是盈凸月(就是3/4个月亮是亮着的)。而AE训练出来的模型并不知道这种事情,只能看运气了。
ae

图2 Auto-encoder特征映射关系示意图[1]

因此AE并不适合用于生成任务。

2.2 Variational AutoEncoder(VAE)

为了让AE适用于生成任务,就有人提出了VAE。想法很直接,既然映射到一个点上不好,我们就把输入图片映射到一个分布上,或者形象点说是一块区域上。

VAE的Encoder输出就是均值mim_imi和方差σi\sigma_iσi。Decoder接到的特征ci=mi+exp(σi)×eic_i=m_i + exp(\sigma_i) \times e_ici=mi+exp(σi)×ei。这里要这么折腾是因为从分布中sample的过程是不可导,那么就干脆把标准的正太分布当作一个外部的常量放进来,不参与梯度更新。这样每次传播的时候,均值和方差由encoder提供,利用外部的标准正太分布做sample,这样整个网络就可导了,机智啊!
vae

图3 VAE示意图[1]

不过模型也挺机智,如果还是像AE一样只有一个reconstruction loss,那么网络就会学会把σi\sigma_iσi都置为0,因为σi\sigma_iσi的存在,encoder的输入是同一张图片时,decoder的输入却会是不同的,这样decoder烦的很,干脆把σi\sigma_iσi置0,这样对模型来说训练简单了,但是却退化为了AE。我们就是要让decoder在有σi\sigma_iσi的噪声干扰下,仍旧尽可能地还原图片。

于是,更机智的人类就加了一项KL散度loss,让encoder输出的分布N(mi,σi)N(m_i,\sigma_i)N(mi,σi)尽可能接近N(0,1)N(0, 1)N(0,1)。这个loss化解后也就是图中的

LKL=∑i=1n(exp(σi)−(1+σi)+(mi−0)2)L_{KL}=\sum_{i=1}^{n}(exp(\sigma_i) - (1+\sigma_i) + (m_i - 0)^2) LKL=i=1n(exp(σi)(1+σi)+(mi0)2)

实际情况下,还会有一个权重来调节reconstruction loss和KL loss的权重。

有了σi\sigma_iσi提供的噪声和足够多的训练数据,模型就会遇到不同输入映射到同一块特征区域的情况,这种时候,模型就知道要如何渐变了。
vae

图4 VAE特征映射关系示意图[1]

2.3 Vector-Quantized Variational AutoEncoder(VQ-VAE)

VAE不好的地方在于容易后验失效,也就是容易train坏掉。而且现实生活中,有些特征它就是不连续的,它就是离散的,比如音乐当中的note,于是就有了VQ-VAE。

VQ-VAE有一个东西叫做codebook(图5中的embedding space),这个codebook里有有限个特征,decoder的输入就会是这个codebook中的特征的一个组合,换句话说,encoder的输出都会被映射到codebook当中的某个特征上。映射的方法很简单,就是取距离最接近的那一个。

codebook当中的特征都是模型学出来的。

vq-vae

图5 VQ-VAE示意图[2]

整个过程可以描述成下面这样:
(1)输入图片XXX,经过encoder之后得到特征Ze(X)Z_e(X)Ze(X)
(2)在codebook中找到与Ze(X)Z_e(X)Ze(X)最接近的特征的index,并记在q(z∣x)q(z|x)q(zx)当中
(3)通过q(z∣x)q(z|x)q(zx)从code中取特征得到Zq(X)Z_q(X)Zq(X)
(4)Zq(X)Z_q(X)Zq(X)经过decoder之后得到生成的图片X′X'X

这里从codebook中找最接近的特征的过程也是一个不可导的过程,但是作者用了一个Straight-through estimator的方法,让整个网络可导。其本质就是引入stop gradient,用codebook中选中的特征和encoder输出特征的差值来辅助传导。其loss为

L=Lrecons+Lcodebook+βLcommitL = L_{recons} + L_{codebook} + \beta L_{commit} L=Lrecons+Lcodebook+βLcommit

其中,LreconsL_{recons}Lrecons为reconstruction loss,也就是输出图片和原图的距离。这个loss当中会把codebook当中的特征当成常量,不更新codebook的内容。也就是这个操作使得整个网络可以梯度更新。
Lrecons=−log⁡p(X∣Zq(X))L_{recons} = -\log p(X|Z_q(X)) Lrecons=logp(XZq(X))

LcodebookL_{codebook}Lcodebook为codebook loss。这部分更新codebook里的向量。sg就是stop gradient。这一步是让codebook的向量和encode的输出尽可能接近。

Lcodebook=∣∣sg(Ze(X))−e∣∣22L_{codebook} = || sg(Z_e(X)) - e||_2^2 Lcodebook=sg(Ze(X))e22

LcommitL_{commit}Lcommit为commit loss。这部分不更新codebook里的向量。这一步是让encode的输出和codebook的向量尽可能接近。
Lcodebook=∣∣Ze(X)−sg(e)∣∣22L_{codebook} = || Z_e(X) - sg(e)||_2^2 Lcodebook=Ze(X)sg(e)22

VQ-VAE就是这点东西,有意思在这个loss的设计上。我们再来看看它的全称,Vector-Quantized Variational AutoEncoder。Vector-Quantized指的就是把特征映射到codebook当中的向量上,用codebook的向量把encoder的输出进行量化。Variational在哪里呢?这里没有σi\sigma_iσi啊?我的理解是,codebook中的每个向量都对应了一片离它最近的区域的向量,这篇区域就是它噪声的容忍度,也就是variational的地方。

2.4 VQ-VAE-2

VQ-VAE还是容易坏掉,而且生成的大图会比较模糊,所以又有人提出了进阶版VQ-VAE-2。简单来说就是把模型变成了multi-level的,也就是hierarchical。Top level负责全局信息,bottom level负责局部信息。这样的模型不容易 collapse,而且细节也会比较到位。我没有仔细看VA-VAE-2的文章,所以具体的细节这里不讲了,可以参考下文献[4]。
在这里插入图片描述

图6 VQ-VAE-2示意图[4]

3 Music VQ-VAE

音乐里的"do",“re”,"mi"都是离散的,因此相比于VAE,在音乐领域VQ-VAE显得更为合适。

这里的Music VQ-VAE既不是单纯的VQ-VAE也不是VQ-VAE-2。它的结构图如下图6所示,乍看之下就是多个VQ-VAE。Music VQ-VAE相比于VQ-VAE和VQ-VAE-2主要有3点不同:
(1)codebook随机初始化
VQ-VAE的codebook是很容易train坏掉的,说的夸张点,可能train着train着,codebook中的向量都映射到同一个向量上了。Music VQ-VAE会在每个batch计算codebook中各个向量的平均使用率,如果使用率过低,就会把这个向量随机初始化成当前batch中的一个向量上。保证codebook中的向量使用率都是比较高的。

(2)多个level的VQ-VAE
Music VQ-VAE的encoder会把音频压缩成不同的尺寸,也就是抽取特征时的hop_length不同。比如下图中的top level可能是1s抽一个feature,middle level可能是0.5s抽一个feature,bottom level可能是0.2s抽一个feature,这里的时间只是我随便举的例子。然后每个level独自是一个VQ-VAE,相互之间不影响,codebook也是独立的。top level关注于一些全局的信息,middle level和bottom level则更关注细节。如果单独拿它们的feature进行decode的话,bottom level的效果应该是最好的。

(3)加了 Spectral Loss
增加了Spectral Loss来让生成的音频保留高频的信号,否则高频信号很容易丢失。不同STFT参数的结果对时间和频率的分辨率影响不同,为了让模型不对某一组STFT的参数过拟合,Music VQ-VAE还用了多组参数的STFT,然后取它们loss的和。
Lspec=∣∣∣STFT(x)∣−∣STFT(x^)∣∣∣2L_{spec} = || | STFT(x) | - | STFT(\hat{x}) | ||_2 Lspec=STFT(x)STFT(x^)2

music-vq-vae

图6 Music VQ-VAE示意图[5]

4 Prior and upsamplers

在生成模型的时候,我们是没有图5中左边部分的encoder的,我们只需要decoder和codebook中向量的组合就可以了。decoder的输入,也就是codebook中向量的组合在生成任务中是要无中生有变出来的,这就是prior和upsamplers的作用,生成decoder的输入。

p(z)=p(ztop,zmiddle,zbottom)=p(ztop)p(zmiddle∣ztop)p(zbottom∣zmiddle,ztop)p(z) = p(z^{top}, z^{middle}, z^{bottom}) \\ = p(z^{top})p(z^{middle}|z^{top})p(z^{bottom}|z^{middle}, z^{top}) p(z)=p(ztop,zmiddle,zbottom)=p(ztop)p(zmiddleztop)p(zbottomzmiddle,ztop)

我们的Music VQ-VAE是三个levels的,top level的decoder输入生成器叫做prior,p(ztop)p(z^{top})p(ztop),因为它不依赖于其他输入,我们只要给一个随机的高斯分布或者什么随机的分布就行了,它是先验的。middle level和bottom level的decoder输入生成器叫做upsampler,p(zmiddle∣ztop)p(z^{middle}|z^{top})p(zmiddleztop)p(zbottom∣zmiddle,ztop)p(z^{bottom}|z^{middle}, z^{top})p(zbottomzmiddle,ztop),它依赖于上面生成的结果,是后验的。下图7中蓝色的block就是prior和upsamplers。
Ancestral sampling

图7 Ancestral sampling示意图[5]

这三个东西就是三个网络结构,对于prior,论文设计了一个和Sparse Tranformer很像的网络,叫做Scalable Transformer的东西,对于upsampler,论文在WaveNet上加了点东西。具体的结构这里不展开讲。我们希望它们生成的特征和Music VQ-VAE训练时的中间从codebook生成的特征是类似的,这就是用自回归的方式去训练就可以了。

我们一方面希望生成模型是多样的,一方面又希望可以控制一下生成的结果,因此会在prior和upsampler的输入中也加入音乐家,音乐风格以及时间的信息。

如果不用prior和upsampler的话,也可以直接用音乐的某个片段经过Music VQ-VAE的encode部分的结果,这个时候的任务变成了续写歌曲了(completions of the song)。

Primed sampling

图8 Primed sampling示意图[5]

5 Lyrics Conditioning

这篇论文惊艳的地方就在于,它可以生成有人声的音乐,而且唱的真像那么回事儿,压根儿听不出是机器合成的。这就得益于它的lyrics conditioning的机制了。为什么说它厉害,现在不是Text-to-speech(TTS)也搞得像模像样吗?唱和说还是有难度区别的,唱有这么三个难点:

(1)模型需要学会对齐歌词和唱的声音

(2)模型需要知道不同音乐家唱歌的风格

(3)模型需要知道同一句话,因为音调,节奏和歌曲风格的不同,唱出来的方法是不一样的

这么一想,还真的挺难的。不光解决这些问题难,要达到大量的歌词和音乐对应的数据就很难。论文为了让任务更简单,就把音乐切成24s的一段一段,然后对应歌词,放进去让模型去学习。网上爬下来的歌词和音乐是不一定能对上的,因此,论文又用了Spleeter抽取人声,用了NUS AutoLyricsAlign把歌词和时间对上。总之就是得到了许多音乐片段,并且这些片段都有对应的歌词文本。

这个歌词是经过一个tranformer变成特征之后和其他conditions一起输进去训练的,其结构如下图9。
music prior

图9 music prior示意图[5]

事实证明,这样的训练,模型可以学到歌词和音乐之间的对齐方式。不过偶尔也会有坏掉的情况,这种情况下,歌词就乱唱了。
在这里插入图片描述

图10 歌词和音乐对齐示意图[5]

Jukebox放出了很多生成的音乐,可见在https://jukebox.openai.com/听一下。

参考文献

[1] Unsupervised Learning: Deep Generative Model
[2] 帶你認識Vector-Quantized Variational AutoEncoder - 理論篇
[3] 变分自编码器VAE:原来是这么一回事
[4] Generating Diverse High-Fidelity Images with VQ-VAE-2
[5] Jukebox: A Generative Model for Music

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十五、PHP框架Laravel学习笔记——构造器的 join 查询

一.join 查询 使用 join 实现内联接的多表查询,比如三张表进行 inner join 查询; $users DB::table(users) ->join(books, users.id, , books.user_id) ->join(profiles, users.id, , profiles.user_id) ->select(users.id, user…

论文阅读 - Group Normalization

文章目录1 概述2 几种normalization的方法2.1 Batch Norm2.2 Layer Norm2.3 Instance Norm2.4 Group Norm3 效果对比参考文献1 概述 Group Nomralization的提出是为了解决一张GPU上能容纳的batch_size很小,导致模型训练效果显著变差的问题。随着深度学习的快速发展…

十六、PHP框架Laravel学习笔记——构造器的增删改

一.增删改操作 使用 insert()方法可以新增一条或多条记录; //新增一条记录 DB::table(users)->insert([ username > 李白, password > 123456, email > libai163.com, details > 123 ]); //新增多条记录 DB::table(users)->insert…

git如何切换分支_拜托,不要再问我Git分支如何使用

今天来讲讲我使用Git分支的一些经验,记录一下,希望对大家有帮助。阐述在平常开发中,一般都会对应三种环境,本地环境、测试环境、线上环境。开发的基本流程都是先在本地环境开发好,再把代码发布到测试环境测试,最后再发…

搞懂HMM

文章目录1 概述2 符号说明3 两点假设4 Evaluation4.1 前向算法(forward algorithm)4.2 后向算法(backward algorithm)5 Learning6 Decoding参考资料1 概述 本文是B站上机器学习-白板推导系列(十四)-隐马尔可夫模型HMM的学习笔记&…

书店售书最低价格问题

书店针对《哈利波特》系列书籍进行促销活动,一共5卷,用编号0、1、2、3、4表示,单独一卷售价8元, 具体折扣如下所示:本数 折扣 2 5% 3 10% 4 …

十七、PHP框架Laravel学习笔记——模型的定义

一.默认设置 框架可以使用 Eloquent ORM 进行数据库交互,也就是关系对象模型; 在数据库入门阶段,我们已经创建了一个 User.php 模型,如下: php artisan make:model Http/Models/User //默认在 app 目录 …

centos 启动一个redis_基于prometheus+grafana体系监控redis缓存服务

概述前面已经介绍了怎么用prometheus监控mysql数据库,今天主要分享下怎么去监控redis服务。由于没有redis环境,所以用docker模拟了一下。一、Docker部署1、下载sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.…

十八、PHP框架Laravel学习笔记——模型的增删改

一.增删改操作 新增方法如下,注意:默认模型接管 created_at 和 updated_at; $users new User(); $users->username 辉夜; $users->password 123; $users->email huiye163.com; $users->details 123; $use…

搞懂语音去噪

文章目录1 概述2 传统语音去噪2.1 谱减法2.2 维纳滤波法3 深度语音去噪参考资料1 概述 语音去噪(noise reduction)又被称为语音增强(speech enhancement),主要是针对于有人声的音频进行处理,目的是去除那些背景噪声,增强音频中人声的可懂性(…

软件架构设计案例_透过现象看本质:常见的前端架构风格和案例

所谓软件架构风格,是指描述某个特定应用领域中系统组织方式的惯用模式。架构风格定义一个词汇表和一组约束,词汇表中包含一些组件及连接器,约束则指出系统如何将构建和连接器组合起来。软件架构风格反映了领域中众多系统所共有的结构和语义特…

十九、PHP框架Laravel学习笔记——批量赋值和软删除

一.批量赋值 上一节增删改中,新增中我们发现需要进行批量赋值的许可;一般情况下,是为了防止提交过来的字段在部分场景中不需要或不能;所以,我们需要通过黑白名单机制进行过滤掉必要的字段; //通…

speech production model

文章目录1 概述2 source model3 filter model4 小结参考资料1 概述 本文的目的是为了厘清在speech production model中source model和filter model所扮演的角色,不涉及具体公式的推导或者模型的建立,只是为了把这两个model在干什么事情说明白。文中用到…

二十、PHP框架Laravel学习笔记——模型的作用域

一.本地作用域 很多情况下,我们在数据查找时有一部分条件会被重复且大量使用;而这个条件,可能只是在这个模型对应的数据表使用,别的表并不使用;那么这种情况,可以使用本地作用域的方式&#xf…

论文阅读 - Joint Beat and Downbeat Tracking with Recurrent Neural Networks

文章目录1 概述2 信号预处理3 分类神经网络4 动态贝叶斯网络(HMM)4.1 原始的bar pointer model4.2 原始的bar pointer model的缺点4.3 改进后的模型5 预测参考资料1 概述 最近在做音乐卡点相关的项目,需要对音乐的基本特征进行理解&#xff…

二十一、PHP框架Laravel学习笔记——模型的访问器和修改器

一.访问器 访问器:就是在获取数据列表时,拦截属性并对属性进行修改的过程;比如,我们在输出性别时,在性别左右加上括号,或给邮件转换为大写; //访问器,前固定 get&#…

python将txt转json_Python控制乐高EV3,以及VSCODE环境配置

乐高EV3的可扩展性很强,但如何用pc连接ev3,并用python代码来控制EV3,资料太少了,试着做了一次,记录在这里。需要的硬/软件硬件准备一、乐高EV3二、PC,win10系统三、TF卡(我用的是64G的&#xff…

移动文件读/写指针----lseek

头文件&#xff1a;#include<sys/types.h>、#include<unistd.h> 函数原型&#xff1a;off_t lseek(int fildes,off_t offset,int whence) 参数说明&#xff1a;fildes:文件描述符 offset:偏移量&#xff0c;正数表示正向偏移&#xff0c;负数表示负向偏移。 whence…

Yolo系列知识点梳理(Yolov1-v5)

文章目录1 概述2 Yolo系列模型2.1 基石 - Yolov12.1.1 Yolov1的网络结构2.1.2 Yolov1的feature map2.1.3 Yolov1的训练2.1.4 Yolov1的预测2.1.5 Yolov1小结2.2 Yolo9000 - Yolov22.2.1 Better2.2.1.1 引入了Batch normalization2.2.1.2 高分辨率的分类器2.2.1.3 加入了anchor机…

二十二、PHP框架Laravel学习笔记——集合的使用

一&#xff0e;创建集合 什么是集合&#xff1f;即&#xff1a;它是一种更具读取性和处理能力的数组封装&#xff1b;比如&#xff0c;我们从数据库得到的数据列表&#xff0c;它就是一种集合&#xff1b;数据集合&#xff0c;提供了大量的方法方便我们进行各种操作&#xff1…