8.Mobilenetv2网络代码实现

代码如下:

import math
import os
import numpy as np

import torch
import torch.nn as nn
import torch.utils.model_zoo as model_zoo

#1.建立带有bn的卷积网络
def conv_bn(inp, oup, stride):
    return nn.Sequential(
        nn.Conv2d(inp,oup,3,stride,bias=False),
        nn.BatchNorm2d(oup),
        nn.ReLU6(inplace=True)
    )

#2.建立卷积核是1x1的卷积网络
def conv_1x1_bn(inp, oup):
    return nn.Sequential(
        nn.Conv2d(inp,oup,1,1,0,bias=False),
        nn.BatchNorm2d(oup),
        nn.ReLU6(inplace=True)
    )


class InvertedResidual(nn.Module):
    def __init__(self, inp, oup, stride, expand_ratio):
        super(InvertedResidual,self).__init__()
        self.stride=stride
        assert stride in [1,2]

        hidden_dim=round(inp*expand_ratio)
        self.use_res_connect=self.stride==1 and inp==oup

        if expand_ratio == 1:

            self.conv=nn.Sequential(
                # --------------------------------------------#
                #   进行3x3的逐层卷积,进行跨特征点的特征提取
                # --------------------------------------------#
                nn.Conv2d(hidden_dim,hidden_dim,3,stride, 1, groups=hidden_dim, bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # -----------------------------------#
                #   利用1x1卷积进行通道数的调整
                # -----------------------------------#
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                nn.BatchNorm2d(oup),
            )
        else:
            self.conv=nn.Sequential(
                # -----------------------------------#
                #   利用1x1卷积进行通道数的上升
                # -----------------------------------#
                nn.Conv2d(inp,hidden_dim,1,1,0,bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # --------------------------------------------#
                #   进行3x3的逐层卷积,进行跨特征点的特征提取
                # --------------------------------------------#
                nn.Conv2d(hidden_dim,hidden_dim,3,stride, 1, groups=hidden_dim, bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # -----------------------------------#
                #   利用1x1卷积进行通道数的下降
                # -----------------------------------#
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                nn.BatchNorm2d(oup)
            )
    def forward(self,x):
        if self.use_res_connect:
            return x+self.conv(x)
        else:
            return self.conv(x)

#搭建MobileNetV2网络
class MobileNetV2(nn.Module):
    def __init__(self, n_class=1000, input_size=224, width_mult=1.):
        super(MobileNetV2, self).__init__()
        block=InvertedResidual
        input_channel=32
        last_channel=1280
        interverted_residual_setting = [
            # t, c, n, s
            [1, 16, 1, 1],  # 256, 256, 32 -> 256, 256, 16
            [6, 24, 2, 2],  # 256, 256, 16 -> 128, 128, 24   2
            [6, 32, 3, 2],  # 128, 128, 24 -> 64, 64, 32     4
            [6, 64, 4, 2],  # 64, 64, 32 -> 32, 32, 64       7
            [6, 96, 3, 1],  # 32, 32, 64 -> 32, 32, 96
            [6, 160, 3, 2],  # 32, 32, 96 -> 16, 16, 160     14
            [6, 320, 1, 1],  # 16, 16, 160 -> 16, 16, 320
        ]
        assert input_size % 32 == 0
        input_channel = int(input_channel * width_mult)
        self.last_channel = int(last_channel * width_mult) if width_mult > 1.0 else last_channel
        # 512, 512, 3 -> 256, 256, 32
        self.features=[conv_bn(3,input_channel,2)]

        for t,c,n,s in interverted_residual_setting:
            output_channel=int(c*width_mult)
            for i in range(n):
                if i==0:
                    self.features.append(block(input_channel,output_channel,s, expand_ratio=t))
                else:
                    self.features.append(block(input_channel,output_channel,1, expand_ratio=t))
                # input_channel修改为该轮的输出层数
                input_channel = output_channel
        self.features.append(conv_1x1_bn(input_channel, self.last_channel))
        self.features=nn.Sequential(*self.features)

        self.classifier=nn.Sequential(
            nn.Dropout(0.2),
            nn.Linear(self.last_channel,n_class)
        )
        self._initialize_weights()

    def forward(self,x):
        x=self.features(x)
        x=x.mean(3).mean(2)
        x=self.classifier(x)
        return x

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                n = m.weight.size(1)
                m.weight.data.normal_(0, 0.01)
                m.bias.data.zero_()




if __name__ == '__main__':
    print("........................................")
    #数据集生成
    input=torch.randn(1,3,224,224)
    print(input.shape)


    #MobileNetV2的输出
    ss=MobileNetV2()
    # print(ss)
    output=ss(input)
    print(output.shape)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值