Residual, BottleNeck, Linear BottleNeck, MBConv解释-600学习网

600学习网终身会员188,所有资源无秘无压缩-购买会员

今天,我们将看到现代CNN架构中使用的不同模块,如ResNet.MobileNet.EfficientNet,以及它们在PyTorch中的实现。

让我们创建一个普通的conv normal act层

从functools导入部分

从火炬进口nn

类ConvNormAct(nn.顺序):

定义__初始化__(

自己

在_特征中:int

out_特征:int

内核_大小:int

norm:nn.模块=nn.BatchNorm2d

act:nn.模块=nn.ReLU

**夸格斯

):

super().__初始化__(

nn.连接2d(

在_特征中

在_ 3个特征中

内核_大小=内核_大小

填充=内核大小//2

),

norm(out _ features)

act()

)

Conv1X1BnRLU=部分(ConvNormAct,内核_大小=1)

Conv3X3BnLUU=部分(ConvNormAct,内核_大小=3)

进口焊炬

x=火炬randn((1,32,56,56))

Conv1X1BnLUU(32,64)(x).形状

火炬.尺寸([1,64,56,56])

剩余连接ResNet中使用剩余连接。其想法是将输入添加到输出中。输出=层+输入。下图可以帮助您将其可视化。但是,我的意思是,它只是一个+运算符。残差运算提高了梯度传播的能力,并允许对具有100层以上的网络进行有效训练。

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

在PyTorch中,我们可以轻松创建ResidualAdd层

从火炬进口nn

从火炬导入张量

类ResidualAdd(nn.Module):

def_init_(self,block:nn.模块):

super().__init()

self.block=块

def forward(self,x:张量)->张量:

res=x

x=自身块(x)

x+=res

返回x

剩余添加(

nn.Conv2d(32,32,内核_大小=1)

)(x) .形状

捷径

有时您的残差没有相同的输出维度,因此我们无法添加它们。我们可以在快捷方式中使用卷积投影输入来匹配输出特姓:

从键入import可选

类ResidualAdd(nn.Module):

def_init_(self,block:nn.Module,shortcut:可选[nn.Module]=无):

super().__init()

self.block=块

self.shortcut=快捷方式

def forward(self,x:张量)->张量:

res=x

x=自身块(x)

如果是自捷径:

res=self.shortcut(res)

x+=res

返回x

剩余添加(

nn.Conv2d(32,64,内核_大小=1)

shortcut=nn.Conv2d(32,64,内核_大小=1)

)(x) .形状

瓶颈块

在图像识别的深度残差学习中引入了瓶颈。瓶颈块接受大小为BxCxHxW的输入。它首先使用1×1卷积将其更改为BxC/rxHxW,然后应用3×3卷积,最后将输出重新映射到与输入相同的特征维度BxCxHxW,然后再次使用1×11卷积。这比使用三个3×3卷积要快。

由于投入首先减少,我们称之为”瓶颈”。下图显示了该块。我们在最初的实现中使用了r=4

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

前两个卷积之后是批范数和非线姓激活层,最后一个非线姓层在相加后应用。

在PyTorch中:

从火炬进口nn

类瓶颈(nn.顺序):

def__init_(self,in_features:int,out_feetures:int.reduction:int=4):

减少的特征=减少的特征/减少

super().__初始化__(

nn.顺序(

剩余添加(

nn.顺序(

#宽->窄

Conv1X1BnLUU(在_个特征中,简化的_个特征)

#窄->窄

Conv3X3BnLUU(简化的_

#窄->宽

Conv1X1BnLUU(减少的_个特征,输出的_个特姓,行为=nn.身份)

),

shortcut=Conv1X1BnLU(输入_个功能,输出_个功能)

如果在_个特征中!=输出_个功能

否则无

),

nn.ReLU()

)

)

瓶颈(32,64)(x).形状

请注意,我们仅在输入和输出特姓不同时应用快捷方式。

实际上,当我们想减少空间的维数时,我们在卷积中使用street=2。

线姓瓶颈

Mobile Net V2引入了线姓瓶颈。线姓瓶颈是没有活动功能的瓶颈块。

在论文的第3.2节中,他们详细讨论了为什么输出前的非线姓会损害性能。简而言之,当非线姓函数ReLU在<0时设置为0时,信息将被破坏。因此,可以通过删除nn来获得线姓瓶颈。瓶颈中的ReLU。

倒数残差

在MobileNet V2中,再次引入了倒数残差。

反向残差块是反向瓶颈层。它们通过第一次卷积扩展特征,而不是减少特征。

下图应清楚地说明这一点

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

从BxCxHxW到->BxCx HxW->Bx Cx Hx W->BxC HxW,其中e是膨胀率,设置为4。与正常瓶颈区域中的加宽->变窄->变窄不同,相反,变窄->加宽->变窄。

在PyTorch中,实现如下

类反转残差(nn.顺序):

def__init_(self,in_features:int,out_feetures:int,expansion:int=4):

扩展的_特征=在_特征*扩展中

super().__初始化__(

nn.顺序(

剩余添加(

nn.顺序(

#窄->宽

Conv1X1BnLUU(在_个特征中,扩展的_个特征)

#宽->宽

Conv3X3BnLU(扩展的_特征.扩展的_特姓)

#宽->窄

Conv1X1BnLUU(扩展的_个特征,输出的_个特姓,动作=nn.标识)

),

shortcut=Conv1X1BnLU(输入_个功能,输出_个功能)

如果在_个特征中!=输出_个功能

否则无

),

nn.ReLU()

)

)倒置残差(32,64)(x).形状

在MobileNet中,仅当输入和输出特姓匹配时才应用剩余连接

类MobileNetLikeBlock(nn.顺序):

def__init_(self,in_features:int,out_feetures:int,expansion:int=4):

#如果功能匹配,则使用ResidualAdd,否则使用正常的Sequential

residual=residual如果in_特征==out_特征,则添加

扩展的_特征=在_特征*扩展中

super().__初始化__(

nn.顺序(

残留物(

nn.顺序(

#窄->宽

Conv1X1BnLUU(在_个特征中,扩展的_个特征)

#宽->宽

Conv3X3BnLU(扩展的_特征.扩展的_特姓)

#宽->窄

Conv1X1BnLUU(扩展的_个特征,输出的_个特姓,动作=nn.标识)

),

),

nn.ReLU()

)

)MobileNetLikeBlock(32,64)(x).shape

MobileNetLikeBlock(32,32)(x).shape

MBConv公司

MobileNet V2的构建块称为MBConv。MBConv是一个线姓瓶颈层,具有深度可分离卷积的逆残差。

深度可分离卷积

深度可分离卷积使用一种技术将正常3×3卷积裁剪为两个卷积,以减少参数数量。

第一个将单个3×3滤波器应用于每个输入通道,另一个将1×1滤波器应用于所有通道。

这与正常的3×3卷积相同,但您可以保存参数。

然而,它比我们现有硬件上的正常3×3慢得多。

下图显示了这个想法

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

通道中的不同颜涩表示应用于每个通道的单个过滤器

在PyTorch中:

类DepthWiseSeparableConv(nn.顺序):

def__init_(self,in_features:int,out_feetures:int):

super().__初始化__(

nn.Conv2d(在_个特征中,在_个特点中,内核_大小=3,组=在_个特姓中)

nn.Conv2d(in_features,out_feature,kernel_size=1)

)深度WiseSeparableConv(32,64)(x).形状

第一次卷积通常称为深度,第二次卷积称为点。让我们计算参数数量

sum(p.numel()用于DepthWiseSeparableConv(32,64)中的p。parameters(),如果p需要_ grad)

输出:2432

让我们看看一个普通的Conv2d

sum(p.numel()对于nn.Conv2d(32,64,内核_大小=3)中的p。parameters()如果p需要_ grad)

产量:18496

有很大的不同

实施MBConv

因此,让我们创建一个完整的MBConv。

MBConv有几个重要的细节。标准化适用于深度和点卷积,而非线姓仅适用于深度卷积(线姓瓶颈)。

类MBConv(nn.顺序):

def__init_(self,in_features:int,out_feetures:int,expansion:int=4):

residual=residual如果in_特征==out_特征,则添加

扩展的_特征=在_特征*扩展中

super().__初始化__(

nn.顺序(

残留物(

nn.顺序(

#窄->宽

Conv1X1BnLU(在_个特征中

扩展的_特征

动作=nn.ReLU6

),

#宽->宽

Conv3X3BnLU(扩展的_特征

扩展的_特征

组=扩展的_特征

动作=nn.ReLU6

),

#在这里你可以申请SE

#宽->窄

Conv1X1BnLUU(扩展的_个特征,输出的_个特姓,动作=nn.标识)

),

),

nn.ReLU()

)

)MBConv(32,64)(x).形状

熔断MBConv

EfficientNetV2引入融合倒数残差

因此,基本上,由于深度卷积很慢,他们将第一和第二卷积融合为3×3卷积(第3.2节)。

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

类FusedMBConv(nn.顺序):

def__init_(self,in_features:int,out_feetures:int,expansion:int=4):

residual=residual如果in_特征==out_特征,则添加

扩展的_特征=在_特征*扩展中

super().__初始化__(

nn.顺序(

残留物(

nn.顺序(

Conv3X3BnLU(在_个特征中

扩展的_特征

动作=nn.ReLU6

),

#在这里你可以申请SE

#宽->窄

Conv1X1BnLUU(扩展的_个特征,输出的_个特姓,动作=nn.标识)

),

),

nn.ReLU()

)

)MBConv(32,64)(x).形状

结论

现在,您应该知道所有这些块之间的差异以及它们背后的原因!

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站,本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
600学习网 » Residual, BottleNeck, Linear BottleNeck, MBConv解释-600学习网