总览
单通道的语音降噪有两种方式:
- 直接在一维的时域原始波形上进行操作
- 把一维的时域波形转换为二维的时频谱再进行操作
第二种方式的主流方法是预测一个时频掩膜用来降噪,PHASEN也是采用这种方法。
总的来说,PHASEN是在时频谱(复数域)基础上预测了一个幅度掩膜和一个相位掩膜,然后用输入的时频谱的模(实数域)乘上两个掩膜得到低噪声时频谱,公式如下:
PHASEN的结构
首先整个模型呈双流结构,强度流用来预测幅度掩膜,相位流用来预测相位掩膜。也可以把模型分为三个部分:TSB之前、TSBs、TSB之后。
我个人在理解一个神经网络模型的时候,比较喜欢从模型的输入输出维度入手,所以下面会着重分析模型各部分的维度变化。
模型的输入是复数域上二维的时频谱,所以要先对一维的时域波形进行STFT(短时傅里叶变换)。其次神经网络用到批处理,所以输入的维度应当是[B,2,t_len,f_len]
,这里的第二个维度2是指时频谱的实部和虚部。
TSB之前:
TSB之前的强度流是两个二维卷积层,卷积核分别为(1对应时域)和(7对应时域)。这两个卷积层不改变输入tensor的时域和频域长度,只改变第二个维度的通道数,也就是说这两个卷积层的输出维度都是[B,c_a,t_len,f_len]
,至于c_a
是多少,论文中没有提(毕竟没有开源),参考文末一位大佬复现的模型代码,可以将c_a
设置为24。
TSB之前的相位流也是两个二维卷积层,卷积核分别为(5对应时域)和(25对应时域)。同强度流一样,这两个卷积层也不改变输入tensor的时域和频域长度,只改变第二个维度的通道数,这两个卷积层的输出维度都是[B,c_p,t_len,f_len]
,根据参考可以将c_p
设置为12。
TSBs:
这一部分由三个TSB模块级联而成。
每个TSB内部的强度流由两个FTB和三个二维卷积层构成。FTB以及三个卷积层的输入和输出维度都是[B,c_a,t_len,f_len]
。
TSB内部的相位流比较简单,由两个卷积层构成,其输入输出维度都是[B,c_p,t_len,f_len]
,但需要注意的一点是,相位流的每个卷积层之前需要进行layer normalization。
TSB的最末尾,双流需要交换信息,公式如下:
由于和的第二维度(通道数)不相同,所以信息交换也要包含通道数的变换,这里可以起到通道数变换的有两个地方,一是圆圈代表的element-wise multiplication(在两个维度不相同的张量element-wise multiplication时,会以某种方式复制其中一个张量至与另一个张量维度相同再相乘),二是一个的卷积层。我更倾向于使用卷积层来做通道变换。也就是:
的维度:
[B,c_a,t_len,f_len]
的维度:
[B,c_p,t_len,f_len]
的维度:
[B,c_p,t_len,f_len]
的维度:
[B,c_p,t_len,f_len]
的维度:
[B,c_a,t_len,f_len]
的维度:
[B,c_a,t_len,f_len]
TSB中的FTB
这篇论文提出了两个创造性的点:
- 双流模型的双流之间需要相互交换信息,目的是为了更好的预测相位掩膜。
- FTB??? frequency transformation blocks ),目的是为了捕获频域上的全局相关性。
下面来分析FTB???,其输入输出维度都是:[B,c_a,t_len,f_len]
。
首先要关注的是T-F attention,这里用到了注意力机制,所以维度变换略微复杂。
T-F attention 一开始先用一个的卷积层将输入张量的通道数从c_a
降至c_r
,此处c_r
为5,即输出维度为[B,c_r,t_len,f_len]
,然后进行reshape,结果维度为[B,c_r*f_len,t_len]
。接下来是关键一步,一个卷积核为9的一维卷积,输出维度为[B,c_a,t_len]
,这个输出要和FTB最开始的输入做一次element-wise multiplication,由于维度不匹配,所以会将[B,c_a,t_len]
的张量复制f_len
次再与[B,c_a,t_len,f_len]
的张量相乘。
Element-wise multiplication后的张量维度为[B,c_a,t_len,f_len]
,这个张量要通过一个不要偏置的全连接层,其权重被论文称为frequency transformation matrix (FTM),权重的维度为[f_len,f_len]
,这一步是FTB的核心,输出的维度是[B,c_a,t_len,f_len]
。
全连接的输出又要和FTB最开始的输入进行合并,即将两个[B,c_a,t_len,f_len]
张量合并为一个[B,2*c_a,t_len,f_len]
的张量,最后通过一个的卷积层降低通道数得到维度为
[B,c_a,t_len,f_len]
的输出。
TSBs之后
TSBs之后的强度流首先通过一个的卷积层将[B,c_a,t_len,f_len]
降低至[B,c_r,t_len,f_len]
,此处c_r
等于8。其输出结果要进入一个BiLSTM,BiLSTM需要设置参数 hidden_size
,这里盲猜为300,其输出维度为[B,t_len,hidden_size*2]
。事实上,张量在进入BiLSTM之前,要进行一次reshape,因为BiLSTM对输入张量的shape是有要求的,所以[B,c_r,t_len,f_len]
要先reshape为[B,t_len,c_r*f_len]
,而后通过BiLSTM得到[B,t_len,hidden_size*2]
。之后通过两个600的FC层得到输出[B,t_len,600]
,最后通过一个257的FC层得到,维度为[B,t_len,257]
这里要说明一下,因为论文中有说明在STFT时的FFT长度为512,那么时频谱的维度就应该是[t_len,512/2+1]
,即f_len=257
,而应当具有和时频谱相同的维度,那为什么论文原图中最后的FC层的输出是514通道呢?我只能说可能论文写错了吧......
TSBs之后的相位流经过一个的卷积层将[B,c_p,t_len,f_len]
降低至[B,2,t_len,f_len]
然后进行一下幅度正则化即可。输出的维度即为[B,2,t_len,f_len]
,第二维的2表示复数的实部和虚部。
至此,模型的前向传播过程就分析完了,得到了幅度掩膜和相位掩膜,然后便可用公式得到估计的时频谱
Loss的计算
公式如下:
就是指无噪声的时频谱,是指幂律压缩时频谱(power-law compressed spectrogram),幂律压缩参数为0.3,坦白讲我一个菜鸡并不知道什么是幂律压缩,参考了其他大佬的复现代码之后才知道。这里有个问题,无论是还是,它们都是复数,而幂律压缩是对实数的操作,所以应当先abs()运算,再压缩,即,但这样的话和应该怎么区分呢?参考了大佬的复现后,我这样做:
参考:https://github.com/huyanxin/phasen
https://hiedean.github.io/2020/04/10/PHASEN/