MobileNet结构第一层为普通卷积,其余为深度可分离卷积和全连接层。
深度可分离卷积结构:
左图为普通卷积,右图为深度可分离卷积,一个深度可分离卷积块包括3*3单通道卷积和1*1跨通道卷积,每个卷积后都有BN,ReLU处理。
整体网络结构如下表:
第二行开始,每两行为一个深度可分离卷积操作,pytorch代码:
import torch.nn as nn
from torchsummary import summary
# pading 除了在1*1卷积层中为=0,其余卷积层都为1
class MobileNetV1(nn.Module):
def __init__(self, ch_in, n_classes):
super(MobileNetV1, self).__init__()
def conv_bn(inp, oup, stride):
return nn.Sequential(
nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
nn.BatchNorm2d(oup),
nn.ReLU(inplace=True)
)
# conv_dw表示一组深度可分离卷积,包括单通道卷积和1*1卷积
def conv_dw(inp, oup, stride):
return nn.Sequential(
# dw
nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
nn.BatchNorm2d(inp),
nn.ReLU(inplace=True),
# pw 1*1卷积
nn.Conv2d(inp, oup, 1, 1, 0, bias=False), # pading=0
nn.BatchNorm2d(oup),
nn.ReLU(inplace=True),
)
self.model = nn.Sequential(
conv_bn(ch_in, 32, 2),
conv_dw(32, 64, 1),
conv_dw(64, 128, 2),
conv_dw(128, 128, 1),
conv_dw(128, 256, 2),
conv_dw(256, 256, 1),
conv_dw(256, 512, 2),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 1024, 2),
conv_dw(1024, 1024, 1),
nn.AdaptiveAvgPool2d(1)
)
self.fc = nn.Linear(1024, n_classes)
def forward(self, x):
x = self.model(x)
x = x.view(-1, 1024)
x = self.fc(x)
return x
model = MobileNetV1(ch_in=3, n_classes=5) # 修改为自己的分类数量
summary(model, input_size=(3, 224, 224), device='cpu') # 打印网络结构