日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

GhostNet

發(fā)布時(shí)間:2023/12/31 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GhostNet 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

論文地址

文章目錄

  • 前言
  • 一、論文解讀
    • 1.Ghost卷積設(shè)計(jì)
    • 2.Gbneck殘差模塊設(shè)計(jì)
    • 3.GhostNet網(wǎng)絡(luò)架構(gòu)
  • 二、代碼實(shí)現(xiàn)
    • 1.卷積模塊
    • 2.殘差模塊實(shí)現(xiàn)
    • 3.網(wǎng)絡(luò)實(shí)現(xiàn)
  • 三、驗(yàn)證模型
  • 總結(jié)


前言

Ghostnet提出自己的架構(gòu)設(shè)計(jì)思路:特征圖的冗余是深度神經(jīng)網(wǎng)絡(luò)成功的一個(gè)重要特征。Ghostnet傾向于以一種代價(jià)低廉的線性操作來(lái)獲取它們,而不是避免冗余的特性映射


一、論文解讀

1.Ghost卷積設(shè)計(jì)

在本文中,我們引入了一個(gè)新的Ghost模塊,用更少的參數(shù)生成更多的特征。具體來(lái)說(shuō),將深度神經(jīng)網(wǎng)絡(luò)中的普通卷積層分為兩部分。第一部分涉及普通的卷積,但它們的總數(shù)將被嚴(yán)格控制。給定第一部分的固有特征圖,然后應(yīng)用一系列簡(jiǎn)單的線性操作來(lái)生成更多的特征圖。在不改變輸出特征圖大小的情況下,與普通卷積神經(jīng)網(wǎng)絡(luò)相比,Ghost模塊所需的參數(shù)總數(shù)和計(jì)算復(fù)雜度都有所降低。實(shí)現(xiàn)過(guò)程如下:
首先通過(guò)主卷積生成基本特征圖集合:X為輸入特征圖(尺寸參數(shù)為h:寬度,w:長(zhǎng)度,c:通道數(shù)),f’為卷積層(尺寸參數(shù)為c:輸入通道數(shù),k:卷積核尺寸大小,m為輸出通道數(shù)),X在與卷積層卷積后輸出特征圖集合Y’(尺寸參數(shù)為h’,w’,m)。此處省略了偏置參數(shù)。

然后,對(duì)輸出的基本特征圖集合Y’做線性變化,以生成Ghost特征圖。其中 fi是基本特征圖集合Y’中第i個(gè)特征圖, 是通過(guò) 生成的第j個(gè)Ghost特征圖所做的線性變化,此處操作即指對(duì)應(yīng)基本特征圖集合中每個(gè)特征圖通過(guò)線性操作生成s個(gè)Ghost特征圖,最后一個(gè)線性操作為恒等映射以保留固有特征。

最后輸出ms張?zhí)卣鲌D來(lái)作為最終輸出特征圖集合,相比于直接通過(guò)用ckkn(n=m*s)的卷積層做卷積,其計(jì)算量大幅減小(衰減比值大約為s)。整個(gè)特征圖變化過(guò)程如下圖:

2.Gbneck殘差模塊設(shè)計(jì)

此處作者參照Resnet的殘差模塊設(shè)計(jì)出Ghost瓶頸模塊,ghost瓶頸主要由兩個(gè)堆疊的ghost模塊組成。第一個(gè)Ghost模塊作為擴(kuò)展層,增加通道的數(shù)量。我們把輸出通道的數(shù)量與輸入通道的數(shù)量之比稱為擴(kuò)展比。第二個(gè)Ghost模塊減少通道數(shù)量以匹配捷徑路徑。然后在這兩個(gè)Ghost模塊的輸入和輸出之間連接快捷方式。每一層之后都使用批處理歸一化(BN)和ReLU非線性。

3.GhostNet網(wǎng)絡(luò)架構(gòu)

以本文之愚見,網(wǎng)絡(luò)架構(gòu)與殘差模塊設(shè)計(jì)基本是延續(xù)前人的思想,Ghostnet最重要的創(chuàng)新點(diǎn)在于卷積的設(shè)計(jì)(確實(shí)NB)!

二、代碼實(shí)現(xiàn)

源代碼比較惡心,嫖幾行代碼根本無(wú)法實(shí)現(xiàn),貌似它把所有的操作都重寫了一遍,對(duì)于我們這種想快速嫖代碼的人來(lái)說(shuō)就很難受了,沒得辦法,只有參考源代碼自己寫一個(gè)簡(jiǎn)單的出來(lái)了。前面說(shuō)了最重要的創(chuàng)新是卷積模塊的設(shè)計(jì),那如果能嫖卷積模塊的設(shè)計(jì),剩下來(lái)的不都是之前論文實(shí)現(xiàn)的工作了嗎?當(dāng)然自己寫出的代碼還是不敢直接就用,還是對(duì)比下模型參數(shù)及計(jì)算量的好。經(jīng)過(guò)驗(yàn)證,果然嫖代碼能力天賦異稟的我完美實(shí)現(xiàn)了該網(wǎng)絡(luò)。
各位同志如果要嫖作者大大的代碼的話,先交個(gè)一鍵三連的學(xué)費(fèi),謝謝各位!

1.卷積模塊

代碼如下:

class Ghostconv(nn.Module):"""Ghostnet的基礎(chǔ)卷積模塊"""def __init__(self,in_channels,out_channels):super(Ghostconv, self).__init__()main_channels=math.ceil(0.5*out_channels)#主卷積輸出通道數(shù)cheap_channels=out_channels-main_channels#通過(guò)線性變化廉價(jià)操作得到的通道數(shù)self.piontconv1=nn.Sequential(nn.Conv2d(in_channels,main_channels,kernel_size=1,stride=1,bias=False),nn.BatchNorm2d(main_channels,eps=1e-5),nn.ReLU(inplace=True))self.linear_option=nn.Sequential(nn.Conv2d(main_channels,cheap_channels,kernel_size=3,padding=1,stride=1,groups=cheap_channels),nn.BatchNorm2d(cheap_channels,eps=1e-5),nn.ReLU(inplace=True))#線性操作通過(guò)深度可分離卷積實(shí)現(xiàn),其中一半的特征圖通過(guò)1*1卷積實(shí)現(xiàn),一半的特征圖由線性操作提供def forward(self,x):x=self.piontconv1(x)y=self.linear_option(x)return torch.cat((x,y),dim=1)

2.殘差模塊實(shí)現(xiàn)

代碼如下(示例):

class GhostUnit(nn.Module):"""實(shí)現(xiàn)基本殘差塊和降維殘差塊"""def __init__(self,in_channels,out_channels,stride,use_se,ex_factor,k_size,padding):super(GhostUnit, self).__init__()# stride為2,3*3或5*5需要做下采樣操作self.stride=strideself.use_se=use_seself.res=nn.Sequential()mid_channels=math.ceil(ex_factor*in_channels)# 主模塊self.expconv=Ghostconv(in_channels,mid_channels)if stride==2:self.dwconv=nn.Sequential(nn.Conv2d(mid_channels,mid_channels,stride=stride,kernel_size=k_size,groups=mid_channels,bias=False,padding=padding),nn.BatchNorm2d(mid_channels,eps=1e-5),nn.ReLU(inplace=True))# 此處卷積核大小有兩種可能:3或5if stride==2 or in_channels!=out_channels:self.res=nn.Sequential(nn.Conv2d(in_channels,in_channels,kernel_size=3,groups=in_channels,padding=1,stride=stride,bias=False),nn.BatchNorm2d(in_channels,eps=1e-5),nn.ReLU(inplace=True),nn.Conv2d(in_channels,out_channels,kernel_size=1,stride=1,bias=False),nn.BatchNorm2d(out_channels))#此處不對(duì)1*1卷積的結(jié)果做激活操作self.pwconv=Ghostconv(mid_channels,out_channels)#SE模塊if use_se==True:self.se=SElayer(4,mid_channels)def forward(self,x):residual=self.res(x)x=self.expconv(x)if self.stride==2:x=self.dwconv(x)if self.use_se:x=self.se(x)x=self.pwconv(x)return x+residual

3.網(wǎng)絡(luò)實(shí)現(xiàn)

代碼如下:

class Ghostnet(nn.Module):def __init__(self,num_calss,width_ratio=1):super(Ghostnet, self).__init__()self.inital=nn.Sequential(nn.Conv2d(in_channels=3,out_channels=int(16*width_ratio),kernel_size=3,padding=1,stride=2,bias=False),nn.BatchNorm2d(int(16*width_ratio)),nn.ReLU(inplace=True))self.block1=nn.Sequential(GhostUnit(in_channels=int(16*width_ratio),out_channels=int(16*width_ratio),stride=1,use_se=False,ex_factor=1,k_size=3,padding=1),GhostUnit(in_channels=int(16*width_ratio),out_channels=int(24*width_ratio),stride=2,use_se=False,ex_factor=3,k_size=3,padding=1))self.block2 = nn.Sequential(GhostUnit(in_channels=int(24*width_ratio), out_channels=int(24*width_ratio), stride=1, use_se=False, ex_factor=3, k_size=3, padding=1),GhostUnit(in_channels=int(24*width_ratio), out_channels=int(40*width_ratio), stride=2, use_se=True, ex_factor=3, k_size=5, padding=2))self.block3 = nn.Sequential(GhostUnit(in_channels=int(40*width_ratio), out_channels=int(40*width_ratio), stride=1, use_se=True, ex_factor=3, k_size=5, padding=2),GhostUnit(in_channels=int(40*width_ratio), out_channels=int(80*width_ratio), stride=2, use_se=False, ex_factor=6, k_size=3, padding=1))self.block4 = nn.Sequential(GhostUnit(in_channels=int(80*width_ratio), out_channels=int(80*width_ratio), stride=1, use_se=False, ex_factor=2.5, k_size=3, padding=1),GhostUnit(in_channels=int(80*width_ratio), out_channels=int(80*width_ratio), stride=1, use_se=False, ex_factor=2.3, k_size=3, padding=1),GhostUnit(in_channels=int(80*width_ratio), out_channels=int(80*width_ratio), stride=1, use_se=False, ex_factor=2.3, k_size=3, padding=1),GhostUnit(in_channels=int(80*width_ratio), out_channels=int(112*width_ratio), stride=1, use_se=True, ex_factor=6, k_size=3, padding=1),GhostUnit(in_channels=int(112*width_ratio), out_channels=int(112*width_ratio), stride=1, use_se=True, ex_factor=6, k_size=3, padding=1),GhostUnit(in_channels=int(112*width_ratio), out_channels=int(160*width_ratio), stride=2, use_se=True, ex_factor=6, k_size=5, padding=2),)self.block5 = nn.Sequential(GhostUnit(in_channels=int(160*width_ratio), out_channels=int(160*width_ratio), stride=1, use_se=False, ex_factor=6, k_size=5, padding=2),GhostUnit(in_channels=int(160*width_ratio), out_channels=int(160*width_ratio), stride=1, use_se=True, ex_factor=6, k_size=5, padding=2),GhostUnit(in_channels=int(160*width_ratio), out_channels=int(160*width_ratio), stride=1, use_se=False, ex_factor=6, k_size=5, padding=2),GhostUnit(in_channels=int(160*width_ratio), out_channels=int(160*width_ratio), stride=1, use_se=True, ex_factor=6, k_size=5, padding=2),)self.conv_last=nn.Sequential(nn.Conv2d(in_channels=int(160*width_ratio),out_channels=960,kernel_size=1,stride=1,bias=False),nn.BatchNorm2d(960),nn.ReLU(inplace=True))self.pool=nn.AdaptiveAvgPool2d(1)self.finally_conv=nn.Conv2d(in_channels=960,out_channels=1280,kernel_size=1,stride=1,bias=True)self.fc=nn.Linear(in_features=1280,out_features=num_calss)def forward(self,x):x=self.inital(x)x=self.block1(x)x=self.block2(x)x = self.block3(x)x = self.block4(x)x = self.block5(x)x=self.conv_last(x)x=self.pool(x)x=self.finally_conv(x)x=x.view(x.size(0),-1)x=self.fc(x)return F.softmax(x,dim=1)

三、驗(yàn)證模型

代碼如下:

with torch.cuda.device(0):net = Ghostnet(1000,1)macs, params = get_model_complexity_info(net, (3, 224, 224), as_strings=True,print_per_layer_stat=True, verbose=True)print('{:<30} {:<8}'.format('Computational complexity: ', macs))print('{:<30} {:<8}'.format('Number of parameters: ', params))

原文中給出了模型的參數(shù)量和計(jì)算量,這不就可以驗(yàn)證一下模型有沒有問(wèn)題嗎!

我模型跑出來(lái)的參數(shù)量(Weight)和計(jì)算量(FLOPs)如下:
1)當(dāng)寬度因子取到0.5時(shí):

這里和2.6M的Weight及42M的FLOPs相差無(wú)幾!
2)當(dāng)寬度因子取到1時(shí):

這里和5.2M的Weight及142M的FLOPs差的一般!
總的來(lái)說(shuō):還行(此處省略一萬(wàn)只草泥馬)!!!

總結(jié)

本文介紹了GhostNet的核心思想及其代碼實(shí)現(xiàn),以供大家交流討論!
往期回顧:
(1)CBAM論文解讀+CBAM-ResNeXt的Pytorch實(shí)現(xiàn)
(2)SENet論文解讀及代碼實(shí)例
(3)ShuffleNet-V1論文理解及代碼復(fù)現(xiàn)
(4) ShuffleNet-V2論文理解及代碼復(fù)現(xiàn)
下期預(yù)告:
EfficientNet論文閱讀及代碼實(shí)現(xiàn)

總結(jié)

以上是生活随笔為你收集整理的GhostNet的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。