中山网站建设公司哪家好,phpcms 做购物网站,软件网站建设方案,建网站怎么分类文章目录 引言正文鉴别器多周期鉴定器多尺度鉴定器问题 总结 引言
这里翻译了HiFi-GAN这篇论文的具体内容#xff0c;具体链接。这篇文章还是学到了很多东西#xff0c;从整体上说#xff0c;学到了生成对抗网络的构建思路#xff0c;包括生成器和鉴定器。细化到具体实现的… 文章目录 引言正文鉴别器多周期鉴定器多尺度鉴定器问题 总结 引言
这里翻译了HiFi-GAN这篇论文的具体内容具体链接。这篇文章还是学到了很多东西从整体上说学到了生成对抗网络的构建思路包括生成器和鉴定器。细化到具体实现的细节如何 实现对于特定周期的数据处理在细化膨胀卷积是如何实现的这些通过文章仅仅是了解大概的实现原理但是对于代码的实现细节并不是很了解。如果要加深印象还是要结合代码来具体看一下实现的细节。本文主要围绕具体的代码实现细节展开对于相关原理只会简单引用和讲解。因为官方代码使用的是pytorch,所以是通过pytorch展开的。当前这篇主要介绍鉴别器的具体实现在HiFi-GAN中鉴别器分是由周期鉴别器和尺度鉴别器构成当前这篇将就两种鉴别器的原理和功能进行具体讲解。
正文
鉴别器
因为声音信号中的长依赖比较重要常规的做法是通过增加鉴别器的感受野或者增加输入数据的维度来获取这种长领域特征。在HiFi-GAN是采用了增加输入信号的范围采用多尺度鉴定器实现MSD。另外因为声音可以通过短时傅立叶变换拆解成不同的周期的正弦信号叠加HiFi-GAN专门采用了多周期鉴定器见捕捉每一段信号的不同周期特征。
多周期鉴定器
多周期鉴定器是有专门针对不同周期信号的若干子鉴定器构成对于多周期信号是通过对原始的波形信号进行不同间隔进行采样将原来的一维波形数据变成二维信号然后在对其进行卷积。而且每一次卷积都是专门针对某一行数据也就是某一个间隔采样生成的数据。具体可以看如下示意图。 由于数据经过等间隔采样每一行是某一个周期信号然后若干行表示有若干个周期信号然后进行宽度为1,高度为特定长度的周期T/p的二维卷积采样具体如下。每一个颜色都是按照一定间隔进行采样之后的数据然后整个卷积层也是按照一个周期进行生成的。 网络具体结构图下鉴别输入的是真实的波形图和生成波形图然后输出两者相似的概率值进而衡量两者的相似程度具体模型如下就是若干个卷积模块的堆叠。 多周期鉴定器具体实现代码在整个多周期鉴定器是由若干个子周期鉴定器构成所以代码也是分成两个部分。 具体的单个周期鉴定器已经定义过了然后就是最终的总的周期鉴定器的结构就是多个不同周期的子鉴定器具的输出构成的列表
class DiscriminatorP(torch.nn.Module):def __init__(self, period, kernel_size5, stride3, use_spectral_normFalse):# 定义鉴定器的初始化函数super(DiscriminatorP, self).__init__()self.period period # 周期# 是否使用谱归一化norm_f weight_norm if use_spectral_norm False else spectral_normself.convs nn.ModuleList([norm_f(Conv2d(1, 32, (kernel_size, 1), (stride, 1), padding(get_padding(5, 1), 0))),norm_f(Conv2d(32, 128, (kernel_size, 1), (stride, 1), padding(get_padding(5, 1), 0))),norm_f(Conv2d(128, 512, (kernel_size, 1), (stride, 1), padding(get_padding(5, 1), 0))),norm_f(Conv2d(512, 1024, (kernel_size, 1), (stride, 1), padding(get_padding(5, 1), 0))),norm_f(Conv2d(1024, 1024, (kernel_size, 1), 1, padding(2, 0))),])self.conv_post norm_f(Conv2d(1024, 1, (3, 1), 1, padding(1, 0)))def forward(self, x):fmap []# 将原始的音频信号进行分割分割成周期个数的小段转换成二维的矩阵b, c, t x.shape# b是批次大小c是通道数t是时间维度的长度if t % self.period ! 0:# 不能进行整除的情况下复制边缘的值进行填充n_pad self.period - (t % self.period)x F.pad(x, (0, n_pad), reflect)# 更新时间维度的长度t t n_pad# 按照形状将数据进行填充将时间维度分割成段数和每段的长度从一维数据变二维数据x x.view(b, c, t // self.period, self.period)# 将音频信号按照制定的周期进行分割并将每个周期的信号转换为特定的维度for l in self.convs:x l(x)x F.leaky_relu(x, LRELU_SLOPE)fmap.append(x)x self.conv_post(x)fmap.append(x)# 将数据恢复成一维数据x torch.flatten(x, 1, -1)return x, fmap# 多周期鉴定器
class MultiPeriodDiscriminator(torch.nn.Module):def __init__(self):# 定义若干个周期的鉴定器super(MultiPeriodDiscriminator, self).__init__()self.discriminators nn.ModuleList([DiscriminatorP(2),DiscriminatorP(3),DiscriminatorP(5),DiscriminatorP(7),DiscriminatorP(11),])def forward(self, y, y_hat):# 两个参数分别是真实的音频信号y和生成的音频信号y_haty_d_rs [] # 真实音频信号的鉴定器的输出y_d_gs [] # 生成音频信号的鉴定器的输出fmap_rs [] # 真实音频信号的鉴定器的特征图fmap_gs [] # 生成音频信号的鉴定器的特征图for i, d in enumerate(self.discriminators):y_d_r, fmap_r d(y)y_d_g, fmap_g d(y_hat)y_d_rs.append(y_d_r)fmap_rs.append(fmap_r)y_d_gs.append(y_d_g)fmap_gs.append(fmap_g)return y_d_rs, y_d_gs, fmap_rs, fmap_gs多尺度鉴定器
上一节中的多周期鉴定器是将数据进行间隔采样然后卷积处理。并没有处理连续的采样点也就获得不了音频数据的长领域依赖。不同于生成其中使用反卷积进行的上采样这里使用了平均池化缩小数据的范围然后让一个数据浓缩更多的信息 然后进行分别进行特征提取操作。具体见下图。 不同于多周期鉴定器多尺度鉴定器中的子鉴定器是相同的不同的是输入的信号经过的平均池化的倍数不同所以每一个采样点包含的信息维度就不同。具体的单个鉴定器的结构如下 具体代码实现如下首先经过平均池化层然后再经过不同的平均特征提取层
# 多尺度鉴定器的定义
class DiscriminatorS(torch.nn.Module):def __init__(self, use_spectral_normFalse):super(DiscriminatorS, self).__init__()norm_f weight_norm if use_spectral_norm False else spectral_norm# 定义特征提取层self.convs nn.ModuleList([norm_f(Conv1d(1, 128, 15, 1, padding7)),norm_f(Conv1d(128, 128, 41, 2, groups4, padding20)),norm_f(Conv1d(128, 256, 41, 2, groups16, padding20)),norm_f(Conv1d(256, 512, 41, 4, groups16, padding20)),norm_f(Conv1d(512, 1024, 41, 4, groups16, padding20)),norm_f(Conv1d(1024, 1024, 41, 1, groups16, padding20)),norm_f(Conv1d(1024, 1024, 5, 1, padding2)),])self.conv_post norm_f(Conv1d(1024, 1, 3, 1, padding1))def forward(self, x):# 在前向传播的过程中会将数据进行展平fmap []for l in self.convs:x l(x)x F.leaky_relu(x, LRELU_SLOPE)fmap.append(x)x self.conv_post(x)fmap.append(x)x torch.flatten(x, 1, -1)return x, fmapclass MultiScaleDiscriminator(torch.nn.Module):def __init__(self):super(MultiScaleDiscriminator, self).__init__()# 定义三个特征提取模块每一个模块前面都有一个平均池化层self.discriminators nn.ModuleList([DiscriminatorS(use_spectral_normTrue),DiscriminatorS(),DiscriminatorS(),])# 定义两个平均池化层尽量获取全局信息self.meanpools nn.ModuleList([AvgPool1d(4, 2, padding2),AvgPool1d(4, 2, padding2)])def forward(self, y, y_hat):y_d_rs []y_d_gs []fmap_rs []fmap_gs []# 遍历每一个平均池化层然后进行卷积特征提取for i, d in enumerate(self.discriminators):if i ! 0:y self.meanpools[i-1](y)y_hat self.meanpools[i-1](y_hat)y_d_r, fmap_r d(y)y_d_g, fmap_g d(y_hat)y_d_rs.append(y_d_r)fmap_rs.append(fmap_r)y_d_gs.append(y_d_g)fmap_gs.append(fmap_g)return y_d_rs, y_d_gs, fmap_rs, fmap_gs问题
对于音频信号的采样间隔合理吗 音频信号确实是由不同的频率的正弦波构成但是这些音频的频率不同他设置的采样间隔并没有任何根据仅仅是因为他们是质数这种采样周期设定不应该根据对音频信号的分析去确定吗。 谱归一化和常规的归一化有什么不同 权重归一化通过对每一个神经元的权重向量进行归一化加夸模型的收敛速度减少训练时间。谱归一化用于约束神经网络 权重的方法主要用于生成对抗网络。通过将权重矩阵的谱范数即权重矩阵的最大奇异值归一化到1来实现借此方式GAN训练过程中的模式崩溃问题。总结两者的作用不同权重归一化是通过修改网络权重加速收敛和改进有化。谱归一化用于约束GAN判别函数确保满足某些数学性质。
总结
在上一篇博客中已经整理过了生成器的相关代码生成器为了获取更加全局更加细致的信息对数据进行了上采样使得数据尽可能在时间维度上和原始的音频信号相同。到了鉴定器在多周期鉴定器中针对周期的特征提取是考虑了全局信息从全局的角度出发。然后在多尺度鉴定器中又使用了三个池化层然后分别保留不同尺度下特征。对于GAN模型而言最重要的还是生成器然后鉴定器是起到了一个引导作用。鉴定器的考虑的越周到相应的生成器的生成的结果也就越准确。