论文代码学习—HiFi-GAN(2)——鉴别器discriminator代码
文章目录
- 引言
- 正文
- 鉴别器
- 多周期鉴定器
- 多尺度鉴定器
- 问题
- 总结
引言
- 这里翻译了HiFi-GAN这篇论文的具体内容,具体链接。
- 这篇文章还是学到了很多东西,从整体上说,学到了生成对抗网络的构建思路,包括生成器和鉴定器。细化到具体实现的细节,如何 实现对于特定周期的数据处理?在细化,膨胀卷积是如何实现的?这些通过文章,仅仅是了解大概的实现原理,但是对于代码的实现细节并不是很了解。如果要加深印象,还是要结合代码来具体看一下实现的细节。
- 本文主要围绕具体的代码实现细节展开,对于相关原理,只会简单引用和讲解。因为官方代码使用的是pytorch,所以是通过pytorch展开的。
- 当前这篇主要介绍鉴别器的具体实现,在HiFi-GAN中,鉴别器分是由周期鉴别器和尺度鉴别器构成,当前这篇将就两种鉴别器的原理和功能进行具体讲解。
正文
鉴别器
- 因为声音信号中的长依赖比较重要,常规的做法是通过增加鉴别器的感受野,或者增加输入数据的维度来获取这种长领域特征。在HiFi-GAN是采用了增加输入信号的范围,采用多尺度鉴定器实现MSD。另外因为声音可以通过短时傅立叶变换,拆解成不同的周期的正弦信号叠加,HiFi-GAN专门采用了多周期鉴定器见捕捉每一段信号的不同周期特征。
多周期鉴定器
- 多周期鉴定器是有专门针对不同周期信号的若干子鉴定器构成,对于多周期信号,是通过对原始的波形信号进行不同间隔进行采样,将原来的一维波形数据,变成二维信号,然后在对其进行卷积。而且每一次卷积都是专门针对某一行数据,也就是某一个间隔采样生成的数据。具体可以看如下示意图。
- 由于数据经过等间隔采样,每一行是某一个周期信号,然后若干行表示有若干个周期信号,然后进行宽度为1,高度为特定长度的周期T/p的二维卷积采样,具体如下。每一个颜色都是按照一定间隔进行采样之后的数据,然后整个卷积层也是按照一个周期进行生成的。
- 网络具体结构图下,鉴别输入的是真实的波形图和生成波形图,然后输出两者相似的概率值,进而衡量两者的相似程度,具体模型如下,就是若干个卷积模块的堆叠。
- 多周期鉴定器具体实现代码在,整个多周期鉴定器是由若干个子周期鉴定器构成,所以代码也是分成两个部分。
- 具体的单个周期鉴定器已经定义过了,然后就是最终的总的周期鉴定器的结构,就是多个不同周期的子鉴定器具的输出构成的列表
class DiscriminatorP(torch.nn.Module):def __init__(self, period, kernel_size=5, stride=3, use_spectral_norm=False):# 定义鉴定器的初始化函数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_norm=False):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, padding=7)),norm_f(Conv1d(128, 128, 41, 2, groups=4, padding=20)),norm_f(Conv1d(128, 256, 41, 2, groups=16, padding=20)),norm_f(Conv1d(256, 512, 41, 4, groups=16, padding=20)),norm_f(Conv1d(512, 1024, 41, 4, groups=16, padding=20)),norm_f(Conv1d(1024, 1024, 41, 1, groups=16, padding=20)),norm_f(Conv1d(1024, 1024, 5, 1, padding=2)),])self.conv_post = norm_f(Conv1d(1024, 1, 3, 1, padding=1))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_norm=True),DiscriminatorS(),DiscriminatorS(),])# 定义两个平均池化层,尽量获取全局信息self.meanpools = nn.ModuleList([AvgPool1d(4, 2, padding=2),AvgPool1d(4, 2, padding=2)])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模型而言,最重要的还是生成器,然后鉴定器是起到了一个引导作用。鉴定器的考虑的越周到,相应的,生成器的生成的结果也就越准确。
相关文章:

论文代码学习—HiFi-GAN(2)——鉴别器discriminator代码
文章目录 引言正文鉴别器多周期鉴定器多尺度鉴定器问题 总结 引言 这里翻译了HiFi-GAN这篇论文的具体内容,具体链接。这篇文章还是学到了很多东西,从整体上说,学到了生成对抗网络的构建思路,包括生成器和鉴定器。细化到具体实现的…...
Linux Shell 脚本编程学习之【第3章 正则表达式 (第二部分) grep命令】
第3章 正则表达式 (第二部分) 4 grep命令4.1 基本用法4.2 参考命令4.2.1 双引号4.2.2 -c 输出匹配行数4.2.3 -h 或 -l 不显示或只显示文件名4.2.4 -s 不显示错误信息4.2.5 -r 递归显示本级目录及下级目录4.2.6 -w 匹配完整词 -x 匹配完整行4.2.7 -q 退出…...

大语言模型LLM
目录 一、语言模型的发展 语言模型(Language Model,LM)目标是建模自然语言的概率分布,具体目标是构建词序列w1,w2,...,wm的概率分布,即计算给定的词序列作为一个句子出现可能的大小P(w1w2...wm)。但联合概率P的参数量…...

自学网络安全(黑客)的误区
前言 网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。 一、网络安全学习的误区 1.不要…...

@Conditional
Conditional Conditional 是 spring framework 中提供的一个条件注解,,满足条件就注入,不满足就不注入ioc Condtional 需要和 Condition接口 一起用: 返回true注入,返回false不注入,, 里面有一…...

【Linux】网络基础之TCP协议
目录 🌈前言🌸1、基本概念🌺2、TCP协议报文结构🍨2.1、源端口号和目的端口号🍩2.2、4位首部长度🍪2.3、32位序号和确认序号(重点)🍫2.4、16位窗口大小🍬2.5、…...
Java设计模式之装饰器(Decorator)模式
装饰器(Decorator)设计模式允许动态地将新功能添加到对象中,同时又不改变其结构。 什么是装饰器模式 装饰器(Decorator)模式通过将对象进行包装,以扩展其功能,而不需要修改其原始类。装饰器模…...
element ui树组件render-content 树节点的内容区的渲染另一种方式
直接上代码吧,不用h的写法。 <el-tree :data"data" node-key"id" default-expand-all :expand-on-click-node"false" :props"defaultProps":render-content"renderContentTree" node-click"handleNodeClick"&g…...

html a标签换行显示
文章目录 用css display属性不用css,可以用<br>标签换行示例 用css display属性 可以使用CSS的display属性来实现多个a标签每行显示一个。 HTML代码: <div class"link-container"><a href"#">Link 1</a>…...
关于Redis-存Long取Integer类型转换错误的问题
背景 最近遇到了两个Redis相关的问题,趁着清明假期,梳理整理。 1.存入Long类型对象,在代码中使用Long类型接收,结果报类型转换错误。 2.String对象的反序列化问题,直接在Redis服务器上新增一个key-value,…...
设计模式一:简单工厂模式(Simple Factory Pattern)
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它提供了一个通用的接口来创建各种不同类型的对象,而无需直接暴露对象的创建逻辑给客户端。 简单工厂的三个重要角色: 工厂类(Factory Class&…...

如何利用plotly和geopandas根据美国邮政编码(Zip-Code)绘制美国地图
对于我自己来说,该需求源自于分析Movielens-1m数据集的用户数据: UserID::Gender::Age::Occupation::Zip-code 1::F::1::10::48067 2::M::56::16::70072 3::M::25::15::55117 4::M::45::7::02460 5::M::25::20::55455 6::F::50::9::55117我希望根据Zip-…...

ceph集群搭建
文章目录 理论知识具体操作搭建ceph本地源yum源及ceph的安装配置NTP(解决时间同步问题)部署ceph自定义crush 理论知识 Ceph是一个分布式存储系统,并且提供了文件、对象、块存储功能。 Ceph集群中重要的守护进程有:Ceph OSD、Cep…...

前端密码加密 —— bcrypt、MD5、SHA-256、盐
🐔 前期回顾悄悄告诉你:前端如何获取本机IP,轻松一步开启网络探秘之旅_彩色之外的博客-CSDN博客前端获取 本机 IP 教程https://blog.csdn.net/m0_57904695/article/details/131855907?spm1001.2014.3001.5501 在前端密码加密方案中ÿ…...

汽车UDS诊断深度学习专栏
1.英文术语 英文术语翻译Diagnostic诊断Onboard Diagnostic 在线诊断 Offboard Diagnostic离线诊断Unified diagnostic service简称 UDS 2.缩写表 缩写解释ISO国际标准化组织UDSUnified diagnostic service,统一的诊断服务ECU电控单元DTC 诊断故障码 ISO14229UD…...
macOS 下安装brew、nvm
1、brew: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" brew -v 查看版本 示例: 安装jdk brew search jdk 查询可用的jdk版本 brew install openjdk11 安装制定版本jdk 更换源࿱…...
【云原生】Kubernetes工作负载-StatefulSet
StatefulSet StatefulSet 是用来管理有状态应用的工作负载 API 对象 StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符 和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同…...
Java:方法的重载
方法重载 为什么需要方法重载 在使用方法的过程中我们可能会遇到以下如同例子的情形: public class method1 {public static void main(String[] args) {int a1 10;int b1 20;double ret1 add(a1, b1);System.out.println("ret1 " ret1);do…...
7.react useCallback与useMemo函数使用与常见问题
react useCallback与useMemo函数使用与常见问题 useCallback返回一个可记忆的函数,useMemo返回一个可记忆的值,useCallback只是useMemo的一种特殊形式。 那么这到底是什么意思呢?实际上我们在父子通信的时候,有可能传递的值是一…...

Sentinel限流中间件
目录 介绍 Sentinel 的特征 Sentinel 的组成 实战使用 简单实例 配置本地控制台 使用可视化ui配置简单流控 配置异步任务限流 使用注解定义限流资源 SpringCloud整合Sentinel 简单整合 并发线程流控 关联模式 整合openFeign使用 介绍 随着微服务的流行࿰…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...