语音分离笔记2

笔记是基于2020年李宏毅老师新课:Deep Learning for Human Language Processing整理的。

目录

1 介绍

2 语音分离(Speech Separation)

3 评估(Evaluation)

(1) Signal-to-noise ratio(SNR)

(2) Scale invariant signal-to-distortion ratio (SI-SDR)    SI-SDR = SI-SNR

(3) SI-SDR improvement

4 置换问题(Permutation Issue)

5 Deep Clusterring

Masking

Ideal Binary Mask (IBM)

Deep Clustering

Deep Clustering – Training

6 Permutation Invariant Training(PIT)

7 TasNet – Time-domain Audio Separation Network

Encoder、Decoder

Separator

8 More

Unknown number of speakers

Multiple Microphones多麦克风阵列

Visual Information

Task-oriented Optimization

1 介绍

人类能够在一个拥挤充满噪声的环境中关注某个特定说话者的声音。

语音分离可以分为两类:

1 语音增强(Speech Enhancement):人声与非人声的分离。

2 语音分离(Speech Separation):多个说话者声音的分离。

2 语音分离(Speech Separation)

本篇文章只讨论简单情况:

        1 两个说话者;

        2 单个麦克风;

        3 说话者无关,即用于训练和测试的说话人是完全不同的。

输入输出是等长的,所以没有必要使用Seq2Seq模型(用于处理输入输出变长序列)。

训练数据直接通过单个数据合成得到:

3 评估(Evaluation)

这里的语音分离是有ground truth,因为混合声音是我们自己混合的,所以有原来未混合的声音。我们直接把输入喂给模型,输出的结果与ground truth越接近越好。

下一步便是评估输出的结果\widehat{X}与ground truthX^*的接近程度,下面介绍几种方法。把每个声音信号看做是一个向量,当然这个向量长度比较长,例如一个16kHz的声音信号,其每秒就会有16k个点(一秒的声音信号就要16k维长度的向量来表示)。

(1) Signal-to-noise ratio(SNR)

SNR的公式为:

SNR=10log_{10}\frac{||\widehat{X}||^2}{||E||^2}

E越小,SNR越大。但这种方式有几个问题:

可以看到输入和输出实际上是一样的,只是声音强度(大小)不一样,造成E很大,SNR很小。这样明显不合适。

可以看到黄色的输入变大(音量变大)后发现E变小,而输入声音其实没有变化。

基于上边两个问题,提出来下面一种算法:

(2) Scale invariant signal-to-distortion ratio (SI-SDR)    SI-SDR = SI-SNR

将输出X^*分解为两部分,一部分是X_T与ground truth平行,一部分是X_Eground truth垂直,计算公式如下:

X_E=X^*-X_T

X_T=\frac{X^*\cdot \widehat{X} }{||\widehat{X}||^2}\widehat{X}

那么SI-SDR的公式为:

SI-SDR=10log_{10}\frac{||X_T||^2}{||X_E||^2}

可见输出X^*\widehat{X}越平行,SI-SDR越大。

再看SNR的两个缺陷:

如果用SI-SDR来计算上图,X_E=0,所以SI-SDR值为∞。

当把输出增大k倍后:

SI-SDR=10log_{10}\frac{||X_T||^2}{||X_E||^2}=10log_{10}\frac{||kX_T||^2}{||kX_E||^2}

结果仍然一样。

(3) SI-SDR improvement

在文献中常常使用SI-SDR improvement来表示Speaker Separation的效果。

就是用分离后的SI-SDR减去分离前的SI-SDR,这个差值通常为正的,因为进行分解后距离ground truth更接近,即:

SI-SDR_i=SI-SDR_2 - SI-SDR_1

4 置换问题(Permutation Issue)

如下图所示,我们的ground truth的位置能不能换位置?

如果我们的训练数据和测试数据都只有两个人,那么这样做是没有问题的,只要固定好位置,那么模型自然会把对应的语者放到相应的位置上,但问题是我们训练数据和测试数据中的人数是不固定的,且每个语者是相互独立的。那么这样固定的摆放就会有问题,例如下图:

训练数据蓝男,红女,绿女,黄男,训练第一组数据的时候,模型学习到:男下女上,训练第二组数据的时候,模型又学到:男上女下。这下模型就蒙了,到底哪个是对的呢?

于是就有了下面的解决方法。

5 Deep Clusterring

Masking

如图,声音信号可以看做是一个矩阵。例如一个16kHz的声音信号,其每秒就会有16k个点(一秒的声音信号就要16k维长度的向量来表示)。一段长度的声音信号就是多个向量排在一起,成为矩阵。

显然这个模型的输入输出是有一定关系的,X分解为X_1X_2或者说X_1X_2可以组合成X,可以用Mask的思想来解。

如上图所示,模型的输出不是声音信号了,而是两个大小和X一样的MaskM_1M_2,Mask 可以连续的也可以是binary(0/1)的。

Ideal Binary Mask (IBM)

下面是语音信号的矩阵示意图:

这两个分离的语音信号对应的Mask如下图所示:

Mask的大小和上面语音信号的矩阵是一样大的,Mask的求法也很简单,就是比较蓝色和红色语音矩阵每个位置上的值,谁大谁那个位置就是1,反之就是0。

最后用Mask与合成语音矩阵进行点乘就得到分离后的结果:

上面假设我们是知道合成前的语音矩阵,才算的Mask矩阵,现在我们手上只有合成后的矩阵,我们要训练一个模型把Mask矩阵给学习出来,这个是可以训练的。

Deep Clustering

Deep Clustering 实质是一个Embedding Generation,用Embedding Generation产生上面说的Mask。

左边是声音信号矩阵(大小是D × T ,实际上是spectrogram时谱图,D可以看做frequency,T可以看做是时间步),经过Embedding Generation后,变成一个D × T × A 的立方体。相当于声音信号矩阵每一个点或者说每一个格子grid会变成一个长度为A的向量。

接下来对这些grid对应的向量做K-means Clustering:

K就是说话的人数,两个人就是2,然后分群的结果如上图所示,1代表一个人,2代表另外一个人。然后根据分群结果得到两个Mask。有多少个人就会有产生多少个Mask。

Deep Clustering – Training

上面的那个模型中K-means Clustering是固定的算法,不可训练,可以训练的就是上面那个粉色模块。
来看怎么训练:以下图中第一行第二和第三个grid为例,我们可以从ground truth可以知道,这两个grid是属于不同的语者的(Different Speakers),因此我们希望Embedding Generation 模块生成后面的grid向量时候,这两个向量距离很远,那么经过K-means Clustering后会分到不同的cluster中,最后产生Mask的时候就会得到不同的结果。

同理,我们看下图中第一行第一和第二个grid,我们可以从ground truth可以知道,这两个grid是属于相同的语者的(Same Speakers),因此我们希望Embedding Generation 模块生成后面的grid向量时候,这两个向量距离很近,那么经过K-means Clustering后会分到相同的cluster中,最后产生Mask的时候就会得到相同的结果。

6 Permutation Invariant Training(PIT)

假设我们已经有一个 speaker separation模型,参数为\theta^i,我们可以将其输出的两种排列的Loss都算出来,看哪个小,就认为这个排序适合当前模型:

但是模型需要先有permutation才能构建。所以先随机初始化permutation,然后定模型,然后优化permutation,如此循环:

最后给出了PIT的实验结果:

可以看到最开始SDR有剧烈变化,到后面收敛。因为刚开始Assignment随机的。
下面是PIT和其它方法的比较,黄色是基于Energy的摆放Groud truth的位置,黑色根据语音的向量表示分组(语者的特点)来摆放:

中间红色那个比较有意思,根据上一次蓝色的训练好的PIT模型作为初始,重新开始训练,绿色以此类推。

7 TasNet – Time-domain Audio Separation Network

整个模型的输入和输出是声波,不用抽取acoustic feature(声学特征)。模型分三个部分:Encoder、Decoder、Separator。声波经过Encoder得到一个Feature map;Feature map经过Separator产生两个Mask;这两个Mask分别乘以Feature map得到两个结果;把这两个结果分别通过Decoder就产生两段声音信号。
如果两个speaker是固定的,可以不用PIT,反之要用PIT。

Encoder、Decoder

Encoder如上图所示,相当于一个线性矩阵,输入是一小段声音,16 samples可以看成是16维的vector,通过Encoder后得到512维的vector。Decoder与之相反。

这里强调了:
Encoder得到的结果不一定要为正值,原文中用relu强行掰正效果并无提升;
Encoder和Decoder实际上就是矩阵,这里二者不需要互为reverse的关系,原文实验表明非要有reverse关系效果反而变差。
下图是Encoder的可视化实例,里面不同颜色的深浅代表了声音的频率的高低,人声低频比较多,所以红色多一点。

Separator

Separator吃encoder的512维的输出,然后Separator自己是1维的CNN构架。第一层吃两个vector,吐一个vector;Separator的CNN是dilate的,在第二层会跳一个(d=2)来读取vector;第三层跳三个(d=4)来读取vector;第四层d=8。因此在得到最上面那个vector结果的时候,Separator模型已经看过很多维vector了。因为整个模型输入只有16k的长度声音,比较短,用来做预测不够,现在dilate CNN可以让模型看到更多的输入,再来做预测就会更加准确。

最上面那个vector结果再经过transform和sigmoid得到两个mask,这里加sigmoid的意思是要获取vector结果是属于语者1还是语者2的多一些。这里不需要对两个mask相同维的和为1做限制,这样做是要用softmax,原文实验表明这样效果并不会有提升。
在实作的时候,CNN是很深的,d会到达128:

到d=128完了以后,再从d=1开始再走一波,大约要走3-4波:

这里还用了Depthwise Separable Convolution,以减少模型参数。
有趣的是,最开始Separator用的是LSTM,LSTM对于输入是有要求的,如果输入不是从句子的起始位置开始,那么其效果会不佳,所以下图中绿色线条就显示出波动很大。而CNN就比较稳定。

 下图是混合信号经过TasNet时的矩阵图:

下图展示了相关算法的性能对比:

值得注意的是,虽然通过表可以看出Deep Clustering的性能比TasNet差,但是在下面这种情况下,Deep Clustering却比TasNet表现更好,即使用WSJ0-2英文数据集训练,而测试数据是两个中文说话者的混合。

8 More

Unknown number of speakers

当不知道说话者的数量的时候,可以采取用迭代的方式每次分离一个语者。判断迭代停止的条件是剩下是声音没有杂讯。

Multiple Microphones多麦克风阵列

Visual Information

使用视频信息来加强语音分离,例如图中有两个人,那么就可以帮助模型进行分离。

Task-oriented Optimization

对于不用的应用或者说目标不一样,那么优化的目标也不同,例如如果语音处理的目的是给人听的,越清楚或者是越响亮越好,那么优化的目标是Quality、Intelligibility;如果目标是给机器进行下游任务,那么优化目标是:系统的性能,准确率等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值