国产在线99爱视频|亚洲AV成人久久无码|亚洲日韩成人片在线播放|精品日韩二区三区精品视频|国产精品成人麻豆视频网站|亚洲午夜AⅤ视频在线天堂|国产亚洲精品成人a·v久久|精品国产一区二区三区每日更新

鄭州華泰聯(lián)合工業(yè)物聯(lián)網(wǎng)云平臺(tái)

掃一掃關(guān)注

Residual, BottleNeck, Linear BottleNeck, MBConv解釋 - OFweek 人工智能網(wǎng)

   2022-04-02 OFweek電子工程網(wǎng)ofweek3850
導(dǎo)讀

今天,我們將看到現(xiàn)代CNN架構(gòu)中使用的不同模塊,如ResNet、MobileNet、EfficientNet,以及它們?cè)赑yTorch中的實(shí)現(xiàn)。讓我們創(chuàng)建一個(gè)通用的conv-norm-act層from

今天,我們將看到現(xiàn)代CNN架構(gòu)中使用的不同模塊,如ResNet、MobileNet、EfficientNet,以及它們?cè)赑yTorch中的實(shí)現(xiàn)。

讓我們創(chuàng)建一個(gè)通用的conv-norm-act層

from functools import partial

from torch import nn

class ConvNormAct(nn.Sequential):

   def __init__(

       self,

       in_features: int,

       out_features: int,

       kernel_size: int,

       norm: nn.Module = nn.BatchNorm2d,

       act: nn.Module = nn.ReLU,

       **kwargs

   ):


       super().__init__(

           nn.Conv2d(

               in_features,

               out_features,

               kernel_size=kernel_size,

               padding=kernel_size // 2,

           ),

           norm(out_features),

           act(),

       )


Conv1X1BnReLU = partial(ConvNormAct, kernel_size=1)

Conv3X3BnReLU = partial(ConvNormAct, kernel_size=3)

import torch

x = torch.randn((1, 32, 56, 56))

Conv1X1BnReLU(32, 64)(x).shape

torch.Size([1, 64, 56, 56])

殘差連接殘差連接用于ResNet中,想法是將輸入添加到輸出中,輸出=層+輸入。下圖可能會(huì)幫助你將其可視化。但是,我的意思是它只是一個(gè)+運(yùn)算符。殘差操作提高了梯度傳播的能力,允許有效地訓(xùn)練具有100層以上的網(wǎng)絡(luò)。

在PyTorch中,我們可以輕松創(chuàng)建一個(gè)ResidualAdd層

from torch import nn

from torch import Tensor

class ResidualAdd(nn.Module):

   def __init__(self, block: nn.Module):

       super().__init__()

       self.block = block
       

   def forward(self, x: Tensor) -> Tensor:

       res = x

       x = self.block(x)

       x += res

       return x
   

ResidualAdd(

   nn.Conv2d(32, 32, kernel_size=1)

)(x).shape


shortcut

有時(shí)你的殘差沒(méi)有相同的輸出維度,所以我們不能添加它們。我們可以使用shortcut中的卷積投射輸入,以匹配輸出特征:

from typing import Optional


class ResidualAdd(nn.Module):

   def __init__(self, block: nn.Module, shortcut: Optional[nn.Module] = None):

       super().__init__()

       self.block = block

       self.shortcut = shortcut
       

   def forward(self, x: Tensor) -> Tensor:

       res = x

       x = self.block(x)

       if self.shortcut:

           res = self.shortcut(res)

       x += res

       return x


ResidualAdd(

   nn.Conv2d(32, 64, kernel_size=1),

   shortcut=nn.Conv2d(32, 64, kernel_size=1)

)(x).shape


BottleNeck Blocks

在圖像識(shí)別的深度殘差學(xué)習(xí)中引入了Bottlenecks。Bottlenecks塊接受大小為BxCxHxW的輸入,它首先使用1x1 卷積將其變?yōu)锽xC/rxHxW,然后應(yīng)用3x3 卷積,最后將輸出重新映射到與輸入相同的特征維度BxCxHxW,然后再次使用1x1卷積。這比使用三個(gè)3x3卷積更快。

因?yàn)槭紫葴p少了輸入,所以我們稱(chēng)之為“Bottlenecks”。下圖顯示了該塊,我們?cè)谠紝?shí)現(xiàn)中使用了r=4

前兩個(gè)卷積之后是batchnorm和一個(gè)非線性激活層,而最后一個(gè)非線性層在加法后應(yīng)用。

在PyTorch中為:

from torch import nn

class BottleNeck(nn.Sequential):

   def __init__(self, in_features: int, out_features: int, reduction: int = 4):

       reduced_features = out_features // reduction

       super().__init__(

           nn.Sequential(

               ResidualAdd(

                   nn.Sequential(

                       # wide -> narrow

                       Conv1X1BnReLU(in_features, reduced_features),

                       # narrow -> narrow

                       Conv3X3BnReLU(reduced_features, reduced_features),

                       # narrow -> wide

                       Conv1X1BnReLU(reduced_features, out_features, act=nn.Identity),

                   ),

                   shortcut=Conv1X1BnReLU(in_features, out_features)

                   if in_features ?。?out_features

                   else None,

               ),

               nn.ReLU(),

           )

       )
       

BottleNeck(32, 64)(x).shape

請(qǐng)注意,僅當(dāng)輸入和輸出特征不同時(shí),我們才應(yīng)用shortcut。

在實(shí)踐中,當(dāng)我們希望減小空間維數(shù)時(shí),在卷積中使用stride=2。

Linear BottleNecks

MobileNet V2中引入了Linear Bottleneck。Linear BottleNecks是沒(méi)有激活函數(shù)的Bottlenecks塊。

在論文的第3.2節(jié)中,他們?cè)敿?xì)討論了為什么在輸出之前存在非線性會(huì)損害性能。簡(jiǎn)而言之,非線性函數(shù)ReLU在<0時(shí)設(shè)為0會(huì)導(dǎo)致破壞信息。因此,在Bottlenecks中刪除nn.ReLU你就可以擁有Linear BottleNecks。

倒殘差

MobileNet V2中再次引入了倒殘差。

倒殘差塊是反向的Bottlenecks層。它們通過(guò)第一次卷積擴(kuò)展特征,而不是減少特征。

下圖應(yīng)該可以清楚地說(shuō)明這一點(diǎn)

我們從BxCxHxW到->BxCxHxW->BxCxHxW->BxCxHxW,其中e是膨脹率,它被設(shè)置為4。而不是像在正常的Bottlenecks區(qū)那樣變寬->變窄->變寬,而是相反,變窄->變寬->變窄。

在PyTorch中,實(shí)現(xiàn)如下

class InvertedResidual(nn.Sequential):

   def __init__(self, in_features: int, out_features: int, expansion: int = 4):

       expanded_features = in_features * expansion

       super().__init__(

           nn.Sequential(

               ResidualAdd(

                   nn.Sequential(

                      # narrow -> wide

                       Conv1X1BnReLU(in_features, expanded_features),

                       # wide -> wide

                       Conv3X3BnReLU(expanded_features, expanded_features),

                       # wide -> narrow

                       Conv1X1BnReLU(expanded_features, out_features, act=nn.Identity),

                   ),

                   shortcut=Conv1X1BnReLU(in_features, out_features)

                   if in_features ?。?out_features

                   else None,

               ),

               nn.ReLU(),

           )

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


在MobileNet中,只有當(dāng)輸入和輸出特征匹配時(shí),才會(huì)應(yīng)用殘差連接

class MobileNetLikeBlock(nn.Sequential):

   def __init__(self, in_features: int, out_features: int, expansion: int = 4):

       # use ResidualAdd if features match, otherwise a normal Sequential

       residual = ResidualAdd if in_features == out_features else nn.Sequential

       expanded_features = in_features * expansion

       super().__init__(

           nn.Sequential(

              residual(

                   nn.Sequential(

                       # narrow -> wide

                       Conv1X1BnReLU(in_features, expanded_features),

                       # wide -> wide

                       Conv3X3BnReLU(expanded_features, expanded_features),

                       # wide -> narrow

                       Conv1X1BnReLU(expanded_features, out_features, act=nn.Identity),

                   ),

               ),

               nn.ReLU(),

           )

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

MobileNetLikeBlock(32, 32)(x).shape


MBConv

MobileNet V2的構(gòu)建塊被稱(chēng)為MBConv。MBConv是具有深度可分離卷積的倒殘差的Linear BottleNecks層。

深度可分離卷積

深度可分離卷積采用一種技巧,將一個(gè)正常的3x3卷積夾在兩個(gè)卷積中,以減少參數(shù)數(shù)量。

第一個(gè)對(duì)每個(gè)輸入的通道應(yīng)用單個(gè)3x3濾波器,另一個(gè)對(duì)所有通道應(yīng)用1x1濾波器。

這與正常的3x3卷積相同,但你節(jié)省了參數(shù)。

然而它比我們現(xiàn)有硬件上的普通3x3慢得多。

下圖顯示了這個(gè)想法

通道中的不同顏色表示每個(gè)通道應(yīng)用的單個(gè)過(guò)濾器

PyTorch中:

class DepthWiseSeparableConv(nn.Sequential):

   def __init__(self, in_features: int, out_features: int):

       super().__init__(

           nn.Conv2d(in_features, in_features, kernel_size=3, groups=in_features),

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

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


第一次卷積通常稱(chēng)為depth,而第二次卷積稱(chēng)為point。讓我們統(tǒng)計(jì)參數(shù)量

sum(p.numel() for p in DepthWiseSeparableConv(32, 64).parameters() if p.requires_grad) 

輸出:2432

讓我們看一個(gè)普通的Conv2d

sum(p.numel() for p in nn.Conv2d(32, 64, kernel_size=3).parameters() if p.requires_grad)

輸出:18496

有很大的區(qū)別

實(shí)現(xiàn)MBConv

那么,讓我們創(chuàng)建一個(gè)完整的MBConv。

MBConv有幾個(gè)重要的細(xì)節(jié),標(biāo)準(zhǔn)化應(yīng)用于深度和點(diǎn)卷積,非線性?xún)H應(yīng)用于深度卷積(Linear Bottlenecks)。

class MBConv(nn.Sequential):

   def __init__(self, in_features: int, out_features: int, expansion: int = 4):

       residual = ResidualAdd if in_features == out_features else nn.Sequential

       expanded_features = in_features * expansion
       

       super().__init__(

           nn.Sequential(

               residual(

                   nn.Sequential(

                      # narrow -> wide

                       Conv1X1BnReLU(in_features, 

                                     expanded_features,

                                     act=nn.ReLU6

                                    ),
                       

                       # wide -> wide

                       Conv3X3BnReLU(expanded_features, 

                                     expanded_features, 

                                     groups=expanded_features,

                                     act=nn.ReLU6

                                    ),
                       

                       # here you can apply SE

                       # wide -> narrow

                       Conv1X1BnReLU(expanded_features, out_features, act=nn.Identity),

                   ),

               ),

               nn.ReLU(),

           )

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


Fused MBConv

EfficientNetV2中引入了融合倒殘差

所以基本上,由于深度卷積比較慢,他們將第一個(gè)和第二個(gè)卷積融合在一個(gè)3x3的卷積中(第3.2節(jié))。

       class FusedMBConv(nn.Sequential):

   def __init__(self, in_features: int, out_features: int, expansion: int = 4):

       residual = ResidualAdd if in_features == out_features else nn.Sequential

       expanded_features = in_features * expansion

       super().__init__(

           nn.Sequential(

               residual(

                   nn.Sequential(

                       Conv3X3BnReLU(in_features, 

                                     expanded_features, 

                                     act=nn.ReLU6

                                    ),

                       # here you can apply SE

                       # wide -> narrow

                       Conv1X1BnReLU(expanded_features, out_features, act=nn.Identity),

                   ),

               ),

               nn.ReLU(),

           )

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

結(jié)論

現(xiàn)在你應(yīng)該知道所有這些塊之間的區(qū)別以及它們背后的原因了!

       原文標(biāo)題 : Residual, BottleNeck, Linear BottleNeck, MBConv解釋

 
關(guān)鍵詞: 圖像識(shí)別
(文/ofweek)
 
反對(duì) 0 舉報(bào) 0 收藏 0 打賞 0 評(píng)論 0
0相關(guān)評(píng)論
免責(zé)聲明
本文為ofweek原創(chuàng)作品,作者: ofweek。歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明原文出處:http://www.uwf831.com/news/show-1674.html 。本文僅代表作者個(gè)人觀點(diǎn),本站未對(duì)其內(nèi)容進(jìn)行核實(shí),請(qǐng)讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,作者需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問(wèn)題,請(qǐng)及時(shí)聯(lián)系我們3101218373@qq.com。
 

(c)2008-2020 HUATAILIANHE.CN SYSTEM All Rights Reserved

豫B2-20160018-3