返回介绍

9.5 用梅尔倒频谱系数(MFCC)提升分类效果

发布于 2024-01-30 22:34:09 字数 3114 浏览 0 评论 0 收藏 0

我们已经知道,FFT是正确的方向,但是它还不能确保我们最终能得到一个分类器,能成功地把含有多种体裁乐曲的目录整理成含有单一体裁乐曲的目录。不管怎样,我们都需要一个更高级的分类器。

在这一点上,多做一点研究肯定是明智的。其他人过去可能也碰到过同样的难题,并且已经找到新的解决方法,这对我们也会有所帮助。确实,甚至有一个每年举行的会议,专门研究音乐体裁分类问题。这个会议是由音乐信息检索国际协会 (International Society for Music Information Retrieval,ISMIR)组织的。很明显,自动音乐体裁分类 (Automatic Music Genre Classification,AMGC)是音乐信息检索 (Music Information Retrieval,MIR)的一个子领域。浏览了一些AMGC的论文之后,我们发现那里有很多自动体裁分类方面的工作,可能有所帮助。

有一个技术似乎已经成功应用在很多工作中了,它叫做梅尔倒频谱系数 (Mel Frequency Cepstral Coefficient,MFCC)。梅尔倒频谱 (Mel Frequency Cepstrum,MFC)会对声音的功率谱进行编码。它是通过对信号谱的对数进行傅里叶变换计算得到的。如果你觉得它听起来过于复杂,那么简单记住“cepstrum”这个名字即可,它源自“spectrum”,前4个字母是倒序的。MFC已经成功应用于对话与发言者的识别。让我们看看在我们的例子里是否也能使用它。

幸运的是,其他人曾经和我们有一样的需求,并且已经发布了一个实现,叫做Talkbox SciKit。我们可以从https://pypi.python.org/pypi/scikits.talkbox 安装。之后,我们可以调用mfcc() 函数,它会计算出MFC系数,如下所示:

>>>from scikits.talkbox.features import mfcc >>>sample_rate, X = scipy.io.wavfile.read(fn) >>>ceps, mspec, spec = mfcc(X) >>> print(ceps.shape) (4135, 13)

用于分类的数据存储在ceps 里,它对歌曲(文件名为fn)的4135帧中的每一帧都有13个系数(mfcc() 函数里nceps 参数的默认值)。如果使用所有数据,将会压垮我们的分类器。相反,我们可以取每个系数在所有帧中的平均值。假设每首歌曲的开始和结束部分,和中间部分相比跟体裁相关的可能性很小,我们可以忽略前后10%的内容。

x = np.mean(ceps[int(num_ceps*1/10):int(num_ceps*9/10)], axis=0)

确实,我们要使用的评比数据集,只包含每首歌曲的前30秒,所以我们无需把后10%的内容切掉。不过我们仍然会做这个处理,这样可以使我们的代码也能在其他的数据集上工作,而其他数据集很可能并没有做这样的截断。

与之前的FFT工作类似,我们肯定还会把生成的MFCC特征缓存起来,并在每次训练分类器的时候直接读取,而不用再重新生成。

这就得到了如下代码:

def write_ceps(ceps, fn): base_fn, ext = os.path.splitext(fn) data_fn = base_fn + ".ceps" np.save(data_fn, ceps) print("Written %s" % data_fn) def create_ceps(fn): sample_rate, X = scipy.io.wavfile.read(fn) ceps, mspec, spec = mfcc(X) write_ceps(ceps, fn) def read_ceps(genre_list, base_dir=GENRE_DIR): X, Y = [], [] for label, genre in enumerate(genre_list): for fn in glob.glob(os.path.join(base_dir, genre, "*.ceps.npy")): ceps = np.load(fn) num_ceps = len(ceps) X.append(np.mean( ceps[int(num_ceps*1/10):int(num_ceps*9/10)], axis=0)) y.append(label) return np.array(X), np.array(y)

我们使用一个每首歌曲只有13个特征的分类器,得到了如下很有希望的结果,如下图所示:

所有类别的分类效果都提升了。爵士和金属类别甚至几乎达到了1.0的AUC。确实,下图中的混淆矩阵现在看起来也好了许多。我们可以很清楚地看到,斜线部分显示出,分类器能够在多数情况下把体裁分正确。这个分类器对于解决我们最初的任务十分有用。

如果我们想要在这个结果的基础上继续提升,混淆矩阵可以快速告诉我们需要专注于哪里:非对角线区域的非白色格子。例如,我们有一个深色格子,在那里把爵士乐曲错误地分类成摇滚乐曲的可能性很大。要想修正这个问题,我们可能需要更深入研究这些乐曲,抽取出诸如节拍模式,以及类似的与具体体裁相关的性质。同样,在浏览ISMIR论文的时候,你可能也读到了关于Auditory Filterbank Temporal EnvelopeAFTE )的特征。它在某些情况下似乎比MFCC特征更好。也许我们也应该试一下这些特征?

一个好消息是,有了ROC曲线和混淆矩阵,我们可以自由地把其他专业知识(以特征提取器形式)引入进来,而不需要完全理解它们的内部工作原理。评估工具总能告诉我们方向是否正确,是否需要改变方向。当然,作为一个爱好学习的机器学习初学者,我们总有一种朦胧的感觉,那就是一个令人激动的算法正埋藏在特征提取器的黑盒子中,只是等待我们去理解它而已。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文