深入理解ECAPA-TDNN——兼谈Res2NetASP统计池化SENetBatch Normalization
Posted DEDSEC_Roger
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解ECAPA-TDNN——兼谈Res2NetASP统计池化SENetBatch Normalization相关的知识,希望对你有一定的参考价值。
概述
- ECAPA-TDNN是说话人识别中基于TDNN的神经网络,是目前最好的单体模型之一
- 关于TDNN,可以参考深入理解TDNN(Time Delay Neural Network)——兼谈x-vector网络结构
ECAPA-TDNN
- TDNN本质上是1维卷积,而且常常是1维膨胀卷积,这样的一种结构非常注重context,也就是上下文信息,具体而言,是在frame-level的变换中,更多地利用相邻frame的信息,甚至跳过 t − 1 , t + 1 t-1,t+1 t−1,t+1的frame,而去对 t − 2 , t + 2 t-2,t+2 t−2,t+2的frame进行连接
- 在ECAPA-TDNN中,更是进一步利用了膨胀卷积,出现了 d i l a t i o n = 2 , 3 , 4 dilation=2,3,4 dilation=2,3,4的情况。此外,还引入了Res2Net,从而获得了多尺度的context,所谓多尺度,指的是各种大小的感受野
- 1维膨胀卷积已经在深入理解TDNN(Time Delay Neural Network)——兼谈x-vector网络结构中讲解清楚,下面先介绍Res2Net
Res2Net
- 经典的ResNet结构如下左图所示,先用 k e r n e l - s i z e = 1 × 1 kernel \\text- size=1 \\times 1 kernel-size=1×1的卷积运算,相当于只针对每个像素点的特征通道进行变换,而不关注该像素点的任何邻近像素,并且是降低特征通道的,所以也被叫做Bottleneck,就好像将可乐从瓶口倒出来,如果是增加特征通道,那么就叫Inverted Bottleneck
- 1 × 1 1\\times1 1×1卷积后,会经过 3 × 3 3\\times3 3×3卷积,通常不改变特征通道,如果不需要在最后加上残差连接,那么 s t r i d e = 2 stride=2 stride=2,特征图的分辨率会被下采样,如果需要在最后加上残差连接,那么 s t r i d e = 1 stride=1 stride=1,保持特征图分辨率不变
- 最后还会有一个
1
×
1
1\\times1
1×1卷积,目的是复原每个像素点的特征通道,使其等于输入时的特征通道,从而能够进行残差连接。整个Bottleneck block形似一个沙漏,中间是窄的(特征通道少),两边是宽的(特征通道多)
- 而Res2Net则是在中间的 3 × 3 3\\times3 3×3卷积进行的微创新,首先将 1 × 1 1\\times1 1×1卷积后的特征图,按照特征通道数进行平分,得到 s c a l e scale scale个相同的特征图(这里的 s c a l e scale scale是“尺度”的意思,Res2Net的作用就是多尺度特征,一语双关)
- 第一个特征图保留,不进行变换,这是对前一层特征的复用,同时也降低了参数量和计算量。从第二个特征图开始,都进行 3 × 3 3\\times3 3×3卷积,并且当前特征图的卷积结果,会与后一个特征图进行残差连接(逐元素相加),然后,后一个特征图再进行 3 × 3 3\\times3 3×3卷积
- 卷积中有一个概念叫感受野,是指当前特征图上的像素点,由之前某一个特征图在多大的分辨率下进行卷积得到的。如下图所示,
d
i
l
a
t
i
o
n
=
1
dilation=1
dilation=1的
3
×
3
3\\times3
3×3卷积,其输出特征图的每一个像素点的感受野都是
3
×
3
3\\times3
3×3,再进行
d
i
l
a
t
i
o
n
=
1
dilation=1
dilation=1的
3
×
3
3\\times3
3×3卷积,其输出特征图的每一个像素点的感受野都是
5
×
5
5\\times5
5×5
- 因此Res2Net中,第二个特征图的感受野为 3 × 3 3\\times3 3×3,第三个特征图的感受野为 5 × 5 + 3 × 3 5\\times5+3\\times3 5×5+3×3,第四个特征图的感受野为 7 × 7 + 5 × 5 + 3 × 3 7\\times7+5\\times5+3\\times3 7×7+5×5+3×3,以此类推,从而得到多尺度特征
- 所有的卷积结果都会按照特征通道进行串联(concatenate),由于第一个特征图保留,不进行变换,所以后续的特征图维度必须与第一个特征图相同,因此 3 × 3 3\\times3 3×3卷积不改变特征通道和分辨率
- 最后的 1 × 1 1\\times1 1×1卷积,目的是复原每个像素点的特征通道,使其等于输入时的特征通道,从而能够进行残差连接
- Res2Net可以作为一个即插即用的结构,插入到现有的其他神经网络中,还可以与其他即插即用的结构一起工作,比如SENet和ResNeXt
SENet
- SENet(Squeeze-and-Excitation Networks)是现代卷积神经网络所必备的结构,性能提升明显,计算量不大。基本思路是将一个特征图的每个特征通道,都映射成一个值(常用全局平均池化,即取该特征通道的均值,代表该通道),从而特征图会映射为一个向量,长度与特征通道数一致
- 之后,对向量进行FC(用1维卷积也行,等价的),输出长度为特征通道数的
1
r
\\frac1r
r1,然后经过激活函数ReLU,这个过程称为Squeeze(挤压);再进行FC,输出长度与特征通道数一致,然后经过激活函数Sigmoid,这个过程称为Excitation(激励);此时输出向量的每一个值,范围都是
(
0
,
1
)
(0,1)
(0,1),最后用输出向量的每一个值,对输入特征图的对应通道进行加权,这个过程称为Scale(伸缩)
- SENet的结构相当于对特征图的特征通道进行加权,因为每个特征通道的重要性是不一样的,所以让神经网络自行学习每个特征通道的权重,因此是一种Attention机制。并且输入特征图和输出特征图的维度完全一致,从而可以作为一个即插即用的结构,下面是Res2Net与SENet结合得到的结构,被称为SE-Res2Net
- Res2Net还可以与ResNeXt结合,其实就是将中间的 3 × 3 3\\times3 3×3卷积换成 3 × 3 3\\times3 3×3分组卷积,不过ECAPA-TDNN中没有用到,就不再赘述了,接下来介绍ECAPA-TDNN的具体设计
回到ECAPA-TDNN
- 在ECAPA-TDNN中所用的Res2Net,是上述结构中的2维卷积全部换成1维卷积,采用的中间
k
=
3
k=3
k=3卷积(1维卷积,不能用
3
×
3
3\\times3
3×3表示,以下都用
k
=
3
k=3
k=3代替)为膨胀卷积,并且随着网络深度增加,
d
i
l
a
t
i
o
n
dilation
dilation分别为
2
,
3
,
4
2,3,4
2,3,4。ECAPA-TDNN的结构图如下,SE-Res2Block后面括号内的参数,指的是Res2Block的中间
k
=
3
k=3
k=3卷积的参数
- SE-Res2Block的内部,如下图所示,夹着Res2的两个CRB(Conv1D+ReLU+BN)结构的参数为
(
k
=
1
,
d
=
1
)
(k=1,d=1)
(k=1,d=1),中间的Res2,
s
c
a
l
e
=
8
scale=8
scale=8,之后的运算与上述Res2Net一致,不过每个
k
=
3
k=3
k=3卷积都是膨胀卷积,并且都会接ReLU和BN,从而形成Res2 Dilated Conv1D+ReLU+BN的结构
- 最后的SE-Block是在特征维度进行的,也就是将T个frame的特征,在每个特征维度求平均,得到的向量,长度与特征维度一致,之后的运算与上述SENet一致
- 之前提到ResNet结构是沙漏型的,但是ECAPA-TDNN的frame-level变换中的ResNet结构,除了Res2会把特征维度进行平分外,其余的运算都没有发生特征维度的变化,关于frame-level变换,详见深入理解TDNN(Time Delay Neural Network)——兼谈x-vector网络结构。ECAPA-TDNN有两个版本,主要区别就在于frame-level的变换中,特征维度是512还是1024
- frame-level变换之后,则是统计池化(Statistics Pooling),ECAPA-TDNN采用了ASP作为统计池化层,并且还进行了一些改进
ASP
- ASP(Attentive Statistics Pooling)是2018年提出的,至今仍然广为使用的带有Attention的统计池化层,直到2022年才出现竞争对手(一种带有Multi-head Attention的统计池化)
- ECAPA-TDNN中对ASP进行了改进,首先将之前3个SE-Res2Block的输出,按照特征维度进行串联,假设frame-level变换中的特征维度是512,由于3个SE-Res2Block的输出维度都是
(
b
s
,
512
,
T
)
(bs,512,T)
(bs,512,T),所以串联之后是
(
b
s
,
512
∗
3
,
T
)
(bs,512*3,T)
(bs,512∗3,T),之后经过一个CRB结构,输出维度固定为
(
b
s
,
1536
,
T
)
(bs,1536,T)
(bs,1536,T),即便frame-level的特征维度是1024,该CRB的输出维度也不变。如下图所示
- 对特征图 ( b s , 1536 , T ) (bs,1536,T) (bs,1536,T),记为h,按照T维度计算每个特征维度的均值和标准差,如上图的TSTP公式所示(符号 ⊙ \\odot ⊙表示哈达玛积,即对应项相乘,两个因子的维度必须相同,从而结果的维度与因子的维度也相同),从而T维度消失,得到的均值和标准差维度均为 ( b s , 1536 ) (bs,1536) (bs,1536)
- 之后的操作很神奇,将均值在T维度重复堆叠T次,维度恢复为
(
b
s
,
1536
,
T
)
(bs,1536,T)
(bs,1536,T),对标准差也是堆叠,维度恢复为
(
b
s
,
1536
,
T
)
(bs,1536,T)
(bs,1536,T),接着将特征图、均值和标准差在特征维度进行串联,得到的特征图维度为
(
b
s
,
1536
∗
3
,
T
)
(bs,1536*3,T)
(bs,1536∗3,T),记为H
- 对H进行1维卷积,等价于上图的 W × H + b W\\times H+b W×H+b,目的是将每个frame的特征从1536*3维降维映射到F维,F可取128,然后经过tanh激活函数,得到特征图a,维度为 ( b s , F , T ) (bs,F,T) (bs,F,T)
- 对a进行1维卷积,等价于上图的 V × a + k V\\times a+k V×a+k,目的是将每个frame的特征从F维恢复映射到与h相同的维度,即1536,然后在T维度,进行softmax激活,得到特征图a,维度为 ( b s , 1536 , T ) (bs,1536,T) (bs,1536,T)
- 此时的特征图a的每一行特征,在T维度上求和,都等于1,这是softmax激活的效果,又因为与h的维度相同,所以可以将a视为一种Attention分数,利用上图的ASTP公式,对h求基于Attention的均值和标准差,关于Attention分数,可以参考深入理解Self-attention(自注意力机制)
- 基于Attention的均值和标准差,维度都为 ( b s , 1536 ) (bs,1536) (bs,1536),再将它们按照特征维度进行串联,得到ASP最终的输出,维度为 ( b s , 1536 ∗ 2 ) (bs,1536*2) (bs,1536∗2),在ECAPA-TDNN中,ASP之后还会接一个BN
BN
- 这一节是讲BN(Batch Normalization)的,可能观众会感觉我太啰嗦了,怎么连BN都要讲,主要是ECAPA-TDNN是一个完全的TDNN结构,连BN都是1维的,所以怕大家一下子转不过来弯,下面主要讲解1维BN,自认对BN滚瓜烂熟的观众,可跳过本节
t o r c h . n n . B a t c h N o r m 1 d ( n u m - f e a t u r e s , e p s = 1 e − 05 , m o m e n t u m = 0.1 , a f f i n e = T r u e , t r a c k - r u n n i n g - s t a t s = T r u e , d e v i c e = N o n e , d t y p e = N o n e ) torch.nn.BatchNorm1d(num \\text- features, eps=1e-05, momentum=0.1, affine=True, track \\text- running \\text- stats=True, device=None, dtype=None) torch.nn.为什么会有DevOps,解决了什么问题:- 现代企业其实都是通过IT系统进行管理和运营的,在变化迅速和竞争激烈的领域,IT系统的新需求数量越来越多,软件发布的频率越来越高,不少互联网公司24小时内会发布几十个到上百个release到生产环境。与此同时,业务对IT服务和系统的稳定性和质量的要求也在不断提高。如何高效稳定地开发并上线新的业务功能,同时提供高质量的IT服务,关系到企业竞争能力的强弱,关乎商业价值的实现。
- 开发团队和运维团队在传统的的企业IT部门中是两个独立的团队。他们的构成和人员背景差异非常大,软件开发团队通常擅长于设计和开发软件功能,算法,他们希望能够尽可能多和快得完成客户或产品部分的需求。而运维团队通常把完成的软件部署到生产环境,负责监控和解决软件系统运行时的问题,希望的是系统的稳定地运行,他们竭尽一切需要达到SLA的标准。
关于测试团队:Test这个环节通常会有专门的测试团队负责,在很早期的时候,测试团队和开发团队也是分开的。不过自从敏捷开发流行以后,测试团队的成员就已经被看做开发部门的一部分了,这也部分归功于微软的贡献,他们当时新发明了SDET(软件开发测试工程师)这个概念,以表明测试工程师也是开发人员。他们写测试用例,进行功能和压力测试,同时需要懂得一些开发技术并拥有自动化测试的能力。开发人员对自己的代码质量也要负责,需要写自己负责模块的单元测试代码,软件开发人员之间需要交叉进行代码review。
下面的DevOps图相信很多朋友都见过了,当然这个图也有不同的变化版本。通过这个图来看,开发和运维团队衔接的最关键环节在Release-Deploy这三个步骤。而这一部分是否能够做得好,直接关系到DevOps在整个IT部门实施的成败。这一部分现在的主要解决方案就是CI/CD-持续集成和持续发布。DevOps不只是一个方法论,其涉及到整个IT团队文化的调整,多种新观念新方法论的实践以及现代化运维工具的应用这三个方面。
DevOps两大流派
对于DevOps问题的解决上,其实分成了两大流派。让我们来探讨一下这两派的观点和适用范围。
传统IT公司的DevOps解决方案,代表 - AWS,IBM...
从传统的运维模式转变到更加灵活和高效的DevOps模式。IT部门还是保持传统的人员配置和工作技能,但是在合作,实践和工具的应用上有很多方向的实践转变。
IT部门文化的转变
开发和运维部门必须打破传统的界限,需要共同承担软件系统运行的稳定性和性能上的责任和义务。运维团队有权利去拒绝没有达到生产环境准入标准的Release。开发和运维之间,测试和运维之间充分的透明度和沟通机制。最好能够在在一起办公,或者至少部分运维团队成员和开发团队成员坐在一起。能够容忍错误的发生,当错误的发生时,不要立刻责罚,而要通过分析,找到根本原因,并通过持续的改进来做好系统的强壮性和避免人为错误造成严重的系统故障。
技术和方法论层面的变革
微服务的应用: IT系统应该逐渐从monolithic的模式转向微服务的模式,这样不同功能/模块的开发和发布能够相对独立,不同的敏捷团队可以更加快速地迭代和测试,同时交给运维团队的发布包的粒度更小,出问题后对整个系统影响更小。同时采用新的运维工具可以无感知逐渐升级微服务,迅速恢复或者回滚故障的微服务。
CI&CD:持续集成和持续交付,这个概念其实提出的很早。但是直到最近几年才开始被主流的业界接受。传统的软件发布频率往往是以周或者月为单位进行的。在很多情况下这已经不能满足业务快速迭代的要求,同时也越来越不适应快速迭代的敏捷开发模式。而且这种大粒度的集成和发布(通常一段时间的许多变更会在一个发布中上生产环境)出现问题的可能性和影响都比较大。 而持续集成和持续交付的粒度小到开发人员每一次代码的提交。一旦完成代码提交就会触发构建并执行自动化测试脚本和单元测试,同时测试团队的成员也会收到通知进行测试确认。一旦通过就能够自动发布到stage环境进行最后的UAT确认,接着在运维团队确认后自动发布到生产环境。这种小颗粒的集成和发布其实降低了每一次发布的风险。同时给开发和运维团队提供了一个快速沟通和协作的流程。另一方面,CI/CD也保证了开发环境,测试环境和生成环境的代码高度得一致性,这给定位和解决问题带来了便利。
Infrastructure as Code: 如今的IT基础架构都运行在虚拟化的平台-共有或者私有云上,从网络,存储到计算能力都是可以同过软件来配置的。这给到基础设施团队和运维团队部署新的服务和计算资源的效率和能力极大得提升。
持续监控和记录:通过监控和日志分析统计实时监控所有系统的运行状态,在出现问题前预警,甚至自动干预和解决,提高整个运维的稳定性和效率。让团队关注在最有可能出问题的环节和系统,提前准备和预防。
运维工具的应用
下图列出的是DevOps各个环节的常用工具。代码的版本管理是Git(Git应该算是一统天下了,其他的版本工具基本都已经很边缘化了)构建工具每种语言都不同,下图里列的是Java相关的构建工具Maven和Gradle。在整个DevOps工具库中最重要和关键的工具必然是CI&CD工具,这是CI/CD在DevOps的核心地位决定的。CI&CD最流行的工具的就是Jenkins了,功能强大而且是开源软件。通过持续集成和交付,真正串联起了开发,测试和运维团队,通过工具和流程让三个团队能够协同工作。其次我觉得是自动化部署工具也非常重要,让运维团队能够迅速发布和创建标准环境。这些工具有Chef,Puppet和Ansible。总体来讲,我觉得Ansible是比较推荐的工具,第一是能够很好的和Docker一起结合使用。另外一点是Ansible采用的是Push模式去部署应用环境,不需要在其他节点上安装任何Agent程序,灵活性很高。
顶级互联网公司SRE派,代表 - Google
两本指导手册,可以在这个网站免费看。在 https://landing.google.com/sre/ 有Google总结的很多关于SRE相关的信息和资源,可以作为参考。这也是是谷歌力推的运维团队的模式。不过这种模式也只有类似Google这样的“豪门”公司可以采用。我阅读了那个网站的介绍,并大概看了两本指导手册,发现SRE就是事实上谷歌的运维团队。但是谷歌本身有着极高的准入标准,哪怕是运维团队的成员也是以SDE的能力和标准来招聘的,其SRE团队成员中软件工程师和系统工程师各占一半。他们通常会以软件工程的思维去处理运维问题,做一些自动化的流程,编写工具提高运维效率和系统稳定性,甚至能够直接去review开发团队提交的代码。SRE团队和产品,开发团队基本处在平等的地位,甚至相比之下还有些许特权。他们不但可以直接拒绝不符合运维要求的版本,甚至可以在某些情况下退出运维的工作,交给原来的开发团队。
谷歌制定了一套标准,还整出了SLI,SLO和SLA三种系统运维指标,其中SLO是由SRE制定的。一旦开发出来的系统达不到SLO(service level objective),SRE团队会要求开发团队必须将主要精力放在增强稳定性上。为此他们还发明了一个名词叫Error Budget,就是说一个系统能够有一定的错误余量(原因是只要是人类做的东西总是有可能会出问题~~~),如果某时间段的Error Budget被用完了,那么这个系统的最优先级任务将不再是新功能开发和上线,而是保证其质量和稳定性,直到其Error Budget再次恢复为正。
我们其实可以看到,与其说SRE是运维人员,还不如把他们归类为专注于系统性能和稳定性的软件工程师团队。这种用软件工程师团队覆盖运维工作的做法,在成本上和实际的企业文化上可能并不是所有公司都能够采用的。不过如果有能力采用这种模式的公司,我觉得还是应该尝试一下。
最后引用Google自己的一句话作为结尾吧,
这句话其实说出了谷歌团队心目中的SRE和DevOps的关系,
class SRE implements interface DevOps
对本文格式不满意可以访问原文地址https://www.rockysky.tech
以上是关于深入理解ECAPA-TDNN——兼谈Res2NetASP统计池化SENetBatch Normalization的主要内容,如果未能解决你的问题,请参考以下文章
改进YOLO系列:YOLOv5结合Res2Net Block骨干网络