婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > pytorch實現(xiàn)ResNet結(jié)構(gòu)的實例代碼

pytorch實現(xiàn)ResNet結(jié)構(gòu)的實例代碼

熱門標(biāo)簽:激戰(zhàn)2地圖標(biāo)注 廣告地圖標(biāo)注app 陜西金融外呼系統(tǒng) 公司電話機器人 哈爾濱ai外呼系統(tǒng)定制 海南400電話如何申請 白銀外呼系統(tǒng) 唐山智能外呼系統(tǒng)一般多少錢 騰訊外呼線路

1.ResNet的創(chuàng)新

現(xiàn)在重新稍微系統(tǒng)的介紹一下ResNet網(wǎng)絡(luò)結(jié)構(gòu)。 ResNet結(jié)構(gòu)首先通過一個卷積層然后有一個池化層,然后通過一系列的殘差結(jié)構(gòu),最后再通過一個平均池化下采樣操作,以及一個全連接層的得到了一個輸出。ResNet網(wǎng)絡(luò)可以達到很深的層數(shù)的原因就是不斷的堆疊殘差結(jié)構(gòu)而來的。

1)亮點

網(wǎng)絡(luò)中的亮點 :

  • 超深的網(wǎng)絡(luò)結(jié)構(gòu)( 突破1000 層)
  • 提出residual 模塊
  • 使用Batch Normalization 加速訓(xùn)練( 丟棄dropout)

但是,一般來說,并不是一直的加深神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)就會得到一個更好的結(jié)果,一般太深的網(wǎng)絡(luò)會出現(xiàn)過擬合的現(xiàn)象嚴(yán)重,可能還沒有一些淺層網(wǎng)絡(luò)要好。

2)原因

其中有兩個原因:

  • 梯度消失或梯度爆炸

當(dāng)層數(shù)過多的時候,假設(shè)每一層的誤差梯度都是一個小于1的數(shù)值,當(dāng)進行方向傳播的過程中,每向前傳播一層,都要乘以一個小于1的誤差梯度,當(dāng)網(wǎng)絡(luò)越來越深時,所成的小于1的系數(shù)也就越來越多,此時梯度便越趨近于0,這樣梯度便會越來越小。這便會造成梯度消失的現(xiàn)象。

而當(dāng)所成的誤差梯度是一個大于1的系數(shù),而隨著網(wǎng)絡(luò)層數(shù)的加深,梯度便會越來越大,這便會造成梯度爆炸的現(xiàn)象。

  • 退化問題(degradation problem)

當(dāng)解決了梯度消失或者梯度爆炸的問題之后,其實網(wǎng)絡(luò)的效果可能還是不盡如意,還可能有退化問題。為此,ResNet提出了殘差結(jié)構(gòu)來解決這個退化問題。 也正是因為有這個殘差的結(jié)構(gòu),所以才可以搭建這么深的網(wǎng)絡(luò)。

2.ResNet的結(jié)構(gòu)

殘差結(jié)構(gòu)如圖所示

作圖是針對ResNet-18/34層淺層網(wǎng)絡(luò)的結(jié)構(gòu),右圖是ResNet-50/101/152層深層網(wǎng)絡(luò)的結(jié)構(gòu),其中注意:主分支與shortcut 的輸出特征矩陣shape。

一下表格為網(wǎng)絡(luò)的一些主要參數(shù)

可以看見,不同層數(shù)的網(wǎng)絡(luò)結(jié)構(gòu)其實框架是類似的,不同的至少堆疊的殘差結(jié)構(gòu)的數(shù)量。

1)淺層的殘差結(jié)構(gòu)

需要注意,有些殘差結(jié)構(gòu)的ShortCut是實線,而有的是虛線,這兩者是不同的。對于左圖來說,ShortCut是實線,這表明輸入與輸出的shape是一樣的,所以可以直接的進行相加。而對于右圖來說,其輸入的shape與輸出的shape是不一樣的,這時候需要調(diào)整步長stribe與kernel size來使得兩條路(主分支與捷徑分支)所處理好的shape是一模一樣的。

2)深層的殘差結(jié)構(gòu)

同樣的,需要注意,主分支與shortcut 的輸出特征矩陣shape必須相同,同樣的通過步長來調(diào)整。

但是注意原論文中:

右側(cè)虛線殘差結(jié)構(gòu)的主分支上、第一個1x1卷積層的步距是2,第二個3x3卷積層的步距是1.

而在pytorch官方實現(xiàn)的過程中是第一個1x1卷積層的步距是1,第二個3x3卷積層步距是2,這樣能夠在ImageNet的top1上提升大概0.5%的準(zhǔn)確率。

所以在conv3_x,conv4_x,conv5_x中所對應(yīng)的殘差結(jié)構(gòu)的第一層,都是指虛線的殘差結(jié)構(gòu),其他的殘差結(jié)構(gòu)是實線的殘差結(jié)構(gòu)。

3)總結(jié)

對于每個大模塊中的第一個殘差結(jié)構(gòu),需要通過虛線分支來調(diào)整殘差結(jié)構(gòu)的輸入與輸出是同一個shape。此時使用了下采樣的操作函數(shù)。
對于每個大模塊中的其他剩余的殘差結(jié)構(gòu),只需要通過實線分支來調(diào)整殘差網(wǎng)絡(luò)結(jié)構(gòu),因為其輸出和輸入本身就是同一個shape的。

對于第一個大模塊的第一個殘差結(jié)構(gòu),其第二個3x3的卷積中,步長是1的,而其他的三個大模塊的步長均為2.
在每一個大模塊的維度變換中,主要是第一個殘差結(jié)構(gòu)使得shape減半,而模塊中其他的殘差結(jié)構(gòu)都是沒有改變shape的。也真因為沒有改變shape,所以這些殘差結(jié)構(gòu)才可以直接的通過實線進行相加。

3.Batch Normalization

Batch Normalization的目的是使我們的一批(Batch)特征矩陣feature map滿足均值為0,方差為1的分布規(guī)律。

其中:
μ,σ_2在正向傳播過程中統(tǒng)計得到
γ,β在反向傳播過程中訓(xùn)練得到

Batch Normalization是google團隊在2015年論文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》提出的。通過該方法能夠加速網(wǎng)絡(luò)的收斂并提升準(zhǔn)確率。

具體的相關(guān)原理見:Batch Normalization詳解以及pytorch實驗

4.參考代碼

import torch
import torch.nn as nn

# 分類數(shù)目
num_class = 5
# 各層數(shù)目
resnet18_params = [2, 2, 2, 2]
resnet34_params = [3, 4, 6, 3]
resnet50_params = [3, 4, 6, 3]
resnet101_params = [3, 4, 23, 3]
resnet152_params = [3, 8, 36, 3]


# 定義Conv1層
def Conv1(in_planes, places, stride=2):
    return nn.Sequential(
        nn.Conv2d(in_channels=in_planes,out_channels=places,kernel_size=7,stride=stride,padding=3, bias=False),
        nn.BatchNorm2d(places),
        nn.ReLU(inplace=True),
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
    )


# 淺層的殘差結(jié)構(gòu)
class BasicBlock(nn.Module):
    def __init__(self,in_places,places, stride=1,downsampling=False, expansion = 1):
        super(BasicBlock,self).__init__()
        self.expansion = expansion
        self.downsampling = downsampling

        # torch.Size([1, 64, 56, 56]), stride = 1
        # torch.Size([1, 128, 28, 28]), stride = 2
        # torch.Size([1, 256, 14, 14]), stride = 2
        # torch.Size([1, 512, 7, 7]), stride = 2
        self.basicblock = nn.Sequential(
            nn.Conv2d(in_channels=in_places, out_channels=places, kernel_size=3, stride=stride, padding=1, bias=False),
            nn.BatchNorm2d(places),
            nn.ReLU(inplace=True),
            nn.Conv2d(in_channels=places, out_channels=places, kernel_size=3, stride=1, padding=1, bias=False),
            nn.BatchNorm2d(places * self.expansion),
        )

        # torch.Size([1, 64, 56, 56])
        # torch.Size([1, 128, 28, 28])
        # torch.Size([1, 256, 14, 14])
        # torch.Size([1, 512, 7, 7])
        # 每個大模塊的第一個殘差結(jié)構(gòu)需要改變步長
        if self.downsampling:
            self.downsample = nn.Sequential(
                nn.Conv2d(in_channels=in_places, out_channels=places*self.expansion, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(places*self.expansion)
            )
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        # 實線分支
        residual = x
        out = self.basicblock(x)

        # 虛線分支
        if self.downsampling:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)
        return out


# 深層的殘差結(jié)構(gòu)
class Bottleneck(nn.Module):

    # 注意:默認 downsampling=False
    def __init__(self,in_places,places, stride=1,downsampling=False, expansion = 4):
        super(Bottleneck,self).__init__()
        self.expansion = expansion
        self.downsampling = downsampling

        self.bottleneck = nn.Sequential(
            # torch.Size([1, 64, 56, 56]),stride=1
            # torch.Size([1, 128, 56, 56]),stride=1
            # torch.Size([1, 256, 28, 28]), stride=1
            # torch.Size([1, 512, 14, 14]), stride=1
            nn.Conv2d(in_channels=in_places,out_channels=places,kernel_size=1,stride=1, bias=False),
            nn.BatchNorm2d(places),
            nn.ReLU(inplace=True),
            # torch.Size([1, 64, 56, 56]),stride=1
            # torch.Size([1, 128, 28, 28]), stride=2
            # torch.Size([1, 256, 14, 14]), stride=2
            # torch.Size([1, 512, 7, 7]), stride=2
            nn.Conv2d(in_channels=places, out_channels=places, kernel_size=3, stride=stride, padding=1, bias=False),
            nn.BatchNorm2d(places),
            nn.ReLU(inplace=True),
            # torch.Size([1, 256, 56, 56]),stride=1
            # torch.Size([1, 512, 28, 28]), stride=1
            # torch.Size([1, 1024, 14, 14]), stride=1
            # torch.Size([1, 2048, 7, 7]), stride=1
            nn.Conv2d(in_channels=places, out_channels=places * self.expansion, kernel_size=1, stride=1, bias=False),
            nn.BatchNorm2d(places * self.expansion),
        )

        # torch.Size([1, 256, 56, 56])
        # torch.Size([1, 512, 28, 28])
        # torch.Size([1, 1024, 14, 14])
        # torch.Size([1, 2048, 7, 7])
        if self.downsampling:
            self.downsample = nn.Sequential(
                nn.Conv2d(in_channels=in_places, out_channels=places*self.expansion, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(places*self.expansion)
            )
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        # 實線分支
        residual = x
        out = self.bottleneck(x)

        # 虛線分支
        if self.downsampling:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out


class ResNet(nn.Module):
    def __init__(self,blocks, blockkinds, num_classes=num_class):
        super(ResNet,self).__init__()

        self.blockkinds = blockkinds
        self.conv1 = Conv1(in_planes = 3, places= 64)

        # 對應(yīng)淺層網(wǎng)絡(luò)結(jié)構(gòu)
        if self.blockkinds == BasicBlock:
            self.expansion = 1
            # 64 -> 64
            self.layer1 = self.make_layer(in_places=64, places=64, block=blocks[0], stride=1)
            # 64 -> 128
            self.layer2 = self.make_layer(in_places=64, places=128, block=blocks[1], stride=2)
            # 128 -> 256
            self.layer3 = self.make_layer(in_places=128, places=256, block=blocks[2], stride=2)
            # 256 -> 512
            self.layer4 = self.make_layer(in_places=256, places=512, block=blocks[3], stride=2)

            self.fc = nn.Linear(512, num_classes)

        # 對應(yīng)深層網(wǎng)絡(luò)結(jié)構(gòu)
        if self.blockkinds == Bottleneck:
            self.expansion = 4
            # 64 -> 64
            self.layer1 = self.make_layer(in_places = 64, places= 64, block=blocks[0], stride=1)
            # 256 -> 128
            self.layer2 = self.make_layer(in_places = 256,places=128, block=blocks[1], stride=2)
            # 512 -> 256
            self.layer3 = self.make_layer(in_places=512,places=256, block=blocks[2], stride=2)
            # 1024 -> 512
            self.layer4 = self.make_layer(in_places=1024,places=512, block=blocks[3], stride=2)

            self.fc = nn.Linear(2048, num_classes)

        self.avgpool = nn.AvgPool2d(7, stride=1)

        # 初始化網(wǎng)絡(luò)結(jié)構(gòu)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                # 采用了何凱明的初始化方法
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def make_layer(self, in_places, places, block, stride):

        layers = []

        # torch.Size([1, 64, 56, 56])  -> torch.Size([1, 256, 56, 56]), stride=1 故w,h不變
        # torch.Size([1, 256, 56, 56]) -> torch.Size([1, 512, 28, 28]), stride=2 故w,h變
        # torch.Size([1, 512, 28, 28]) -> torch.Size([1, 1024, 14, 14]),stride=2 故w,h變
        # torch.Size([1, 1024, 14, 14]) -> torch.Size([1, 2048, 7, 7]), stride=2 故w,h變
        # 此步需要通過虛線分支,downsampling=True
        layers.append(self.blockkinds(in_places, places, stride, downsampling =True))

        # torch.Size([1, 256, 56, 56]) -> torch.Size([1, 256, 56, 56])
        # torch.Size([1, 512, 28, 28]) -> torch.Size([1, 512, 28, 28])
        # torch.Size([1, 1024, 14, 14]) -> torch.Size([1, 1024, 14, 14])
        # torch.Size([1, 2048, 7, 7]) -> torch.Size([1, 2048, 7, 7])
        # print("places*self.expansion:", places*self.expansion)
        # print("block:", block)
        # 此步需要通過實線分支,downsampling=False, 每個大模塊的第一個殘差結(jié)構(gòu)需要改變步長
        for i in range(1, block):
            layers.append(self.blockkinds(places*self.expansion, places))

        return nn.Sequential(*layers)


    def forward(self, x):

        # conv1層
        x = self.conv1(x)   # torch.Size([1, 64, 56, 56])

        # conv2_x層
        x = self.layer1(x)  # torch.Size([1, 256, 56, 56])
        # conv3_x層
        x = self.layer2(x)  # torch.Size([1, 512, 28, 28])
        # conv4_x層
        x = self.layer3(x)  # torch.Size([1, 1024, 14, 14])
        # conv5_x層
        x = self.layer4(x)  # torch.Size([1, 2048, 7, 7])

        x = self.avgpool(x) # torch.Size([1, 2048, 1, 1]) / torch.Size([1, 512])
        x = x.view(x.size(0), -1)   # torch.Size([1, 2048]) / torch.Size([1, 512])
        x = self.fc(x)      # torch.Size([1, 5])

        return x

def ResNet18():
    return ResNet(resnet18_params, BasicBlock)

def ResNet34():
    return ResNet(resnet34_params, BasicBlock)

def ResNet50():
    return ResNet(resnet50_params, Bottleneck)

def ResNet101():
    return ResNet(resnet101_params, Bottleneck)

def ResNet152():
    return ResNet(resnet152_params, Bottleneck)


if __name__=='__main__':
    # model = torchvision.models.resnet50()

    # 模型測試
    # model = ResNet18()
    # model = ResNet34()
    # model = ResNet50()
    # model = ResNet101()
    model = ResNet152()
    # print(model)

    input = torch.randn(1, 3, 224, 224)
    out = model(input)
    print(out.shape)

以上就是pytorch實現(xiàn)ResNet結(jié)構(gòu)的實例代碼的詳細內(nèi)容,更多關(guān)于pytorch ResNet結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • 關(guān)于PyTorch源碼解讀之torchvision.models
  • PyTorch實現(xiàn)ResNet50、ResNet101和ResNet152示例
  • 關(guān)于ResNeXt網(wǎng)絡(luò)的pytorch實現(xiàn)
  • PyTorch數(shù)據(jù)讀取的實現(xiàn)示例
  • pytorch教程resnet.py的實現(xiàn)文件源碼分析

標(biāo)簽:鷹潭 惠州 益陽 黑龍江 黔西 常德 上海 四川

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《pytorch實現(xiàn)ResNet結(jié)構(gòu)的實例代碼》,本文關(guān)鍵詞  pytorch,實現(xiàn),ResNet,結(jié)構(gòu),的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《pytorch實現(xiàn)ResNet結(jié)構(gòu)的實例代碼》相關(guān)的同類信息!
  • 本頁收集關(guān)于pytorch實現(xiàn)ResNet結(jié)構(gòu)的實例代碼的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    婷婷久久综合九色国产成人| 国产乱码精品一区二区三| 久久精品亚洲精品国产欧美kt∨ | 国产成人在线电影| 成人免费高清视频在线观看| 成人晚上爱看视频| 欧美亚洲免费在线一区| 久久午夜国产精品| 亚洲第一av色| 日本精品一区二区三区高清| 亚洲午夜免费电影| 日韩av电影免费观看高清完整版在线观看 | 国产精品热久久久久夜色精品三区 | 亚洲狼人国产精品| 成人黄色一级视频| 中文字幕一区二区三区在线播放 | 国产精品国产三级国产三级人妇 | 成人av综合一区| 欧美—级在线免费片| 秋霞午夜av一区二区三区| 欧美精品一二三| 国产一区二区精品久久| 国产精品国模大尺度视频| 成人久久18免费网站麻豆| 精品国产乱码久久久久久1区2区| 韩国女主播一区| 久久久综合网站| 色综合天天综合给合国产| 亚州成人在线电影| 久久久精品2019中文字幕之3| 91亚洲资源网| 日本成人在线不卡视频| 久久在线免费观看| 欧美日韩美少妇| 国产一区二区三区香蕉| 日韩精品五月天| 亚洲日韩欧美一区二区在线| 欧美一区二区三区白人| 粉嫩aⅴ一区二区三区四区五区 | 亚洲国产精品视频| 国产精品久久久99| 日韩欧美一级片| 7777精品伊人久久久大香线蕉最新版 | 日韩午夜激情免费电影| 欧美日韩1234| 欧美日本乱大交xxxxx| 欧美欧美午夜aⅴ在线观看| 欧美一区二区三区在线看| 欧美日韩视频不卡| 91麻豆精品国产91久久久久久| 色av综合在线| 欧美性猛交一区二区三区精品| 欧美日韩中文字幕一区二区| 欧美日韩不卡视频| 欧美日韩高清在线播放| 91精品国产综合久久香蕉的特点| 欧美精品tushy高清| 精品国产一区二区在线观看| 精品国一区二区三区| 亚洲天堂精品视频| 波多野结衣在线一区| 中文字幕在线一区免费| 欧美最猛性xxxxx直播| 亚洲一区自拍偷拍| 日本一区二区综合亚洲| 久久精品综合网| 亚洲日本乱码在线观看| 成人高清免费观看| 国产欧美日韩在线| 91色九色蝌蚪| 欧美美女bb生活片| 亚洲视频在线一区二区| 国产一区二区三区免费看| 91在线国产观看| 国产精品成人免费| 国产九色精品成人porny| 欧美日韩亚洲不卡| 亚洲激情中文1区| 欧美最猛性xxxxx直播| 亚洲综合色视频| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 亚洲一二三区不卡| 欧美va在线播放| 亚洲欧美激情在线| 欧美人体做爰大胆视频| 国产成人午夜精品影院观看视频 | 国产精品美女视频| 丝袜a∨在线一区二区三区不卡| 日韩精品乱码免费| 97aⅴ精品视频一二三区| 国产91精品一区二区| 欧美色爱综合网| 日韩欧美色电影| 色综合久久久久| 精品毛片乱码1区2区3区| 欧美性猛片aaaaaaa做受| 欧美成va人片在线观看| 精品久久久久久久久久久院品网| 精品国精品国产| 日韩在线卡一卡二| 久久久精品中文字幕麻豆发布| 夜夜嗨av一区二区三区网页 | 夜夜嗨av一区二区三区中文字幕| 欧美精品一卡两卡| 捆绑紧缚一区二区三区视频 | 亚洲欧美一区二区三区孕妇| 日韩美一区二区三区| 99精品久久久久久| 国产成人亚洲精品狼色在线| 亚洲成av人影院| 亚洲精品日产精品乱码不卡| 久久午夜电影网| 国产精品第四页| 日韩免费看网站| 精品国产91洋老外米糕| 欧洲激情一区二区| 欧美性猛片xxxx免费看久爱| 色久综合一二码| 在线免费观看一区| 欧美精品一二三区| 精品国产免费一区二区三区四区| 国产成人免费网站| 国产麻豆成人精品| 色婷婷精品久久二区二区蜜臂av| 日韩一区二区三区av| 国产精品免费视频观看| 精品在线观看免费| 99久久婷婷国产综合精品电影| 精品一区二区三区的国产在线播放| 奇米888四色在线精品| 亚洲成av人**亚洲成av**| 亚洲色图制服丝袜| 亚洲综合久久av| 亚洲一区二区三区激情| 欧美丝袜自拍制服另类| 精品制服美女久久| 亚洲成人自拍偷拍| 91精品福利视频| 亚洲一区二区免费视频| 日本精品一区二区三区四区的功能| 亚洲国产视频网站| 欧美性色黄大片手机版| 欧美性生活影院| 欧美一级淫片007| 中文字幕中文在线不卡住| 日韩精品国产精品| 欧美无砖专区一中文字| 最新热久久免费视频| 老鸭窝一区二区久久精品| 欧美日韩高清一区| 日韩国产精品大片| 欧美精品在线视频| 蜜臀a∨国产成人精品| 欧美精品久久一区二区三区| 国产日产欧美一区| av电影在线不卡| 亚洲综合一区二区精品导航| 色哟哟一区二区三区| 亚洲一区在线观看免费 | 欧美一级专区免费大片| 国产在线精品一区二区夜色| 欧美日韩国产系列| 亚洲一区二区三区不卡国产欧美| 欧美日韩免费视频| 成人手机电影网| 亚洲一区二区三区在线| 久久午夜老司机| 欧美日本免费一区二区三区| 欧美激情中文字幕一区二区| 91视频免费播放| 亚洲人成在线观看一区二区| 欧美视频在线播放| 国产一区欧美日韩| 亚洲欧美日韩国产另类专区| 国产不卡在线播放| 欧美电影免费观看高清完整版在| 麻豆精品蜜桃视频网站| 国产精品免费视频一区| 91精品1区2区| 国产一区二区视频在线播放| 国产精品久久看| 欧美一区二区三区视频| 国产精品66部| 亚洲欧美国产毛片在线| 久久网站热最新地址| 93久久精品日日躁夜夜躁欧美| 日韩av中文在线观看| 中文字幕亚洲不卡| 精品国产91久久久久久久妲己 | 久久精品视频一区二区| 欧美少妇bbb| 91亚洲国产成人精品一区二区三| 日本最新不卡在线| 国产精品久久久99| 国产欧美综合在线| 欧美一区二区三区四区高清| 91天堂素人约啪| 国产主播一区二区三区| 青青草原综合久久大伊人精品 | 亚洲日本电影在线|