我爱编程

乐谱识别

2018-04-03  本文已影响1063人  跑者小越

https://www.lunaverus.com/cnn

音乐中的音符检测可被视为图像识别问题。 在这里,我将回顾一些像狗和汽车之类的图像和音乐图像之间的差异。 我还将描述用于从计算机视觉修改神经网络的技术,以生成实际上颇具可玩性的(和弦)音乐的乐谱转录。

卷积神经网络(CNN)已经在计算机视觉领域取得了最准确的结果。 在一个典型的CNN中,您首先将图像作为三维数组(宽度,高度和3个颜色通道),然后将这些数据通过几层卷积,最大池和某种非线性传递,如ReLU。 最后一层为每个图像类(花,猫等)输出一个分数,表示输入属于该分类的可能性。 反向传播用于从一组标记的训练数据(输入和期望输出对)迭代更新卷积参数。 这个过程建立了一个复杂的功能,由许多简单的功能组成,主要是卷积。

来自音乐的图像

那么,音乐中的音符检测如何与图像识别相似呢? 我们可以创建称为谱图的音频图像。 它们显示频谱或频率内容随时间如何变化。 如果您将立体声音频中的左右声道视为类似于照片中的颜色通道,则谱图图像与您要输入图像识别神经网络的三维图像阵列相似。

频谱图,垂直轴表示频率,水平轴表示时间,颜色显示幅度(蓝色低,红色高)

但在概念上,在谱图图像中找到笔记以找到照片中的物体有多类似? 音乐比较简单,因为没有真正需要学习的重要纹理,频谱图通常仅由两种基本形状组成:谐波,窄频带,跨越短频率范围和长时间范围,以及鼓或其他宽带特征, 它跨越了很短的时间范围和很长的频率范围。 也不需要担心或缩放不同距离的旋转。 而且,我们只关心一个对象类:注释。

B♭ 谐波(对数频率标度)

但是音符的几个方面比物理对象的图像更具挑战性。 在某些基波频率(如B♭3(233 Hz))中的音符由该基频的倍数处的谐波组成,随着上升幅度逐渐减小。 因此,与大多数物体不同,音符不会局限于输入的单个区域。

与物理图像不同,来自不同音符的谐波可能会相互干扰。 在照片中,一个物体可以被另一个物体部分隐藏,但前面的物体不会发生任何变形。 不过,笔记确实会变形。 附近的谐波会导致振幅“跳动”,您可以在上图中的第4次和第5次谐波中看到这种振幅。 音符识别算法需要以某种方式考虑音乐的这些方面。

音符检测有点像找到透明斑马

使用CNN

由于我们希望能够一次检测多个音符,因此可以省略通常用于分类的softmax层。 每个钢琴键只有88个输出节点,而不是图像类。 由于一次处理整个谱图图像是不可行的,我们需要首先检测可能的音符开始时间,然后以这些时间为中心的频谱图的矩形切片(全频率范围和前后的固定时间量 提供一些上下文)。

音符开始检测提供了CNN评估的位置。 这些位置周围的区域(以红色矩形为界)是CNN的输入。

注意起始点的特征是许多频率在某个小的时间间隔内幅度增加的点。 可以训练单独的神经网络来识别这些位置,但我只是在平均幅度变化中寻找局部最大值。 如果这些点中的某些点没有任何注释,这是可以的,因为CNN将确定具体的注释是什么,但是错过有注释的区域是不好的。 我训练CNN找到哪些音符在每个区域开始并忽略偏移量。 为了创建可播放的乐谱,我假设每个音符在下一个音符开始时结束。

创建频谱图

短时傅里叶变换(STFT)是创建频谱图的常用方法,但它有一些缺点。 离散傅里叶变换的频率是线性间隔的,但音符频率与每个八度(每12个音符)一起加倍。 我使用了一些更接近恒定Q变换的东西,这是一个恒定的频率带宽比,每个音符有4个频率分档。 这对于卷积很好,因为第一和第二谐波或第二和第三谐波之间的距离现在对于所有音符是相同的,与基频无关。 这意味着不需要完全连接的层,并且CNN可以完全由卷积层和最大池化层构成。

常数Q转换(ConstantQtransform)与短时距傅立叶转换一样为重要时频分析工具,其中特别适用于音乐信号的分析,这个转换产生的频谱最大的特色是在频率轴为对数标度(logscale)而不是线性标度(linearscale),且窗口长度(windowlength)会随着频率而改变。

STFT,线性频率尺度 相同的音频,常数Q变换,低Q因素干扰 动态Q,这是我们想要的

为了减少来自附近谐波的干扰效应,我在生成频谱图时检测到附近谐波区域的Q因子增加。 这与增加FFT中的窗口大小类似,只是它仅适用于较窄的频率和时间范围。 较高的Q可以减少来自附近谐波的幅度失真,但是改进的频率分辨率是以较差的时间分辨率为代价的,所以我们希望默认使用较低的Q因子来保存关于幅度如何随时间变化的信息。 我还进行了一些非线性缩放以获得更接近振幅对数的东西。

优化CNN

由于音符没有局限于单个区域,CNN需要查看整个频谱以确定是否存在任何特定的音符,因此我使得许多卷积过长且很瘦。 通过最后一层,每个输出神经元都受到每个输入箱的影响。 大多数网络由成对的层组成:一个Mx1,后面跟着一个1xN。 这些长卷积有助于有效连接遥远的频谱区域。

跳过连接(橙色)将CNN分解为一系列添加项或残差

我还使用了微软ResNet中描述的向前跳转连接,它在2015年赢得了ILSVRC挑战。它们帮助网络训练更快,并允许输出由输入上的一系列增加(残差)组成。 这在音乐中很有意义,在消除非基本谐波之后,输出基本上等同于输入。

后期处理

为了提高准确度,对CNN的输出进行了附加处理,滤除了一些较低置信度的音符(音符大于0.5的概率但小于某个阈值)。 这涉及单独的音符检测算法,该算法使用更传统的方法来搜索谱图中的峰值,形成连续峰值的轨道,并从最可能到最不可能的顺序排列候选笔记。 这个辅助算法背后的主要思想是,任何时刻最强的音轨很可能是一个低谐波:第一,第二或第三。
更新:我删除了版本3.0.0中的后期处理,因此只使用了CNN。

训练与结果

为了训练这个网络,我创建了一个包含3000个MIDI文件的250万个训练样例的数据集,这些样本涵盖了几种不同类型的音乐。 MIDI文件包含歌曲中有关音符和乐器的信息,这使得创建带标签的真实数据变得很容易。 MIDI-to-WAV实用程序创建用于声谱图生成的实际音频数据。 每个训练示例的数据集平均有3个音符。

损失率,音符准确率和帧级精度

在TensorFlow的980 Ti GPU上训练了几天之后,CNN在评估级别(未用于训练的数据)上的准确率为99.200%。 该数值来自将88个输出中的每一个舍入为0或1,并测量与真值相匹配的所有输出的分数。 但是,由于每个训练示例的数据集平均有3个音符和85个非音符,如果CNN从未检测到任何音符,则使用此测量的准确率为96.6%。 我还测量了评估分组中样本的百分比,其中88个舍入输出中的每一个都是正确的。 这个数字达到了60.326%。 整个端到端算法的准确性还取决于CNN输出开始时间检测和过滤的精确度。 对于钢琴,只有评估音符开始和音高,它达到0.8左右的F分数。

上一篇下一篇

猜你喜欢

热点阅读