# pytorch实现MobileNet

## 创新点：

M ⋅ D F ⋅ D F ⋅ D K ⋅ D K + N ⋅ D F ⋅ D F ⋅ M N ⋅ D F ⋅ D F ⋅ M ⋅ D K ⋅ D K = 1 N + 1 D K 2 \frac{M\cdot D_{F}\cdot D_{F} \cdot D_{K}\cdot D_{K}+N\cdot D_{F}\cdot D_{F} \cdot M}{N\cdot D_{F}\cdot D_{F} \cdot M\cdot D_{K}\cdot D_{K}}=\frac{1}{N}+\frac{1}{D_{K}^{2}}

## 网络结构

α M ⋅ D F ⋅ D F ⋅ D K ⋅ D K + α N ⋅ D F ⋅ D F ⋅ α M \alpha M\cdot D_{F}\cdot D_{F} \cdot D_{K}\cdot D_{K}+\alpha N\cdot D_{F}\cdot D_{F} \cdot \alpha M
α ∈ ( 0 , 1 ] \alpha\in (0,1] ，典型的设置为1,0.75,0.5,0.25.

α M ⋅ ρ D F ⋅ ρ D F ⋅ D K ⋅ D K + α N ⋅ ρ D F ⋅ ρ D F ⋅ α M \alpha M\cdot \rho D_{F}\cdot \rho D_{F} \cdot D_{K}\cdot D_{K}+\alpha N\cdot \rho D_{F}\cdot \rho D_{F} \cdot \alpha M
ρ ∈ ( 0 , 1 ] \rho\in (0,1] ，通过隐式地设置可以使得输入分辨率为224,192,160,128.

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

class Block(nn.Module):
'''Depthwise conv + Pointwise conv'''
def __init__(self, in_planes, out_planes, stride=1):
super(Block, self).__init__()
self.conv1 = nn.Conv2d\
(in_planes, in_planes, kernel_size=3, stride=stride,
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv2 = nn.Conv2d\
(in_planes, out_planes, kernel_size=1,
self.bn2 = nn.BatchNorm2d(out_planes)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
return out

class MobileNet(nn.Module):
# (128,2) means conv planes=128, conv stride=2,
# by default conv stride=1
cfg = [64, (128,2), 128, (256,2), 256, (512,2),
512, 512, 512, 512, 512, (1024,2), 1024]

def __init__(self, num_classes=10):
super(MobileNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3,
self.bn1 = nn.BatchNorm2d(32)
self.layers = self._make_layers(in_planes=32)
self.linear = nn.Linear(1024, num_classes)

def _make_layers(self, in_planes):
layers = []
for x in self.cfg:
out_planes = x if isinstance(x, int) else x[0]
stride = 1 if isinstance(x, int) else x[1]
layers.append(Block(in_planes, out_planes, stride))
in_planes = out_planes
return nn.Sequential(*layers)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layers(out)
out = F.avg_pool2d(out, 2)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out

def test():
net = MobileNet()
x = torch.randn(1,3,32,32)
y = net(x)
print(y.size())

test()


10-24

02-19 7998
11-01 9210