mobilenet V3 pytorch

import torch
import torch.nn as nn
import torch.nn.functional as F

class HSwish(nn.Module):
    def forward(self, x):
        return x * F.relu6(x + 3) / 6

class SEBlock(nn.Module):
    def __init__(self, in_channels, reduction=4):
        super(SEBlock, self).__init__()
        self.fc1 = nn.Conv2d(in_channels, in_channels // reduction, kernel_size=1)
        self.fc2 = nn.Conv2d(in_channels // reduction, in_channels, kernel_size=1)

    def forward(self, x):
        scale = F.adaptive_avg_pool2d(x, 1)
        scale = F.relu(self.fc1(scale))
        scale = torch.sigmoid(self.fc2(scale))
        return x * scale

class MobileBottleneck(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride, expand_ratio, se=False, nl="RE"):
        super(MobileBottleneck, self).__init__()
        self.use_res_connect = stride == 1 and in_channels == out_channels
        self.nl = nl

        hidden_dim = round(in_channels * expand_ratio)
        self.expand = in_channels != hidden_dim
        self.se = se

        if self.expand:
            self.conv1 = nn.Conv2d(in_channels, hidden_dim, kernel_size=1, bias=False)
            self.bn1 = nn.BatchNorm2d(hidden_dim)

        self.conv2 = nn.Conv2d(hidden_dim, hidden_dim, kernel_size=kernel_size, stride=stride, padding=kernel_size // 2, groups=hidden_dim, bias=False)
        self.bn2 = nn.BatchNorm2d(hidden_dim)
        self.se_block = SEBlock(hidden_dim) if self.se else nn.Identity()

        self.conv3 = nn.Conv2d(hidden_dim, out_channels, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(out_channels)

        self.hswish = HSwish()
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        identity = x
        if self.expand:
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.hswish(x) if self.nl == "HS" else self.relu(x)

        x = self.conv2(x)
        x = self.bn2(x)
        x = self.se_block(x)
        x = self.hswish(x) if self.nl == "HS" else self.relu(x)

        x = self.conv3(x)
        x = self.bn3(x)

        if self.use_res_connect:
            x += identity

        return x

class MobileNetV3(nn.Module):
    def __init__(self, num_classes=1000, mode="small"):
        super(MobileNetV3, self).__init__()
        self.mode = mode

        if mode == "small":
            self.cfgs = [
                [3, 16, 16, 0, 'RE', 2],
                [3, 72, 24, 0, 'RE', 2],
                [3, 88, 24, 0, 'RE', 1],
                [5, 96, 40, 1, 'HS', 2],
                [5, 240, 40, 1, 'HS', 1],
                [5, 240, 40, 1, 'HS', 1],
                [5, 120, 48, 1, 'HS', 1],
                [5, 144, 48, 1, 'HS', 1],
                [5, 288, 96, 1, 'HS', 2],
                [5, 576, 96, 1, 'HS', 1],
                [5, 576, 96, 1, 'HS', 1],
            ]
            self.last_channel = 576
        else:
            raise ValueError("Unsupported mode: {}".format(mode))

        input_channel = 16
        self.first_conv = nn.Sequential(
            nn.Conv2d(3, input_channel, kernel_size=3, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(input_channel),
            HSwish()
        )

        self.blocks = self._make_layers(in_channel=input_channel)

        self.last_conv = nn.Sequential(
            nn.Conv2d(self.cfgs[-1][2], self.last_channel, kernel_size=1, bias=False),
            nn.BatchNorm2d(self.last_channel),
            HSwish()
        )

        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.classifier = nn.Sequential(
            nn.Linear(self.last_channel, 1024),
            HSwish(),
            nn.Dropout(0.2),
            nn.Linear(1024, num_classes)
        )

    def _make_layers(self, in_channel):
        layers = []
        for k, exp, c, se, nl, s in self.cfgs:
            out_channel = c
            exp_ratio = exp / in_channel
            layers.append(MobileBottleneck(in_channel, out_channel, k, s, exp_ratio, se, nl))
            in_channel = out_channel
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.first_conv(x)
        x = self.blocks(x)
        x = self.last_conv(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

from torchsummary import summary
device = torch.device("cuda:0")
model = MobileNetV3(num_classes=150, mode="small").to(device)
summary(model, input_size=(3, 224, 224))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MobileNet V3是一种轻量级的卷积神经网络模型,它特别适合在移动设备上进行图像识别任务。Onnx是一种开源的神经网络训练和推理框架,它可以将训练好的模型从一个框架转换到另一个框架。 MobileNet V3可以在计算资源受限的移动设备上实现快速而精确的图像分类。它采用了一系列的深度可分离卷积操作,这些操作将整个模型的计算量大大减小,并且保持了较高的分类准确率。MobileNet V3通过研究网络结构、特征选择和激活函数等方面的创新,进一步提高了模型的性能。 Onnx则是一种跨平台、多框架的神经网络模型表示格式。通过使用Onnx,我们可以将MobileNet V3模型从一个框架(如PyTorch)转换到另一个框架(如TensorFlow),以便在不同的平台和环境中进行推理和应用部署。Onnx提供了一个统一的模型表示,使得在不同框架中进行模型转换变得更加简单和高效。 通过将MobileNet V3模型导出为Onnx格式,我们可以在移动设备上使用不同的推理引擎进行实时图像分类。Onnx的跨平台特性使得模型可以在不同的硬件加速器上进行高效运行,提供良好的用户体验。此外,Onnx还允许我们对模型进行调优和组合,以满足不同的应用需求。 综上所述,MobileNet V3 onnx是将MobileNet V3模型转换为Onnx格式的一种方法,使得在移动设备上进行高效的图像分类成为可能。这种方法不仅提供了良好的性能和可移植性,还为开发者提供了更大的灵活性和扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值