MobileNets是Google针对手机等嵌入式设备提出的一种轻量级的深层神经网络;中点在于压缩模型,同时保证精度。
MobileNets是基于一个流线型的架构,它使用深度可分离的卷积来构建轻量级的深层神经网络。
二、网络特点
切除卷积滤波器
逐点的卷积
二、单个block结构
该block体现了深度分离卷积的特点。
三、整体网络结构
四、模型复现
1 ,添加依赖库
import paddle
from paddle.nn import Conv2D, BatchNorm2D, AdaptiveAvgPool2D
import paddle.nn.functional as F
2、建立基础的代码运行块
class ConvBNLayer(paddle.nn.Layer):
def __init__(self, in_channels, out_channels, kernel_size, stride, padding, num_group = 1):
super(ConvBNLayer, self).__init__()
self.conv = Conv2D(
in_channels,
out_channels,
kernel_size,
stride = stride,
padding = padding,
groups = num_group
)
self.bn = BatchNorm2D(out_channels)
def forward(self, inputs):
x = self.conv(inputs)
x = self.bn(x)
x = F.relu(x)
return x
3、按照单个block结构建立深度可分离卷积的block
class DepthwiseSeperable(paddle.nn.Layer):
def __init__(self, inchannels, outchannels, stride):
super(DepthwiseSeperable, self).__init__()
self.dcf = ConvBNLayer(
in_channels = inchannels,
out_channels = inchannels,
kernel_size = 3,
stride = stride,
padding = 1,
num_group = inchannels
)
self.pc = ConvBNLayer(
in_channels=inchannels,
out_channels=outchannels,
kernel_size=1,
stride=1,
padding=0
)
def forward(self, inputs):
x = self.dcf(inputs)
x = self.pc(x)
return x
4、搭建整体的网络结构
class MobileNet_v1(paddle.nn.Layer):
def __init__(self):
super(MobileNet_v1, self).__init__()
self.dws = []
self.conv0 = ConvBNLayer(
in_channels=3,
out_channels=32,
kernel_size=3,
stride=2,
padding=1
)
layer0 = DepthwiseSeperable(
inchannels=32,
outchannels=64,
stride=1
)
self.dws.append(layer0)
layer1 = DepthwiseSeperable(
inchannels=64,
outchannels=128,
stride=2
)
self.dws.append(layer1)
layer2 = DepthwiseSeperable(
inchannels=128,
outchannels=128,
stride=1
)
self.dws.append(layer2)
layer3 = DepthwiseSeperable(
inchannels=128,
outchannels=256,
stride=2
)
self.dws.append(layer3)
layer4 = DepthwiseSeperable(
inchannels=256,
outchannels=256,
stride=1
)
self.dws.append(layer4)
layer5 = DepthwiseSeperable(
inchannels=256,
outchannels=512,
stride=2
)
self.dws.append(layer5)
for i in range(5):
tmp = DepthwiseSeperable(
inchannels=512,
outchannels=512,
stride=1
)
self.dws.append(tmp)
layer6 = DepthwiseSeperable(
inchannels=512,
outchannels=1024,
stride=2
)
self.dws.append(layer6)
layer7 = DepthwiseSeperable(
inchannels=1024,
outchannels=1024,
stride=1
)
self.dws.append(layer7)
self.pooling = AdaptiveAvgPool2D(output_size=(1, 1))
def forward(self, inputs):
x = self.conv0(inputs)
for dws in self.dws:
x = dws(x)
x = self.pooling(x)
x = paddle.squeeze(x)
return x
5、查看网络结构
model = MobileNet_v1()
paddle.summary(model, (1, 3, 224, 224))
运行后的效果
-------------------------------------------------------------------------------
Layer (type) Input Shape Output Shape Param #
===============================================================================
Conv2D-1 [[1, 3, 224, 224]] [1, 32, 112, 112] 896
BatchNorm2D-1 [[1, 32, 112, 112]] [1, 32, 112, 112] 128
ConvBNLayer-1 [[1, 3, 224, 224]] [1, 32, 112, 112] 0
AdaptiveAvgPool2D-1 [[1, 1024, 7, 7]] [1, 1024, 1, 1] 0
===============================================================================
Total params: 1,024
Trainable params: 896
Non-trainable params: 128
-------------------------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 9.20
Params size (MB): 0.00
Estimated Total Size (MB): 9.77
-------------------------------------------------------------------------------