做这个项目纯粹是好玩。问题是这么来的,没事躺床上听歌,发现网易云音乐有个“听歌识曲”功能,对着手机唱了一段,然而并没有什么用。一度怀疑 自己的演唱水平下降了,甚至开始怀疑人生。不过经过一番研究后,却为我打开了一扇知识的大门。

原来网易不是让人唱歌识别的,它使用的是声纹识别技术,对音乐片段提取特征(傅立叶描述子)做哈希,也就是说对建好索引的音乐只有replay才能准确 检索到,同一首歌的翻唱、清唱都不会当作同一首歌。

原来我想要的是一个哼唱检索系统,学名叫 Query By Humming System,它与声纹识别的不同在于特征选取上。

歌曲特征的提取

声纹识别使用傅立叶描述子特征,我们知道,声音可以可做是多个三角波的叠加,根据傅立叶描述子可以重建原始信号。它提取了傅立叶特征本质上 是对原始信号做了压缩,也可以看作是一个hash的过程。只有一模一样的声音才能得到一样的傅立叶特征。所以杨宗纬与孙燕姿的“雨天”在声纹识别看来 就是两首歌。

哼唱检索的的特征提取为一个叫音高(pitch)的特征,得到一个音高序列。音高这个名词其实是试图用数值化方法来描述人对音乐的理解,感兴趣的可以以[fundamental frequency,pitch]为关键字作为进一步的理解。这样,哼唱的音乐检索就是查询特征数据库中与该序列最接近的音高序列,其对应的即最可能 哼唱的歌曲。

此外,在pitch之上可以进一步提取特征,称为note特征,它其实是将pitch特征离散化,将音高固定在几个段位上。在时间段(t_i,t_i+1)之间音高为n, 将pitch序列分割成(note,duration)这样的序列,与midi音乐格式暗合。

不管是选pitch特征还是note特征,检索的任务就变成了两个时间序列的匹配过程,匹配的相似度以其距离来度量。 一般来讲note特征匹配速度较快,但是精度低一些,所以常用算法都是将两者结合起来,利用note特征筛选出种子歌曲,在种子中再根据pitch特征匹配, 根据两次的筛选结果联合打分。

时间序列的比较

linear scaling 和 dtw是常用的方法。这两个一个是线性拉伸,一个是动态规划求最优路径,老生常谈了。

论文中看到有用高维数据索引的方式,这是第一次见到,不禁眼前一亮。采用方法叫做局部敏感哈希(Locality-Sensitive Hashing, LSH),它将近似的序列尽量映射到一起,类似于找k近邻的k-d树,除了k-d树在高纬数据中表现不佳(不停的递归回溯父节点的其他子节点)。这个方法会在后期加入我的系统中去。

存在的问题

时间序列的比较,算法的计算量会随着序列长度暴涨,所以就不适合对整首歌曲特征提取。不过,在多数应用场景中人会哼唱歌曲开头或副歌部分, 所以对这两部分特征提取不失为一个好办法。然而,又引入一个问题,如何自动找出歌曲副歌部分?需要进一步研究。目前的实现只考虑了歌曲开头 部分的特征。

计算速度慢,可以考虑使用GPU加速查询速度,前期资料准备过程中,看到有几篇论文有实现,剩下的就是纯工程问题了。

深度学习在图像领域运用的风生水起,语音与图像实在是有太多相似的地方,语音识别已经使用了深度学习取得不错的效果,哼唱检索却没有看到 相关的论文,实在是可惜。

目前只是一个雏形系统,速度与功能都不太满意,希望毕业前能把这个有意思的事情做好,详见你唱我猜

TODO:

  • 提供web、微信使用接口
  • 副歌纳入提取特征
  • 计算速度优化
  • 深度学习方法研究
Original Link: http://tianyaqu.com/blog/2015/08/01/a-query-by-humming-system/
Attribution - NON-Commercial - ShareAlike - Copyright © Alex

Comments