PARALLEL WAVEGAN笔记目录
来源: 2020 ICASSP
机构: 日本line, 韩国naver
论文地址: https://arxiv.org/abs/1910.11480
源码地址: https://github.com/kan-bayashi/ParallelWaveGAN
一、论文思想
PARALLEL WAVEGAN(以下都简称PWG)是一种非常快速和轻量的声码器模型。
PWG的主要思想就是采用了多重分辨率STFT损失函数和对抗损失结合的损失去训练生成器。
二、网络结构
2.1 整体结构
由下图所示,PWG由一个生成器和一个判别器组成。
2.1.1 生成器损失
整体损失为STFT loss
和adversarial loss
之和
L
G
(
G
,
D
)
=
L
a
u
x
(
G
)
+
λ
a
d
v
L
a
d
v
(
G
,
D
)
L_{G}(G,D)=L_{aux}(G) + \lambda_{adv}L_{adv}(G,D)
LG(G,D)=Laux(G)+λadvLadv(G,D)
gen_loss += self.config["lambda_adv"] * adv_loss
>STFT LOSS
输入预测的波形序列
与真实的波形序列
通过不同的stft loss计算多重分辨率损失。STFT损失分为两个部分,分别为频谱收敛损失sc
和对数幅度谱损失mag
L
s
c
(
x
,
x
^
)
=
∥
∣
S
T
F
T
(
x
)
∣
−
∣
S
T
F
T
(
x
^
)
∣
∥
F
∥
∣
S
T
F
T
(
x
)
∣
∥
F
L_{sc}(x, \widehat{x}) = \frac{\Vert \vert STFT(x)\vert-\vert STFT(\widehat{x})\vert \Vert_F}{\Vert \vert STFT(x)\vert \Vert_F}
Lsc(x,x
)=∥∣STFT(x)∣∥F∥∣STFT(x)∣−∣STFT(x
)∣∥F
L
m
a
g
(
x
,
x
^
)
=
1
N
∥
l
o
g
∣
S
T
F
T
(
X
)
∣
−
l
o
g
∣
S
T
F
T
(
x
^
)
∣
∥
1
L_{mag}(x,\widehat{x})=\frac{1}{N}\Vert log\vert STFT(X)\vert-log\vert STFT(\widehat{x})\vert\Vert_1
Lmag(x,x
)=N1∥log∣STFT(X)∣−log∣STFT(x
)∣∥1
L
s
(
G
)
=
E
z
∼
p
(
z
)
,
x
∼
p
d
a
t
a
[
L
s
c
(
x
,
x
^
)
+
L
m
a
g
(
x
,
x
^
)
]
L_{s}(G) = E_{z\sim p(z),x\sim p_{data}}[L_{sc}(x, \widehat{x}) + L_{mag}(x,\widehat{x})]
Ls(G)=Ez∼p(z),x∼pdata[Lsc(x,x
)+Lmag(x,x
)]
在具体的实现中,将每一个STFT损失
的两个部分分别进行累加,然后除以STFT损失
的个数。
for f in self.stft_losses:
sc_l, mag_l = f(x, y)
sc_loss += sc_l
mag_loss += mag_l
sc_loss /= len(self.stft_losses)
mag_loss /= len(self.stft_losses)
将sc和mag相加就得到了生成损失。
gen_loss += sc_loss + mag_loss
gen_loss *= self.config.get("lambda_aux", 1.0)
>adversarial loss
预测的波形
输入判别器,然后计算MSE损失
L
a
d
v
(
G
,
D
)
=
E
z
∼
N
(
0
,
I
)
[
(
1
−
D
(
G
(
z
)
)
)
2
]
L_{adv}(G,D)=E_{z\sim N(0,I)}[(1-D(G(z)))^{2}]
Ladv(G,D)=Ez∼N(0,I)[(1−D(G(z)))2]
p_ = self.model["discriminator"](y_)#y_为生成器预测的波形
adv_loss = F.mse_loss(p_, p_.new_ones(p_.size()))
self.total_train_loss["train/adversarial_loss"] += adv_loss.item()
2.1.2 判别器损失
判别器输入生成器预测的波形序列
和真实的波形序列
,分别通过均方损失(MSE) 得到discriminator loss
中的real loss
和feak loss
。
L
D
(
G
,
D
)
=
E
x
∼
p
d
a
t
a
[
(
1
−
D
(
X
)
)
2
]
+
E
z
∼
N
(
0
,
I
)
[
(
D
(
G
(
z
)
)
)
2
]
L_{D}(G,D)=E_{x\sim p_{data}}[(1-D(X))^{2}]+E_{z\sim N(0,I)}[(D(G(z)))^{2}]
LD(G,D)=Ex∼pdata[(1−D(X))2]+Ez∼N(0,I)[(D(G(z)))2]
p = self.model["discriminator"](y) #y是真实波形
p_ = self.model["discriminator"](y_.detach()) #y_是预测波形
real_loss = F.mse_loss(p, p.new_ones(p.size()))
fake_loss = F.mse_loss(p_, p_.new_zeros(p_.size()))
dis_loss = real_loss + fake_loss
2.2 生成器结构(Generator)
输入: 随机噪声
和辅助特征(辅助特征为梅尔
,能将随机噪声并行的转换为输出波形)
随机噪声
的size与判别器输入的音频的size一致。
# make input noise signal batch tensor
if self.use_noise_input:
z_batch = torch.randn(y_batch.size()) # (B, 1, T)
return (z_batch, c_batch), y_batch
else:
return (c_batch,), y_batch
网络: 主体采用wavenet
的网络结构,与传统的wavenet不同的地方有——
- 采用非因果卷积代替因果卷积(见6.1)。
- 输入之一为来自高斯分布的随机噪声。
- 模型在训练和推理阶段都是非自回归的。
主体网络由30层dilated residual convolution块组成,以指数方式增加三个dilation cycles。
残差通道数和skip通道数为64个,卷积滤波器大小为3个。
def forward(self, x, c):
# x是噪声, c是梅尔
if c is not None and self.upsample_net is not None:
c = self.upsample_net(c)
assert c.size(-1) == x.size(-1)
# encode to hidden representation
x = self.first_conv(x)
skips = 0
for f in self.conv_layers: #30层
x, h = f(x, c)
skips += h
skips *= math.sqrt(1.0 / len(self.conv_layers))
# apply final layers
x = skips
for f in self.last_conv_layers:
x = f(x)
return x
2.3 判别器结构(Discriminator)
判别器由10层一维的非因果扩展卷积组成,激活函数为leaky ReLU。
stride设置为1,除第一和最后一层外,从1到8的一维卷积应用线性增加的扩张。
三、实现细节
- 生成器先进行训练,生成器训练100000 step后判别器再进行训练。
- 用于生成器训练的梅尔特征,训练前需进行归一化,使其均值和单位方差都为0
- 论文实验用到的数据集为24小时左右语音数据集,
- 将权值归一化应用于所有的卷积层,无论是生成器还是鉴别器。
四、实验结果
4.1 本论文实验结果
本论文对比的基线是ClariNet
MOS评价人群:18个人,20句话
- 训练时间,PWG远小于基线
- 模型小,速度快,MOS接近基线
4.2 VOCBENCH实验对比
来自facebook在2021年发表的关于vocoder整体评价的论文VOCBENCH,从下表可得,PWG在现有的声码器中各项指标都居于前列。
【相关工作】
1 因果卷积
什么任务可以用到因果卷积?
利用卷积学习t时刻之前的输入数据,来预测t+1时刻的输出。
在实现上,1D的casual 主要是通过padding来实现的。在2D的casual 主要是通过mask filter map来实现的。
2 扩展卷积
不增加参数和模型复杂度的条件下,可以指数倍的扩大视觉野,dilated为扩展系数。
可以将dilated看成是kernel稀疏化的一种模式。而stride只是dilated的一种特例。
- 二维扩展卷积
- 一维扩展卷积