http://www.csdn.net/article/2015-02-10/2823907
摘要:本文概述了作者在Spotify的机器学习实践经验,解释了使用卷积神经网络(CNN)做基于音频的音乐推荐的方法,并提出了有关该卷积网络的实际学习效果的心得。采用了GTX 780Ti GPU,Theano软件框架,小批量梯度下降法。
【编者按】本文是比利时根特大学(Ghent University)的Reservoir Lab实验室博士研究生Sander Dieleman所撰写的博客文章,他的研究方向是音乐音频信号分类和推荐的层次表征学习,专攻深度学习和特征学习。以下为译文:
2014年夏天,我在 网络音乐平台Spotify (纽约)实习, 致力于使用卷积神经网络 (convolutional neural networks)做基于内容的音乐推荐。本文将介绍我使用的方法,并展示一些初步的结果。
这篇文章很长,所以先对各节的内容做一个概述:
网络音乐平台Spotify传统上 主要依靠协同过滤 驱动音乐推荐。 协同过滤 的原理是根据历史使用数据确定用户的喜好。 例如,如果两个用户收听大致相同类型的歌曲,他们的喜好大概就是类似的。反过来,如果两支歌曲由同一组用户所收听,这些歌曲听起来很可能是相似的。这种信息可以被用来做推荐。
纯粹的协同过滤方法,除了相关的消费模式信息以外,不涉及被推荐物品本身的任何信息:也就是它是内容无关的(content-agnostic)。这个特点使得这种方法可以有非常广泛的应用:例如,同样的一个模型就可以用于推荐书籍、电影或者音乐。
不幸的是,这个特点也导致了它最大的不足。由于依据使用数据,流行物品就会比非流行物品更容易得到推荐,因为前者有更多的使用数据。而这通常是刚好与我们所希望的相反。由于同样的原因,这样的推荐常常是很无聊的,而且是可预知的。
特定到音乐还有另一个问题,就是相似使用模式的内容异质性(heterogeneity of content with similar usage patterns)。例如,听众可能一次听过了整张专辑,而专辑中可能包含引曲、终曲、 插曲、 翻唱曲和混音曲等。它们也许不都是该艺术家典型的作品,因此不是一些好的推荐。可是协同过滤算法不能解决这个问题。
而它最大的问题,可能还在于不能推荐新的和非流行的歌曲:如果没有可供分析的使用数据,协同过滤方法就会失效。这就是所谓的冷启动问题。 我们希望新音乐能够在发行后的第一时间获得推荐,而且我们也希望能向听众介绍那些他们从来没有听过的很棒的乐队。为了实现这些目标,我们就需要有不同的方法。
Spotify根据几个月之前从智能音乐平台 The Echo Nest 得到的反馈信息,最近已经开始考虑在推荐管道中结合其它信息源,以减少这些问题。可以帮助音乐推荐的信息有很多种:比如标签,艺术家和专辑信息,歌词,从互联网上挖掘到的文稿(评论、访谈…),以及音频信号本身。
在这些信息源中,音频信号可能是最难有效利用的。一方面由于音乐音频信号之间的语义差别(semantic gap)很大,另一方面影响听众喜好的因素又多种多样。有的信息可以比较容易地从音频信号中提取出来,比如音乐的类型和演奏的乐器;而其他的就比较有挑战性了,比如音乐的情绪,和发行的年份(或者时期);还有一些实际上是不可能从音频中得到的:就像艺术家所在的地理位置和抒情的主题。
尽管存在这些挑战,但是很明显地,歌曲的实际声音极大地影响到听众是否愿意收听。于是通过分析音频信号,预测谁可能欣赏这支歌曲,看起来像个不错的主意。
去年十二月, 我和同事Aäron van den Oord 在NIPS上发表了一篇关于这个主题的论文, 题目是‘ Deep content-based music recommendation’(基于内容的深度音乐推荐) 。我们试图这样解决问题:通过训练回归模型(regression model),预测从协同过滤模型输出歌曲的隐藏表征(latent representations) ,实现依靠音频信号预测收听喜好。这个方法可以使我们在即使没有使用数据的情况下,也能够在协同过滤空间中预测歌曲表征。(正如可以从论文的题目中推测出来的那样,涉及的回归模型是一个深度神经网络)。
这种方法的基本思想是假定许多协同过滤模型都是把听众和歌曲投射到一个共享的低维度隐空间(latent space)中。在这个空间中歌曲的位置包含了影响听众喜好的各种编码信息。假如有两首歌曲在空间上临近,它们很可能是相似的。如果一首歌曲距离一个听众很近,这首歌对他可能就是一个好推荐(如果他还没有听过这首歌)。如果可以通过音频信号预测一首歌曲在这个空间中的位置,那就能够把它推荐给合适的听众,而并不需要历史使用数据。
论文中我们做了可视化效果,即通过投射隐空间中模型的预测结果到使用 t-SNE 算法 降低的二维空间。从如下的结果图中可以看出,相似的歌曲群集到了一起。说唱乐主要出现在左上角,而电声艺术家聚集在图的底部。
t-SNE算法的隐空间可视化(中部)。几个特写图展现了歌曲投射在特定区域的艺术家。摘自 Deep content-based music recommendation, Aäron van den Oord, Sander Dieleman and Benjamin Schrauwen, NIPS 2013.
在我们论文中训练的深度神经网络由两个卷积层和两个完全连接层组成。输入是3秒钟音频片断的声谱。对于更长音频片断的预测,只需要把它分成几个3秒钟长的窗口,然后把这些窗口的预测值作平均。
我在Spotify接触了大量歌曲的数据源,以及从不同的协同过滤模型产生的隐藏因素表征(latent factor representations)。我还配备了一台高级的GPU,用于实验运算。它们相当地提升了效率。现在我正在训练总数达7层或8层的卷积神经网络(convnets),使用了大得多的中间表征和更多的参数。
下面详细介绍的,是我已经实验过的诸多架构中的一个。它有四个卷积层和三个稠密层(dense layers)。你将看到为了音频信号设计的卷积神经网络,与用于计算机视觉网络任务的传统神经网络,有一些重要的不同。
警告:下面有可怕的细节!如果你不太关心诸如ReLUs,最大值池化(max-pooling)和小批量梯度下降法(minibatch gradient descent)等细节,尽管直接跳到“分析”段落。
我试验过的用于隐藏因素预测的一种卷积神经网络架构。纵轴是时间轴(在其上卷积)。
网络输入是一系列梅尔声谱(mel-spectrograms),它们有599帧(frames)和128 个频点(frequency bins)。梅尔声谱是一种时间-频率表证(time-frequency representation)。是从音频信号的窄重叠窗口傅立叶变换(Fourier transforms)得到的。每一个傅立叶变换构成一帧。 然后将这些连续的帧排列成一个矩阵,就形成了这个声谱。最后将频率轴由线性刻度变成 梅尔刻度(mel scale)以降低维数,并且采用对数刻度值。
卷积层用红色矩形显示, 表现了过滤器滑过输入时的情形。它们使用了线性修正单位(ReLUs, 使用的激活函数是max(0, x))。请注意所有这些卷积都是一维的;卷积仅仅在时间维度出现,而不在频率维度。虽然技术上可以沿着声谱图的两个坐标轴都进行卷积,但现在我并没有这样做。要意识到与图像不一样,声谱图两个轴的意义是不同的(时间和频率),这个非常重要。结果就是,在图像数据中典型的方形过滤器,在这里是没有意义的。
在卷积层之间用最大值池化运算(max-pooling operations)降低时域中间表征采样率,同时增大过程的时不变性。这些操作用“MP”表示。可以看出在每个卷积层中使用了尺寸为4帧的过滤器,在第一与第二卷积层之间是池尺寸为4的最大池化(主要是出于性能方面的考虑),而在其他层之间是池尺寸为2的最大池化。
在最后卷积层的后面,我增加了一个全局时域池化层(global temporal pooling layer)。这一层覆盖整个时间轴,有效地计算时域学习特征的统计值。我引入了三个不同的池化功能:平均值(mean),最大值(maximum)和L2范数(L2-norm)。
我这样做的原因是由于从音频信号中检测到的绝对位置特征,与手头任务的要求不是特别地相关。这里的情况与图像分类不同:在图像分类中,知道一个特征的大概位置就可以了。例如,检测出云朵特征很可能激活图像的上半部分。如果激活在下半部分,可能检测到羊了。在音乐推荐场合,我们通常只对音乐中某些特征整体上是出现还是缺乏感兴趣,所以在时间上做池化是在情理之中的。
另外一种处理方法可以是用短音频片段训练网络,通过平均这些窗口的输出得到较长片段的数据,就像我们在NIPS论文中做的那样。不过在模型中引用池化似乎更好一些,因为在学习阶段就可以开始使用这种处理步骤。
2048个线性修正单位的全局池化特征输入到了一串完全连结层(fully-connected layers)。在本网络中这一串只有两个。该网络的最后一层是输出层(output layer),它选用Spotify用过的各种协同过滤算法中的 vector_exp 算法,预测40个隐藏因素。
训练网络减少协同过滤模型输出的隐藏因素向量与音频预测之间的均方差(MSE)。这些向量首先要按照单位规范(unit norm)标准作规范化。这样做是为了降低歌曲人气的影响(许多协同过滤模型的隐藏因素向量范数往往与歌曲的人气相关)。在稠密层中采用丢弃法(Dropout)作为正规化方法。
我现在使用的数据集是从Spotify保存的一百万条最流行曲目中截取的30秒长的梅尔声谱。我使用了大约一半曲目用做训练(0.5M),大约5000条做在线验证,其余的用做测试。在训练的时候,通过沿着时间轴做随机的偏移,稍稍调整了声谱,扩展了数据。
实现的网络采用了英伟达(NVIDIA )GeForce GTX 780Ti GPU硬件, Theano软件框架。使用了小批量梯度下降法,和涅斯捷罗夫冲量因子(Nesterov momentum)。用一个单独的进程进行数据加载和调整,所以当GPU用于大块数据训练时,下一批数据可以并行地加载进来。总共执行了大约750000个梯度更新。我已经记不清训练这个特殊架构的准确时间了,但我记得总的试验时间在18到36小时之间。
正像我在前面讲到的,这只是我试验过的架构中的一个例子。我已经试过,或将要试验的还有:
这里是几点工作效果不如预期的地方:
现在到了有点酷的部分:这些网络究竟在学习什么?特征看起来是怎样的? 我选择卷积网络解决这个问题的主要原因,是认为根据音频信号的音乐推荐,是一个连接多层次抽象的复杂问题。我希望连续的网络层能像在图像分类问题中那样,渐进地学会更复杂和更多的不变特征。
实际情况看起来确实如此。首先让我们看一看第一个卷积层,它学习直接应用于输入声谱的一组过滤器。这些过滤器是容易可视化的。它们显示在下列图像中。点击就能看到高分辨率版本(5584x562, ~600kB)。负值是红色,正值是蓝色而白色是零值。注意每个过滤器宽度仅仅是四帧。深红色的垂直线将各个过滤器分隔开来。
第一卷积层学习过滤器的可视化。时间轴是横轴,频率轴是竖轴(频率从顶部到底部是增加的)。点击就能看到高分辨率版本(5584x562, ~600kB)。
从这个表示中可以看出,许多过滤器探测出了谐波成分,这体现在不同频率处并行的红蓝条带上。有时候这些条带是向上或向下倾斜的,表示出现了音高的升高或降低。它证明这些过滤器有助于检测人声。
为了对过滤器学习的是什么有更好的理解,我准备了一些最大激活的测试歌曲集播放表。 下面是几个例子。网络的第一层有256个过滤器,它们被从0到255编号。注意这个编号是任意的,因为过滤器没有排序。
通过查找在分析的30秒内对给定过滤器最大激活的歌曲,得到了这四个播放列表。我从第一卷积层中选择了几个看起来有趣的过滤器,计算了每个特征表现,然后从整个测试集中查找最大激活。请注意如果要了解过滤器正在接收的内容,应该听取曲目的中段,因为这部分音频信号才是被分析的部分。
下面每个Spotify播放表都有10个曲目。由于版权的问题有些曲目在有的国家收听不到。
过滤器 14:颤音歌唱过滤器 242: 环境气氛(ambience)
过滤器 250:人声大三度(vocal thirds) 过滤器 253: 低音鼓
过滤器14,242, 250 和 253的特写图。
这些播放表中曲目的流派是很不同的,这表示它们主要是从音频信号的低级特性中检测出这些特征的。
下面四个播放表是用稍微不同的方式获得的:首先对每个曲目计算时域特征的激活平均,然后找出它们中的最大值。这意味着在这些播放表中,涉及的过滤器在分析的30秒钟内一直有效(也就是, 它不会只是一个‘峰值’)。这对于检测和声模式更加有用。
过滤器 1:噪音,失真 过滤器 2:音高(A, Bb)
过滤器 4:嗡嗡声过滤器 28:和声(A, Am)
过滤器1,2,4和28的特写图。
我觉得很有趣的是,该网络学会了检测特别的音高和和声。我以前还以为歌曲中准确的音高和和声的出现,不会影响听众的喜爱程度。至于为什么会这样我有两点推测:
我还没有验证上述两点中的任何一点,但看起来后者对于网络有更大的挑战,因此我认为前者的可能性更大。
网络的每一层都从下一层取得特征表现,然后从中提取一组高级特征。在网络最上面的完全连接层,即最靠近输出层的前面一层,学习过的过滤器对某些副主题是非常有选择性的。 显而易见,在声谱级可视化这些过滤器的检测结果不是一件简单的事情。下面是六个测试集歌曲的播放表,这些歌曲最大激活了其中的几个高级过滤器。
过滤器 3:基督教摇滚(christian rock) 过滤器 15:合唱/无伴奏合唱+时尚爵士
过滤器 26: 福音歌 过滤器 37:华语流行
过滤器 49:合成电子乐,8比特过滤器 1024:deep house音乐
很明显,其中每个过滤器都识别一种特定的类型。有趣的是有些过滤器,比如第15号,似乎是多模式的(multimodal):它强烈地被两种或更多种风格的音乐激活,而那些音乐经常是完全不相关的。大概这些过滤器在结合了所有其它过滤器的激活以后,消除了输出歧义。
过滤器37很有趣,因为它似乎可以识别中文语言。这不是完全不可能的,因为中文的语音库与其他语言相比是很独特的。有其他几个过滤器似乎学习了特定的语言:比如有一个能检测出西班牙语的rap音乐。也有可能性是华语流行音乐存在其它可区分的特性,而那个模型就是检测到了此特性。
我花了一些时间对开始的约50个过滤器作了详细的分析。我想出的其他几个过滤器种类还有:酒廊音乐,雷鬼乐(reggae),暗潮(darkwave),乡村音乐, 金属核(metalcore),莎莎舞乐(salsa),荷兰和德国的狂欢节音乐,儿童歌曲,人声电音(vocal trance),朋克(punk),土耳其流行乐,还有我最喜爱的 ‘exclusively Armin van Buuren’。很明显由于他有那么多的曲目,所以他才有了自己的过滤器。
经过 Alex Krizhevsky ImageNet网络学习的过滤器,已经被重复用在各种计算机视觉任务中,并获得了极大的成功。基于这些过滤器的多样性和不变性特性(invariance properties),这些学习音频信号的过滤器,除了能预测隐藏因素之外,也可以用于其他音乐信息检索任务。
预测的隐因素向量也可以用来查找听起来相似的歌曲。下面是这样产生的几个播放表:首先预测给定歌曲的因素向量,然后从测试集中查找出这样的歌曲,其预测因素向量的余弦距离,靠近给定的歌曲。这样播放列表中的第一个曲目永远是查询曲目本身。
The Notorious B.I.G. – Juicy Cloudkicker - He would be riding on
(嘻哈舞曲) the subway…后现代摇滚,前卫金属)
Architects - Numbers Count For Nothing Neophyte - Army of Hardcore
(金属核, 硬核) (硬式电子音乐, 盖巴舞曲)
Fleet Foxes - Sun It Rises(独立民谣) John Coltrane - My Favorite Things(爵士乐)
绝大多数相似的曲目都是很合适向查询该曲目的歌迷推荐的。当然这些列表并不是很完美的,但是考虑到仅仅依靠音频信号,就获得了这样的结果,应该算是相当不错了。有一个有错误的例子出现在John Coltrane的‘My Favorite Things’播放表中,此播放表的一个不同点是包含几个奇异值(outliers),最明显的地方是在Elvis Presley的‘Crawfish’中。其原因可能是在被分析的音频信号段(从8:40 到9:10)包含一段疯狂的萨克斯独奏。如果分析整首歌曲,可能会有比较好的结果。
Spotify已经在其推荐管道中使用了一大堆不同的信息源和算法,因此我的工作最明显的应用就是添加成另外一个信号源。当然它也可以用来过滤由其它算法推荐的异常结果。我在前面已经指出,协同过滤算法趋向于在推荐中包含引曲、终曲、翻唱曲和混音曲。这些可以通过基于音频的方法有效地过滤。
我在这项工作中的一个主要目标是可以用它推荐新的,以及尚未流行的音乐。我希望这样提供帮助,那些不太知名和未来的乐队,通过允许Spotify向适合的听众推荐他们的音乐,得到公平的竞争环境。(宣传未来的乐队碰巧也是我一个非营利网站 got-djent.com的主要目标。)
希望不久它们的部分功能就能开始 A/B 测试 ,于是我们可以知道这个基于音频的推荐,能不能在实践中表现非凡。这是我非常兴奋的一件事情,因为它不是在学术界轻松做到的。
Spotify收集到的另一种用户反馈形式是用户对电台播放曲目的向上拇指和向下拇指。这类信息对于确定哪些曲目是类似的十分有用。不幸的是其中的噪音也很大。我目前正在尝试在‘ 排序学习’(learning to rank)设置中使用这些数据。我也在实验各种距离度量学习方案,比如 DrLIM。如果有任何很酷的结果我可能会写一篇新的文章。
本文中我概述了在Spotify机器学习实习中到目前为止所做的工作。我解释了使用卷积网络做基于音频的音乐推荐的方法,并提出了有关该卷积网络的实际学习效果的心得。有关这个方法更详细的内容,请参考由我和 Aäron van den Oord在NIPS 2013合写的论文 ‘ 基于内容的深度音乐推荐’(Deep content-based music recommendation)。
如果你对深度学习,特征学习以及它在音乐中的应用有兴趣,可以到我网站的 research中看看,了解一下我在这个领域做过的其它工作。如果你对在音乐推荐中Spotify的方法有兴趣,参考一下Slideshare和 Erik Bernhardsson在其博客中 的介绍。
Spotify是一个很酷的工作场所。他们对其使用的方法很开放(同时允许我写这篇博客文章),这在工业界并不是很常见的。
如果你对本文有任何问题或者反馈意见,请留下你的评论!