实时音频编解码之十九 基于AI的语音编码(LPCNet)

本文谢绝任何形式转载,谢谢。
自2012年Opus编码器推出以来经过近10年,2020年的新冠大流行使得实时音视频会议和虚拟增强会议需求进一步增加,Opus是这类场景中非常优秀的音频编码器,但AI技术可以进一步提升音视频效果。

Satin

Satin是微软于2021年2月官宣的一款基于AI的语音编码器,其目标是替代Silk编码器,Silk是Skype使用的语音编码器,Opus中LPC部分也是基于Silk编码器,Satin的特性如下:

从6kbps开始可以支持超带宽语音

从17kbps开始可以支持全带宽语音

更高的比特率可以带来更好的编码质量

即使在高丢包率的情况下音频质量依然很高

更好的冗余算法,在突发丢失情况下提供更好的保护
请添加图片描述
Satin已经在微软Teams和Skype的双向通话中使用,显然未来是会扩展到多人通话中。Satin的目标是替换掉Silk/Opus编码器。

为了在6kbps码率下达到超带宽,Satin根据对语音产生、建模和心理声学的深入理解来提取和编码信号的稀疏表示,在进一步降低所需比特率时,Satin仅对较低频带进行编码和传输某些参数,在解码侧,Satin使用深度学习网络从接收到的低频带参数以及附加信息估计高频带参数,这种方法虽然使用超低比特率编码超带宽信号,但是计算复杂度大大提高。分析输入语音信号以提取低维表示需要大量计算,在深度神经网络上进行实时推理会增加更多的复杂性。
请添加图片描述
和其他编码器相比,Satin独立编码各个包,所以丢失一个包并不会影响后续包的编解码质量,由于Satin能够以6kbps的低速率提供出色的音频,因此可以灵活使用增加比特率来添加冗余和前向纠错,以便快速恢复丢包。

LPCNet

WaveNet是DeepMind 2016提出的方法,其不对语音做任何先验假设,用神经网络从数据中学习分布,其不直接预测语音样本值,而是通过一个采样过程来生成语音,其语音质量比之前的所有基于参数声码器多要好,但是其生成语音太慢,主要是因为为了或得足够大的感受野使得卷积层太深太复杂,这使得计算量有几十GFLOPS,因此DeepMind和GoogleBrain提出了WaveRNN,用RNN提示计算效率并采用权重稀疏化方法进一步降低计算量,但其计算量仍然需要10GFLOPS,相对于不需要1GFLOPS的基于信号处理的编码器而言,这仍然高了近两个数量级。自然而然将信号处理和深度学习方法结合以达到实时计算和性能提升的目的,LPCNet正式在这一想法下诞生的编码器。

WaveRNN主要由一层GRU、两层全连接以及softmax激励层组成。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-20DSLn3N-1652586220899)(https://github.com/fatchord/WaveRNN/blob/master/assets/wavernn_alt_model_hrz2.pngraw=true)] 摘自https://github.com/fatchord/WaveRNN

LPCNet是基于WaveRNN的低复杂度语音编码器,通过将线性预测技(对声道建模)和WaveRNN相结合以达到低复杂度语音合成和压缩,其计算复杂度在3GFLOPS以下,许多带支持SIMD指令低功耗移动端处理器(手机和嵌入式系统)都可以支持这一计算复杂度,Jean-Marc Valin是LPCNet和Opus编码器的主要贡献者之一,因而LPCNet信号处理部分使用Opus部分实现方法,开源代码中包含了推理和基于Keras的训练代码。

线性预测是一种简单高效的谱包络建模方法,但是激励信号却没有如此简单高效的方法,LPCNet的谱包络建模还是使用线性预测方法实现,谱特性平坦的激励使用神经网络建模。下图是LPCNet的基本结构,它包括一个工作频率为16 kHz的采样率网络和一个处理10 ms帧(160个采样)的帧率网络,帧率网络为采样率网络提供一个条件向量输入,这个条件向量一帧计算一次,并在该帧时间内保持不变。提取的特征是18个Bark倒谱系数和两个基频参数(周期和相关性),对于低比特率编码应用场景,接收端收到的倒谱系数和基频参数通常经过量化压缩,网络的左侧部分(黄色)每帧计算一次,其结果在整个帧中对于右侧的采样率网络保持不变,compute prediction 模块基于t时刻之前的采样点根据线性预测方法估计的当前采样点值,对输出的采样点 s t s_t st使用去加重滤波后输出。
请添加图片描述

请添加图片描述
图 LPCNet框架结构

条件参数

模型使用交叉熵准则训练,用softmax计算预测值误差 e t e_t et分布和真实值分布的交叉熵,测试时仅包含特征,训练时输入还包括利用利用BFCC特征按LPC合成预测值 p t p_t pt,原始语音 s t 1 s_{t-1} st1和 e t 1 e_{t-1} et1,输出参考为 e t e_t et, e t = s t p t e_t=s_t-p_t et=stpt即是输入(延迟)也是输出参考。 p t p_t pt是从特征BFCC计算得到而非直接从原始语音 s t s_t st计算得到,这是因为解码端接收到的特征只有BFCC和pitch以及pitch corr,通过从BFCC预测 p t p_t pt以减少训练和测试/部署推理之间的不匹配问题,此外,因为训练时使用了原始语音作为label,计算模型损失,但是在测试时只有特征(在部署时接收到的只有特征),因而对原始语音加了不同均方误差的噪声以减弱预测误差累积,为了增加训练数据多样性,使用一些随机的二阶IIR滤波器(零极点均在单位圆内的最小相位系统),这些滤波器的增益是随机的,滤波器的传输函数为:
H ( z ) = 1 + b 1 z 1 + b 2 z 2 1 + a 1 z 1 + a 2 z 2 H(z) = rac{1+b_1z^{-1} + b_2z{-2}}{1+a_1z{-1}+a_2z^{-2}} H(z)=1+a1z1+a2z21+b1z1+b2z2
,其中 a 1 , a 2 , b 1 , b 2 a_1, a_2, b_1, b_2 a1,a2,b1,b2均服从ext{U}(0, 0.75)分布,这可以确保零极点位于单位圆内,进而保证滤波器的稳定性,训练时将pitch处理成64维embedding,然后接在原来的特征之后,构成102维特征,因此第一个卷积层使用128个filter,第二个卷积层使用102个filter,以便和输入的102维一致,网络输入的 μ l a w mu-law μlaw值先处理成128维embedding,输出分布直接与u-law对应,8bit对应于126维的分布,输出层大小为256,条件向量 f mathbf {f} f也是也是128维。由于LPC是基于编码的量化BFCC参数计算得到的,因而和真实语音计算的LPC并不一致,但是从模型最终结果看影响很小,神经网络具有可以弥补这一差异。

左侧帧率模块用于给右侧采样率模块提供条件参数,首先10ms的帧提取的20个输入特征参数通过两层卷积,由于卷积核大小为1x3,因而具有5帧的感受野(两帧向前,两帧向后),两层卷积之后的结果和输入特征相加之后输入两层全连接层,全连接层最终输出 f mathbf f f为128维的帧率特征向量,这一帧率特征向量在10ms帧保持不变。

预加重和量化

一些语言合成模型,如WaveNet使用8比特μ-law量化以便最终输出限制在256个可能值。8比特μ-law量化考虑了语音采样值主要集中在0附近幅度较小的地方这一统计分布特征,幅值越大概率越小,因此给幅值小的区间更多比特以减小量化误差,幅值大的区间用较少的比特,以达到整体较优,导出对数特性的压缩曲线。由于语音信号能量通常集中在低频段,μ-law高频段的白量化噪声通常听觉上式可以感知到的。为了避免这一问题,一些方法如WaveRNN将输出扩展为16比特,而LPCNet方法采用的是对训练数据使用预加重滤波 H ( z ) = 1 α z 1 , α = 0.85 H(z)=1-alpha z^{-1}, alpha =0.85 H(z)=1αz1,α=0.85,先提升一下高频能力,合成语音是再用去加重滤波 D ( z ) = 1 1 α z 1 D(z)= rac{1}{1-alpha z^{-1}} D(z)=1αz11压一压高频段能量后再输出,这使得奈奎斯特频率点的噪声减少16dB,这极大减少了高频带可感知的噪声。
线性预测

语音采样率较高,相邻采样点之间有很强的相关性,可以利用自回归对采样过程建模,即当前采样点依赖于若干先前点,误差可建模为高斯白噪声。为了减少计算复杂度,声道响应使用全极点线性滤波器建模,设t时刻的采样点为 s t s_t st,则线性预测的输出为:
p t = ∑ k = 1 P a k s t k p_t = sum limits_{k=1}^Pa_ks_{t-k} pt=k=1∑Pakstk
其中P为线性预测的阶数, a k a_k ak和前文LPC系数意义一样,首先将18个Bark频带谱转为线性频率谱密度(PSD),然后使用逆FFT将PSD转为自相关,再使用Levinson-Durbin方法计算LPC系数,从Brak频带谱计算LPC系数的原因是这样可以不编码传输LPC系数,使得传输带宽需求进一步下降,尽管低分辨的Bark倒谱使得解码侧计算LPC系数不够准确,但是采样率网络对其有部分补偿效果。

采样率网络的LPC输入有助于提升网络效率和预测准确性,采样率网络也可以用于预测激励(预测残差),这可以减少μ-law量化噪声,这是因为激励通常经过归一化处理,因而其幅度比预加重信号小。

输出层

为了在不显著增加前一层大小的情况下更容易计算输出概率,将两个全连接层(图中DualFC)输出对应点权重相加,
d u a l _ f c ( x ) = a 1 ° tanh ( W 1 x ) + a 2 ° tanh ( W 2 x ) dual_fc(mathbf x) = mathbf a_1 circ anh(mathbf W_1 mathbf x) + mathbf a_2 circ anh(mathbf W_2 mathbf x) dual_fc(x)=a1°tanh(W1x)+a2°tanh(W2x)
其中 W 1 mathbf W_1 W1和 W 2 mathbf W_2 W2是权重矩阵, a 1 mathbf a_1 a1和 a 2 mathbf a_2 a2是权重向量,DualFC输出使用softmax激活方法计算可能激励 e t e_t et的概率 P ( e t ) P(e_t) P(et),

稀疏矩阵

为了保持低复杂度,对于最大的GRUA使用稀疏矩阵方法,并未使用逐个元素稀疏方法,而是基于块的稀疏方法,训练过程中逐步将最小幅度块强制为零,直到达到期望的稀疏率,LPCNet作者发现按16x1分块模型效果最好且容易向量化结果。

softmax分布

p ( x ) = ∏ t = 1 T p ( x t ∣ x 1 , , x t 1 ) p(mathbf x) = prod limits_{t=1}^Tp(x_t|x_1,cdots,x_{t-1}) p(x)=t=1∏Tp(xt∣x1,xt1)
16比特语音的采样点取值范围是[-32768,32767],softmax直接输出采样点维度需要65536,这样的计算量太多了,因而使用μlaw映射以减少softmax大小,将[-32768,32767]映射为[0,255],首先对采样点归一化为[-1,1],然后改区间值通过μlaw映射为[0,255],μlaw的映射公式如下:
f ( x t ) = s i g n ( x t ) ln ( 1 + μ ∣ x t ∣ ) ln ( 1 + μ ) , μ = 255 f(x_t)=sign(x_t) rac{ln(1+mu|x_t|)}{ln(1+mu)},mu=255 f(xt)=sign(xt)ln(1+μ)ln(1+μ∣xt∣),μ=255
之所以采用μlaw映射是因为相对于较大值,较小值对听觉的敏感度影响较大。
输入特征处理

输入特征使用20维,18个BFCC Bark-Frequency Cepstral Coefficients, 2 pitch parameter(pitch,correlation),BFCC和语音识别中常用的MFCC特征类似,都是利用人耳的听觉特性,Bark 谱是根据人耳对响度感知灵敏度确定的频带划分方法,而Mel 谱是根据人耳对音高感知灵敏度确定的频带划分方法,两者最终频带划分类似,都是低频段频带窄(高分辨),高频段频带宽(低分辨),和线性频率对应关系近似对数关系,LPCNet选择了Opus编码器的频带划分方法,之所以这么选择是因为Brak频带低频带宽太窄,会导致参数估计不准,由于LPCNet输入信号采样率为16kHz,因而有效频带宽度为8kHz,这样只剩下18个频带。LPCNet输入是经过μlaw映射的压缩(embedding)矩阵E,而不是直接输入缩放的原始PCM数据,embedding方法将每个μ-law值映射为一个向量,因为embedding特征是直接输入GRU的,因而可以通过预先将其和GRU的非循环权重 U ( ) U() U()相乘以降低复杂度。

  • 16 LPC ( LPC 从 BFCC 计算获得,首先 BFCC 通过 IDCT 然后 EXP 恢复成 BFE, 然后通过线性插值得到线性频谱(功率谱),然后 IFFT 得到自相关函数,最后通过 Levinson Durbin 算法计算 LPC )

  • pitch 参数通过一个基于互相关函数的 open-loop search 获得

  • BFCC 通过如下过程获得(和 MFCC 提取非常一致,二者仅在频带划分有差异)

    • 波形数据通过 FFT 到频谱

    • 频谱按 Bark 频率分成 18 个频带,计算每个频带内的能量(通过三角窗加权,也可以理解为三角滤波获取频谱包络)

    • Log 压缩动态范围得到倒谱

    • DCT 去相关得到最终的 BFCC
      概率采样分布

直接对输出采样分布有时会导致过大的噪声,引入一个常数 c 来控制采样过程,总体思路是给浊音的采样更多确定性,当当前帧为浊音有 pitch 时,给概率大的候选更大的权重,相当于冷却和降低随机性,可以根据基频相关性减弱采样过程的影响,因而调节因子可以采用下式,
c = 1 + max ( 0 , 1.5 g p 0.5 ) c = 1 + max(0, 1.5g_p-0.5) c=1+max(0,1.5gp0.5)
其中 g p , 0 < g p < 1 g_p, 0 lt g_p lt 1 gp,0<gp<1是基频相关性。
在得到调节因子之后,从输出采样分布减去一个常量以确保任何在常量门限 T T T以下的概率为零,这可以阻止较低概率带来的脉冲噪声,修改后的概率分布为:
P ′ ( e t ) = R ( max [ R ( [ P ( e t ) ] c ) T , 0 ] ) P{'}(e_t)=mathcal{R}(max[mathcal{R}([P(e_t)]c)-T,0]) P′(et)=R(max[R([P(et)]c)T,0])
R mathcal{R} R操作符将采样分布概率重新规范化为单位一,实际采用 T = 0.002 T=0.002 T=0.002是脉冲噪声和合成语音自然度二者的折中, T = 0.002 砍掉概率太小的候选。

训练噪声注入

由于前向推理时生成的采样点和训练时使用的采样点有差异,这导致部署推理和训练是网络运行的条件是不一样的,这种错配会放大合成语音失真,这可以通过对训练数据加噪声的方法抑制错配带来的失真。输入语音加噪后,线性预测和激励都基于加噪的语音重新计算,使得网络输入和参考激励都同步引入噪声效果更好。

线性预测方法使得注入噪声的细节尤其重要,按下图注入噪声,网络可以有效的最小化信号误差,为了使得噪声和信号幅度成比例,直接对μ-law域信号加噪。
请添加图片描述
图 训练过程注入噪声

图中 Q Q Q是μ-law量化, Q 1 Q^{-1} Q1是从μ-law转为线性域,预测滤波器 P ( z ) = ∑ k = 1 p a k z k P(z)=sum limits_{k=1}pa_kz{-k} P(z)=k=1∑pakzk对输入带噪信号滤波,未量化的纯净语音和滤波后的带噪信号之差作为激励信号,μ-law域所加的噪声值均匀分布于区间[-3,3]。

Embedding 以及计算简化

这部分主要是为了加速合成语音,是在测试阶段,权重都训练好固定了。那么计算最大开销就在 sample rate 的 GRU 环节。作者的思路是对非循环部分都预先计算好。显然 μ-law 的输入 ![s{t-1}, p_t, e{t-1}]都只有 256 种可能,因此作者先将 μ-law Embedding 转成 128 维,然后把 256 个可能 embeding 和 GRU 中相关 非循环 矩阵相乘结果存储,这样合成时就可以通过查找表完成该部分计算。同时条件向量 f 也是一帧仅需计算一次,因此在帧内也可以把 f 和 GRU 里对应矩阵相乘结果存储复用。

合成语音质量

作者提到 LPCNet 可以应用于 speaker-dependentspeaker-independent 场景,作者挑战了更难的 speaker-independent 语音合成。这里 speaker-independent 具体含义我不太清楚。 不过根据本人实验,单说话人效果非常好;男女混合多说话人训练的模型倾向于平均模型,合成的语音有些含糊不清。另外一个有趣的实验现象是用一个女生的语音训练了单说话人模型,用另外一个女生的数据测试也能合成非常自然的语音,不确定是否是偶然现象。
作者的实验中训练语料使用了 4 小时 NTT Multi-Lingual Speech Database for Telephonometry,评价准则采用 MUSHRA-like listening test。 MUSHRA-like Listening Test: 两男两女说的 8 句话,分别让 100 个人听然后打分,分数越高说明语音质量越好,满分为 100。黑线为原始 PCM16 的 Reference, 绿线为 μ-law 的 Reference,可见 μ-law 压缩后语音质量几乎没有下降。
红线和蓝线分别是 LPCNet 和 WaveRNN 的合成语音,横轴是 G R U A {GRU}_A GRUA(的等价神经元数 ,越大模型越复杂。对比测试了三个不同大小的网络,分别对应 G R U A {GRU}_A GRUA(的神经元数 N A = 192 , 384 , 640 , N_A =192, 384, 640, NA=192,384,640, 对应等价神经元数为$N_A’ = 61, 122, 203, $同时 WaveRNN 测试了同等复杂度的网络。可见同等复杂度下 LPCNet 比 WaveRNN 合成语音质量更高。
请添加图片描述

构建训练数据

滤波

为了增加网络对不同频率信号的鲁棒性,使用两个二阶滤波器对输入信号进行滤波,采用SILK滤波器,SILK滤波器的传递函数表达式为:
H ( z ) = b 0 + b 1 z 1 + b 2 z 2 a 0 + a 1 z 1 + a 2 z 2 H(z)= rac{b_0+b_1z{-1}+b_2z{-2}}{a_0+a_1z{-1}+a_2z{-2}} H(z)=a0+a1z1+a2z2b0+b1z1+b2z2
在代码实现中 a 0 = 1 , a 1 = 1.99599 , a 2 = 0.99600 , b 0 = 1 , b 1 = 2 , b 2 = 1 a_0=1, a_1=-1.99599, a_2=0.99600, b_0=1, b_1=-2, b_2=1 a0=1,a1=1.99599,a2=0.99600,b0=1,b1=2,b2=1,采用了转置直接形式二实现。第二个二阶滤波器的系数均匀分布在 [ 3 8 , 3 8 ] [- rac{3}{8}, rac{3}{8}] [83,83],对幅度的鲁棒性通过可变增益实现,对噪声的鲁棒性通过添加随机噪声实现。

 //dump_data.c文件
 46 //这是Transposed direct forms实现方式
 47 //
 48 static void biquad(float *y, float mem[2], const float *x, const float *b, const float *a, int N) {
 49   int i;
 50   for (i=0;i<N;i++) {
 51     float xi, yi;
 52     xi = x[i];
 53     yi = x[i] + mem[0];
 54     mem[0] = mem[1] + (b[0]*(double)xi - a[0]*(double)yi);
 55     mem[1] = (b[1]*(double)xi - a[1]*(double)yi);
 56     y[i] = yi;
 57   }
 58 }
 
252     biquad(x, mem_hp_x, x, b_hp, a_hp, FRAME_SIZE);
253     biquad(x, mem_resp_x, x, b_sig, a_sig, FRAME_SIZE);

其滤波器的响应特性如下:
请添加图片描述

预加重

H ( z ) = 1 α z 1 H(z) = 1 -alpha z^{-1} H(z)=1αz1
α = 0.85 alpha=0.85 α=0.85,其滤波器的幅频特性如下:
请添加图片描述

增加增益

计算增益,范围为[0.1, 8.912509],增加增益的使用了新旧增益平滑输入信号,增加网络的对幅度的鲁棒性。

243       speech_gain = pow(10., (-20+(rand()%40))/20.);
244       if (rand()%20==0) speech_gain *= .01;
245       if (rand()%100==0) speech_gain = 0;

255     for (i=0;i<FRAME_SIZE;i++) {
256       float g;
257       float f = (float)i/FRAME_SIZE;
258       g = f*speech_gain + (1-f)*old_speech_gain;
259       x[i] *= g;
260     }
261   //对于16kHz采样率,TRAINING_OFFSET=80,pcm是长度为160的数组,其中前80个点是上一帧数据,后80个点是当前帧数据,其目的是使得特征位于帧中心
263     for (i=0;i<FRAME_SIZE-TRAINING_OFFSET;i++) pcm[i+TRAINING_OFFSET] = float2short(x[i]);
//计算当前帧的特征,包括子带能量,见下一小节
264     compute_frame_features(st, x);
//计算噪声,在训练过程中,因为模型计算的输出会作为下一个点输入网络,当不够精确时,为了防止模型对误差产生累积,这里对label信号添加噪声,以增加网络的抗干扰性。
267     if (fpcm) {
268         compute_noise(&noisebuf[st->pcount*FRAME_SIZE], noise_std);
269     }
271     if (!quantize) {
  //计算pitch和帧间互相关,并将最终特征存入ffeat指向的文件中
272       process_single_frame(st, ffeat);
  //将带噪声语音信号写入文件,见下一节
273       if (fpcm) write_audio(st, pcm, &noisebuf[st->pcount*FRAME_SIZE], fpcm, 1);
274     }

特征计算

特征计算是针对频域信号计算,首先计算加窗FFT的Bark子带能量。子带的划分方法如下:

static const opus_int16 eband5ms[] = {
/*0  200 400 600 800  1k 1.2 1.4 1.6  2k 2.4 2.8 3.2  4k 4.8 5.6 6.8  8k*/
  0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 20, 24, 28, 34, 40
};

//lpcnet_enc.c
496 void compute_frame_features(LPCNetEncState *st, const float *in) {
509   frame_analysis(st, X, Ex, in);
510   logMax = -2;
511   follow = -2;
 //对Bark子带能量约束,为了防止相邻子带能量出现过小
512   for (i=0;i<NB_BANDS;i++) {
513     Ly[i] = log10(1e-2+Ex[i]);
514     Ly[i] = MAX16(logMax-8, MAX16(follow-2.5, Ly[i]));
515     logMax = MAX16(logMax, Ly[i]);
516     follow = MAX16(follow-2.5, Ly[i]);
517     E += Ex[i];
518   }
//对子带能量进行DCT变换,这是因为  
519   dct(st->features[st->pcount], Ly);
520   st->features[st->pcount][0] -= 4;
  //通过子带能量计算LPC系数,
521   lpc_from_cepstrum(st->lpc, st->features[st->pcount]);
  
536   /*基于半帧(对于16kHz采样率,10ms帧长,这里的FRAME_SIZE=160)的互相关 */
537   for (sub=0;sub<2;sub++) {
538     int off = sub*FRAME_SIZE/2;
539     celt_pitch_xcorr(&st->exc_buf[PITCH_MAX_PERIOD+off], st->exc_buf+off, xcorr, FRAME_SIZE/2, PITCH_MAX_PERIOD);
  //能量计算
540     ener0 = celt_inner_prod(&st->exc_buf[PITCH_MAX_PERIOD+off], &st->exc_buf[PITCH_MAX_PERIOD+off], FRAME_SIZE/2);
541     st->frame_weight[2+2*st->pcount+sub] = ener0;
543     for (i=0;i<PITCH_MAX_PERIOD;i++) {
  //加1是为了防止545行分母能量等于0.
544       ener = (1 + ener0 + celt_inner_prod(&st->exc_buf[i+off], &st->exc_buf[i+off], FRAME_SIZE/2));
  //基于能量归一化互相关
545       st->xc[2+2*st->pcount+sub][i] = 2*xcorr[i] / ener;
546     }

写入带噪语音

 86 void write_audio(LPCNetEncState *st, const short *pcm, const int *noise, FILE *file, int nframes) {
 87   int i, k;
 88   for (k=0;k<nframes;k++) {
 89   short data[2*FRAME_SIZE];
 90   for (i=0;i<FRAME_SIZE;i++) {
 91     float p=0;
 92     float e;
 93     int j;
   //使用LPC系数滤波预测当前值
 94     for (j=0;j<LPC_ORDER;j++) p -= st->features[k][NB_BANDS+2+j]*st->sig_mem[j];
   //将真实pcm值和预测值之差转换到ulaw域,以压缩模型size和计算复杂度
 95     e = lin2ulaw(pcm[k*FRAME_SIZE+i] - p);
 96     /* 输入信号 */
 97     data[2*i] = float2short(st->sig_mem[0]);
 98     /* 输出信号,因写入同一个文件,因而奇偶数索引对应输入和输出*/
 99     data[2*i+1] = pcm[k*FRAME_SIZE+i];
100     /* 对误差信号加噪声,在训练集增加噪声以增加模型鲁棒性*/
101     e += noise[k*FRAME_SIZE+i];
102     e = IMIN(255, IMAX(0, e));
103
104     RNN_MOVE(&st->sig_mem[1], &st->sig_mem[0], LPC_ORDER-1);
   //将误差信号的噪声和LPC预测值相加,得到带噪和量化影响后的信号
105     st->sig_mem[0] = p + ulaw2lin(e);
106     st->exc_mem = e;
107   }
   //将输入写入文件
108   fwrite(data, 4*FRAME_SIZE, 1, file);
109   }
110 }

训练

过拟合问题

在训练过程中,模型在验证集上准确性在某个epoch时可能达到最大值,在这之后验证集上的准确性可能下降,这可能就是在训练集上出现了过拟合的表现,处理过拟合是必要的,过拟合的极端是模型在训练集上为训练特征(feature)和训练正确结果(label)之间做了一一映射,这一映射关系使得模型失去了泛化能力。为了增加模型的泛华能力,可以从训练数据增强、模型搭建、训练过程等方面入手,数据增强方面可以增加噪声、变换等,模型搭建方面可以先使用简单的全连接层,然后逐渐增加层数、各层类型以及各层神经元的数量,并比较不同配置下验证集上的准确性,训练过程中对数据进行shuffle、对神经元参数正则化、训练数据dropout,以及Batch normalization、learning rate改变等操作。

Scalars 面板显示了loss和metrics随着每个epoch变化情况,该面板同样跟踪了学习速度以及学习率等标量;

Graphs面板可视化了模型结构

Distributions 和 Histograms 显示了张量随时间变化的情况,这可以观察权重以及偏移是否随着训练的进行按照期望的方向在变化;

LPCNet变种

LPCNet的子带之间是没有相关性的,而实际中同一段语音的子带之间是有相关性的,基于LPCNet的子带线性预测方法提出了一个基于子带自回归模型学习子带之间的联合分布关系。基于人类听觉感知系统对基带谐波语音分量的敏感度,为低频子带分配了更多的计算资源以合成相位和幅度更为自然的语音。

线性预测方法将语音分为谱包络和激励两部分,预测激励分布比直接预测语音要简单很多,基于源-滤波模型,一些神经网络声码器可以用更小的模型得到更自然的语音,如LPCNet、LP-WaveNet等,iLPCNet提供了激励和谱建模的闭环解决方案,这提高了16比特PCM的合成质量。

多速率信号处理方法将语音分解到多个子带同样可以提高神经网络推理效率,子带生成语音的一些优点如下:

1.通过降采样之后每个子带采样点数变少,这减少了复杂度提升了效率;

2.子带分解有助于根据人类听觉灵敏度区分处理不同的子带;

分解之后的子带之间是有相关性的,用好这一相关性有助于提升合成语音质量,首先分析滤波器组将语音分为四个子带,根据子带间关系对子带序的列联合分布用自回归模型建模,激励信号使用基带的LP方法获取,这压缩了输入维度同时也考虑了听觉感知特性,提取的声学特征作为网络条件,训练和推理都是同时生成子带采样点,生成的子带采样点再通过合成滤波器组合成。

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页
评论

打赏作者

普通网友

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值