Speech Separation - NMF methods

最近在看一些语音分离的文章,时间旧了,需要做一些总结。这篇文章先说一种传统而有效的方法,NMF(非负矩阵分解)。

将一个矩阵$\mathbf{V}$分解成两个非负矩阵的乘积形式,这种方法就叫非负矩阵分解,数学表达为:

若$\mathbf{V} \in \mathbf{R}^{F \times T}$,那么$\mathbf{W} \in \mathbf{R}^{F \times D}, \mathbf{H} \in \mathbf{R}^{D\times T}$,其中$D$为分解过程的一个超参数,在一些文献中,$\mathbf{W}$被称为dictionary或者basis functions,$\mathbf{H}$被称为atoms或者activations,这种称呼的原因会在后文中解释。

下面将从三个方面认识这个概念:

  1. 如何得到这种表示
  2. 这种表示的意义何在
  3. 在分离任务中如何应用

NMF

有定义可知,虽然NMF的分解形式不唯一,但是最终得到的结果,需要尽量降低和原始矩阵的误差(否则恢复不过来,失去意义了),定义$D(\mathbf{V}|\mathbf{WH})$表示误差函数,那么我们要求解的问题就表示为:

其中$\mathbf{\Lambda} = \mathbf{WH}$。$\mathcal{D}$不唯一,可以根据任务不同分别定义,如欧式距离,KL散度等等,目前文献中常用$\beta$-divergence统一描述如下

定义$\mathbf{D}_\beta$之后,$\mathbf{W}$,$\mathbf{H}$的求解通过如下迭代的方式进行:

很多时候,我们期望$\mathbf{H}$的具有较高的稀疏程度,因此,$\mathcal{D}$中常常出现关于$\mathbf{H}$的正则项:

其中$|\cdot|_1$表示$L_1$范数。在这种情况下,需要修正矩阵的更新公式,一种简单的处理方式是保持$\mathbf{W}$的更新法则不变,$\mathbf{H}$更新的分子加上正则系数$\mu$:

这种NMF在文献[1]中被称为NMF+S(NMF with Sparsity)而非SNMF(Sparse NMF),后者修正的$\mathbf{W}$的更新公式,且在分离任务中表现优于前者。讨论可以详细参考原始论文,这里不做过多叙述。

NMF历史悠久,实现方便,在MATLAB,sklearn等工具中均有实现,论文[1]也开源了SNMF的MATLAB代码,可以通过链接下载。

在语音信号处理中,NMF通常用于对信号的频谱进行分解,如下,图(2,1)表示原始的频谱,图(1,2)为NMF近似的结果,使用MERL的SNMF工具,参数配置$\beta = 1, \mu = 5, D = 64$。

spectrum_nmf如果用MATLAB中的nnmf方法,在相同的配置下,结果如下:

spectrum_nnmf

可以看出,SNMF估计的$\mathbf{H}$矩阵稀疏性更高。

如何理解

关于表达式:

我们可以换一种写法,即:

$\mathbf{v}_i, \mathbf{h}_i$表示各自矩阵中第$i$列的列向量。对于$\mathbf{v}_i$,有:

上式表明,$t$时刻的频谱,可以表示为$\mathbf{W}$矩阵列向量的线性组合,组合系数为$\mathbf{H}$矩阵的第$t$列。也就是说,NMF会将原始矩阵分解成一组非负的向量组,和对应的一组非负权值。理解这点对于理解NMF在语音分离中的应用比较重要。

另外一点需要提到,一般情况下,设置的$D$值小于$T$值,既然$\mathbf{W}$具有描述原始矩阵的性质,那么可以视其为一组具有非负性的特征向量。我们希望使用少数的特征向量就可以表示原始矩阵,一方面可以减少向量之间的相关性,避免冗余,一方面为了计算,存储的高效性。

另外,有时我们会看到如下定义:

即几组$\mathbf{W}$和$\mathbf{V}$矩阵的乘积和,典型的比如语音分离任务中。这种形式依旧可以规整成上面的原始表示形式,如下:

语音分离:NMF方法

在比较理想的情况下,混合语音信号$\mathbf{S}$由多路信号相加表示:

对$\mathbf{S}_c$做NMF,有:

若$\widetilde{\mathbf{W}} \widetilde{\mathbf{H}}$可被估计,那么,可以下式分离出对应的语音信号:

supervised NMF方法中,分为训练阶段和测试阶段。训练阶段需要单一说话人的监督数据,用来得到说话人的特征集合$\widetilde{\mathbf{W}} $,测试阶段,将其作为初始$\mathbf{W}$进行NMF,过程中只训练$\mathbf{H}$。收敛之后,用上式做说话人分离。

有一点需要注意,就是测试的时候可以将句子分block进行,类似于声学模型中的拼帧。分离的结果只保留中间位置的帧即可。主要是希望利用picth和vocal在时间轴上的局部相似性,获取更好的分离效果。

我进行了Oracle-NMF作实验验证上述流程,之所以称之为Oracle,是因为我直接从$\mathbf{S}_c$中学习speaker的特征矩阵,将他们进行concat作为NMF中的初始化,得到$\mathbf{H}$进行分离,而非从该说话人的其他说话语料中进行。

实验使用MERL实现的SNMF,数据为wsj0的2spk混合数据(用的Deep Clustering的混合程序,生成16k数据),拼左右4帧,帧长和帧移为64ms,16ms。我可视化几个样例结果如下:

online_oracle_snmf_demo1

从语谱图上可以看出,结果还是比较理想的。下面这个两个例子可以看出,在silence段,NMF的表现也不差。

online_oracle_snmf_demo1

online_oracle_snmf_demo1

参考文献[2]中也使用了NMF,不过整体思路非上面所述,后期我会更一版GCC-PHAT,在那里简单讨论一些它的想法。

Reference

[1]. Le Roux J, Weninger F J, Hershey J R. Sparse NMF–half-baked or well done?[J]. Mitsubishi Electric Research Labs (MERL), Cambridge, MA, USA, Tech. Rep., no. TR2015-023, 2015.

[2]. Wood S U N, Rouat J, Dupont S, et al. Blind speech separation and enhancement with GCC-NMF[J]. IEEE/ACM Transactions on Audio, Speech and Language Processing (TASLP), 2017, 25(4): 745-755.