国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MobileNetV2原理說明及實踐落地

這篇具有很好參考價值的文章主要介紹了MobileNetV2原理說明及實踐落地。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文參考:

輕量級網(wǎng)絡——MobileNetV2_Clichong的博客-CSDN博客_mobilenetv2

1、MobileNetV2介紹

MobileNetV1主要是提出了可分離卷積的概念,大大減少了模型的參數(shù)個數(shù),從而縮小了計算量。但是在CenterNet算法中作為BackBone效果并不佳,模型收斂效果不好導致目標檢測的準確率不高。

MobileNetV2在MobileNetV1的DW和PW的基礎上進行了優(yōu)化,使得準確率更高,作為CenterNet算法的BackBone效果也可以。它的兩個亮點是:

  • Inverted Residuals:倒殘差結構
  • Linear Bottlenecks:結構的最后一層采用線性層

2、MobileNetV2的結構

(1)倒殘差結構

mobilenetv2,神經(jīng)網(wǎng)絡,深度學習,計算機視覺,目標檢測

ResNet網(wǎng)絡:殘差結構是先用1*1卷積降維 再升維 的操作,所以兩頭大中間小。

MobileNetV2中,殘差結構是先用1*1卷積升維 再降維 的操作,所以兩頭小中間大。

在MobileNetV2中采用了新的激活函數(shù):ReLU6,它的定義如下:

mobilenetv2,神經(jīng)網(wǎng)絡,深度學習,計算機視覺,目標檢測

(2)線性Bottlenecks

針對倒殘差結構最后一層的卷積層,采用了線性的激活函數(shù)(f(x)=x,可以認為沒有激活函數(shù)),而不是使用ReLU6激活函數(shù)。

原因解釋:

mobilenetv2,神經(jīng)網(wǎng)絡,深度學習,計算機視覺,目標檢測

?ReLU激活函數(shù)對于低維的信息可能會造成比較大的損失,而對于高維的特征信息造成的損失很小。而且由于倒殘差結構是兩頭小中間大,所以輸出的是一個低維的特征信息。所以使用一個線性的激活函數(shù)避免特征損失。

低維解釋:低維針對的是channel,低維意味著[batch, channel, height, width]中的height和width還較大。

(3)整體結構

mobilenetv2,神經(jīng)網(wǎng)絡,深度學習,計算機視覺,目標檢測

當stride=1且輸入特征矩陣與輸出特征矩陣shape相同時才有shortcut鏈接。

?3、MobileNetV2的pytorch實現(xiàn)

import torch
import torch.nn as nn
import torchvision

# 分類個數(shù)
num_class = 5

# DW卷積
def Conv3x3BNReLU(in_channels, out_channels, stride, groups):
    return nn.Sequential(
        # stride=2,wh減半; stride=1,wh不變
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, stride=stride, padding=1, groups=groups),
        nn.BatchNorm2d(out_channels),
        nn.ReLU6(inplace=True)
    )

# PW卷積
def Conv1x1BNReLU(in_channels, out_channels):
    return nn.Sequential(
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
        nn.BatchNorm2d(out_channels),
        nn.ReLU6(inplace=True)
    )

# PW卷積(Linear)沒有使用激活函數(shù)
def Conv1x1BN(in_channels, out_channels):
    return nn.Sequential(
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
        nn.BatchNorm2d(out_channels)
    )


class InvertedResidual(nn.Module):
    # t為擴展因子
    def __init__(self, in_channels, out_channels, expansion_factor, stride):
        super(InvertedResidual, self).__init__()
        self.stride = stride
        self.in_channels = in_channels
        self.out_channels = out_channels
        mid_channels = (in_channels * expansion_factor)

        # 先1*1卷積升維,再1*1卷積降維
        self.bottleneck = nn.Sequential(
            # 升維操作
            Conv1x1BNReLU(in_channels, mid_channels),
            # DW卷積,降低參數(shù)量
            Conv3x3BNReLU(mid_channels, mid_channels, stride, groups=mid_channels),
            # 降維操作
            Conv1x1BN(mid_channels, out_channels)
        )

        # stride=1才有shortcut,此方法讓原本不相同的channels相同
        if self.stride == 1:
            self.shortcut = Conv1x1BN(in_channels, out_channels)

    def forward(self, x):
        out = self.bottleneck(x)
        out = (out + self.shortcut(x)) if self.stride == 1 else out
        return out

class MobileNetV2(nn.Module):
    def make_layer(self, in_channels, out_channels, stride, factor, block_num):
        layers = []
        layers.append(InvertedResidual(in_channels, out_channels, factor, stride))
        for i in range(block_num):
            layers.append(InvertedResidual(out_channels, out_channels, factor, 1))
        return nn.Sequential(*layers)

    def init_params(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
                nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear) or isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def __init__(self, num_classes=num_class, t=6):
        super(MobileNetV2, self).__init__()

        self.first_conv = Conv3x3BNReLU(3, 32, 2, groups=1)
        # 32 -> 16 stride=1 wh不變
        self.layer1 = self.make_layer(in_channels=32, out_channels=16, stride=1, factor=1, block_num=1)
        # 16 -> 24 stride=2 wh減半
        self.layer2 = self.make_layer(in_channels=16, out_channels=24, stride=2, factor=t, block_num=2)
        # 24 -> 32 stride=2 wh減半
        self.layer3 = self.make_layer(in_channels=24, out_channels=32, stride=2, factor=t, block_num=3)
        # 32 -> 64 stride=2 wh減半
        self.layer4 = self.make_layer(in_channels=32, out_channels=64, stride=2, factor=t, block_num=4)
        # 64 -> 96 stride=1 wh不變
        self.layer5 = self.make_layer(in_channels=64, out_channels=96, stride=1, factor=t, block_num=3)
        # 96 -> 160 stride=2 wh減半
        self.layer6 = self.make_layer(in_channels=96, out_channels=160, stride=2, factor=t, block_num=3)
        # 160 -> 320 stride=1 wh不變
        self.layer7 = self.make_layer(in_channels=160, out_channels=320, stride=1, factor=t, block_num=1)
        # 320 -> 1280 單純的升維操作
        self.last_conv = Conv1x1BNReLU(320, 1280)

        self.avgpool = nn.AvgPool2d(kernel_size=7, stride=1)
        self.dropout = nn.Dropout2d(p=0.2)
        self.linear = nn.Linear(in_features=1280, out_features=num_classes)
        self.init_params()

    def forward(self, x):
        x = self.first_conv(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.layer5(x)
        x = self.layer6(x)
        x = self.layer7(x)
        x = self.last_conv(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.dropout(x)
        x = self.linear(x)
        return x

if __name__ == '__main__':
    model = MobileNetV2()

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

4、MobileNetV2作為CenterNet的BackBone

import torch
import torch.nn as nn

# DW卷積
def Conv3x3BNReLU(in_channels, out_channels, stride, groups):
    return nn.Sequential(
        # stride=2,wh減半; stride=1,wh不變
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, stride=stride, padding=1, groups=groups),
        nn.BatchNorm2d(out_channels),
        nn.ReLU6(inplace=True)
    )

# PW卷積
def Conv1x1BNReLU(in_channels, out_channels):
    return nn.Sequential(
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
        nn.BatchNorm2d(out_channels),
        nn.ReLU6(inplace=True)
    )

# PW卷積(Linear)沒有使用激活函數(shù)
def Conv1x1BN(in_channels, out_channels):
    return nn.Sequential(
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
        nn.BatchNorm2d(out_channels)
    )


class InvertedResidual(nn.Module):
    # t為擴展因子
    def __init__(self, in_channels, out_channels, expansion_factor, stride):
        super(InvertedResidual, self).__init__()
        self.stride = stride
        self.in_channels = in_channels
        self.out_channels = out_channels
        mid_channels = (in_channels * expansion_factor)

        # 先1*1卷積升維,再1*1卷積降維
        self.bottleneck = nn.Sequential(
            # 升維操作
            Conv1x1BNReLU(in_channels, mid_channels),
            # DW卷積,降低參數(shù)量
            Conv3x3BNReLU(mid_channels, mid_channels, stride, groups=mid_channels),
            # 降維操作
            Conv1x1BN(mid_channels, out_channels)
        )

        # stride=1才有shortcut,此方法讓原本不相同的channels相同
        if self.stride == 1:
            self.shortcut = Conv1x1BN(in_channels, out_channels)

    def forward(self, x):
        out = self.bottleneck(x)
        out = (out + self.shortcut(x)) if self.stride == 1 else out
        return out

class MobileNetV2(nn.Module):
    def make_layer(self, in_channels, out_channels, stride, factor, block_num):
        layers = []
        layers.append(InvertedResidual(in_channels, out_channels, factor, stride))
        for i in range(block_num):
            layers.append(InvertedResidual(out_channels, out_channels, factor, 1))
        return nn.Sequential(*layers)

    def init_params(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
                nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear) or isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def __init__(self, heads, t=6):
        super(MobileNetV2, self).__init__()

        num_classes = heads['hm']

        self.first_conv = Conv3x3BNReLU(3, 32, 2, groups=1)
        # 32 -> 16 stride=1 wh不變
        self.layer1 = self.make_layer(in_channels=32, out_channels=16, stride=1, factor=1, block_num=1)
        # 16 -> 24 stride=2 wh減半
        self.layer2 = self.make_layer(in_channels=16, out_channels=24, stride=2, factor=t, block_num=2)
        # 24 -> 32 stride=2 wh減半
        self.layer3 = self.make_layer(in_channels=24, out_channels=32, stride=2, factor=t, block_num=3)
        # 32 -> 64 stride=2 wh減半
        self.layer4 = self.make_layer(in_channels=32, out_channels=64, stride=2, factor=t, block_num=4)
        # 64 -> 96 stride=1 wh不變
        self.layer5 = self.make_layer(in_channels=64, out_channels=96, stride=1, factor=t, block_num=3)
        # 96 -> 160 stride=2 wh減半
        self.layer6 = self.make_layer(in_channels=96, out_channels=160, stride=2, factor=t, block_num=3)
        # 160 -> 320 stride=1 wh不變
        self.layer7 = self.make_layer(in_channels=160, out_channels=320, stride=1, factor=t, block_num=1)
        # 320 -> 1280 單純的升維操作
        self.last_conv = Conv1x1BNReLU(320, 1280)
        self.init_params()

        self.hm = nn.Conv2d(20, num_classes, kernel_size=1)
        self.wh = nn.Conv2d(20, 2, kernel_size=1)
        self.reg = nn.Conv2d(20, 2, kernel_size=1)


    def forward(self, x):
        x = self.first_conv(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.layer5(x)
        x = self.layer6(x)
        x = self.layer7(x)
        x = self.last_conv(x)

        y = x.view(x.shape[0], -1, 128, 128)
        z = {}
        z['hm'] = self.hm(y)
        z['wh'] = self.wh(y)
        z['reg'] = self.reg(y)
        return [z]

if __name__ == '__main__':
    heads = {'hm': 10, 'wh': 2, 'reg': 2}
    model = MobileNetV2(heads)

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

5、MobileNetV2在CenterNet目標檢測落地情況

(1)訓練情況

訓練loss,mobilenetV1在batch_size=16時最少達到4.0左右,而mobileNetV2在batch_size=16時最少達到0.5以下。與DLASeg的效果基本接近。

mobilenetv2,神經(jīng)網(wǎng)絡,深度學習,計算機視覺,目標檢測

(2)目標檢測效果

mobilenetv2,神經(jīng)網(wǎng)絡,深度學習,計算機視覺,目標檢測

檢測效果也與DLASeg基本接近

(3)模型參數(shù)量

DLASeg為2000W個左右

MobileNetV1為320W個左右

MobileNetV2為430W個左右,總模型大小為17M

(4)CPU運行時間

DLASeg為1.2s

MobileNetV1為250ms

MobileNetV2為600ms

?文章來源地址http://www.zghlxwxcb.cn/news/detail-720235.html

到了這里,關于MobileNetV2原理說明及實踐落地的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 機器學習筆記 - 基于MobileNetV2的遷移學習訓練關鍵點檢測器

    機器學習筆記 - 基于MobileNetV2的遷移學習訓練關鍵點檢測器

    ????????StanfordExtra數(shù)據(jù)集包含12000張狗的圖像以及關鍵點和分割圖圖。 GitHub - benjiebob/StanfordExtra:12k標記的野外狗實例,帶有2D關鍵點和分割。我們的 ECCV 2020 論文發(fā)布的數(shù)據(jù)集:誰把狗排除在外?3D 動物重建,循環(huán)中期望最大化。 https://github.com/benjiebob/StanfordExtra ? ? ?

    2024年02月10日
    瀏覽(29)
  • DeepLabV3+:Mobilenetv2的改進以及淺層特征和深層特征的融合

    DeepLabV3+:Mobilenetv2的改進以及淺層特征和深層特征的融合

    目錄 Mobilenetv2的改進 淺層特征和深層特征的融合 完整代碼 參考資料 在DeeplabV3當中,一般不會5次下采樣,可選的有3次下采樣和4次下采樣。因為要進行五次下采樣的話會損失較多的信息。 在這里mobilenetv2會從之前寫好的模塊中得到,但注意的是,我們在這里獲得的特征是[-

    2024年01月19日
    瀏覽(38)
  • MobileNetv1,v2網(wǎng)絡詳解并使用pytorch搭建MobileNetV2及基于遷移學習訓練(超詳細|附訓練代碼)

    MobileNetv1,v2網(wǎng)絡詳解并使用pytorch搭建MobileNetV2及基于遷移學習訓練(超詳細|附訓練代碼)

    目錄 前言 學習資料 一、MobilnetV1 二、MobileNetV2 倒殘差結構:? ? ? ?? 那么什么是relu6激活函數(shù)呢?編輯 ?Linear Bottlenecks 三、MobileNetV3 SE模塊: ?更新激活函數(shù): 重新設計耗時層結構: 使用pytorch搭建MobileNetv2網(wǎng)絡結構 3.1 model.py 3.2 train.py 3.3 predict.py ?3.4?class_indices.json 使用

    2024年02月05日
    瀏覽(42)
  • MobileNetV1詳細原理(含torch源碼)

    MobileNetV1詳細原理(含torch源碼)

    目錄 MobileNetV1原理 MobileNet V1的網(wǎng)絡結構如下: 為什么要設計MobileNet: MobileNetV1的主要特點如下: MobileNetV1的創(chuàng)新點: MobileNetV1源碼(torch版) 訓練10個epoch的效果 ????????MobileNet V1是一種輕量級的卷積神經(jīng)網(wǎng)絡,能夠在保持較高準確率的情況下具有較少的參數(shù)量和計算時

    2023年04月19日
    瀏覽(22)
  • MobileNetV3詳細原理(含torch源碼)

    MobileNetV3詳細原理(含torch源碼)

    作者:愛笑的男孩。 個人簡介:打工人。 持續(xù)分享:機器學習、深度學習、python相關內(nèi)容、日常BUG解決方法及WindowsLinux實踐小技巧。 如發(fā)現(xiàn)文章有誤,麻煩請指出,我會及時去糾正。有其他需要可以私信我或者發(fā)我郵箱:zhilong666@foxmail.com 目錄 MobileNetV3原理 MobileNetV3創(chuàng)新點

    2023年04月20日
    瀏覽(16)
  • DDD技術方案落地實踐

    從接觸領域驅(qū)動設計的初學階段,到實現(xiàn)一個舊系統(tǒng)改造到DDD模型,再到按DDD規(guī)范落地的3個的項目。對于領域驅(qū)動模型設計研發(fā),從開始的各種疑惑到吸收各種先進的理念,目前在技術實施這一塊已經(jīng)基本比較成熟。在既往經(jīng)驗中總結了一些在開發(fā)中遇到的技術問題和解決方

    2024年02月05日
    瀏覽(30)
  • 彈性伸縮落地實踐

    HPA(Horizontal Pod Autoscaler)是 Kubernetes 中的一種資源自動伸縮機制,用于根據(jù)某些指標動態(tài)調(diào)整 Pod 的副本數(shù)量。 負載波動:當您的應用程序的負載經(jīng)常發(fā)生波動時,HPA 可以自動調(diào)整 Pod 的副本數(shù)量,以適應負載的變化。例如,對于 Web 應用程序,在高峰期需要更多的副本以處

    2024年02月05日
    瀏覽(27)
  • 3. 云計算的落地實踐(下)

    云計算如何落地實踐 ISO鏡像文件 創(chuàng)建虛擬機入門 創(chuàng)建數(shù)據(jù)節(jié)點 配置 VMWare創(chuàng)建虛擬機三種網(wǎng)絡模式 上一章我們講了云計算的業(yè)界實踐,即: 搭建IaaS后,用于創(chuàng)建虛擬機,在虛擬機上部署PaaS,用于管理同時部署在虛擬機上的容器,這就是業(yè)界普遍的云計算實踐 。 ok,但是我

    2024年02月02日
    瀏覽(18)
  • 2. 云計算的落地實踐(上)

    云計算如何落地實踐 物理機與虛擬機 容器虛擬技術 Docker 橫空出世 PaaS 時代來臨 業(yè)界實踐 我們上一節(jié)講了有關云計算的概念,那么我們思考一下,云計算在現(xiàn)實中是如何落地實踐的呢? 如今云計算落地實踐中,已經(jīng)形成了一套有效的體系。一家公司的傳統(tǒng)業(yè)務如數(shù)據(jù)庫、計

    2024年02月09日
    瀏覽(20)
  • 云原生落地實踐的25個步驟

    云原生落地實踐的25個步驟

    一、什么是云原生? 云原生從字面意思上來看可以分成云和原生兩個部分。 云是和本地相對的,傳統(tǒng)的應用必須跑在本地服務器上,現(xiàn)在流行的應用都跑在云端,云包含了IaaS,、PaaS和SaaS。 原生就是土生土長的意思,我們在開始設計應用的時候就考慮到應用將來是運行云環(huán)境

    2024年02月14日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包