文章目录
- 一、介绍
- 二、网络特点
- 二、单个block结构
- 三、整体网络结构
- 四、论文复现
- 1、导入相关库
- 2、建立基础的代码运行块
- 3、按照单个block结构建立深度可分离卷积的block
- 4、搭建整体的网络结构
- 5、查看网络结构
一、介绍
MobileNets是Google针对手机等嵌入式设备提出的一种轻量级的深层神经网络;中点在于压缩模型,同时保证精度。
MobileNets是基于一个流线型的架构,它使用深度可分离的卷积来构建轻量级的深层神经网络。
二、网络特点
Depthwise Convolutional Filter
Pointwise Convolution
该网络相比于标准卷积网络,将层卷积和深度卷积分离,减少了计算量。
标准卷积的计算:DK.DK.M.N.DF.DF
可分离卷积的计算:DK.DK.M.DF.DF+M.N.DF.DF
计算比为: D K . D K . M . N . D F . D F D K . D K . M . D F . D F + M . N . D F . D F \frac{D_K.D_K.M.N.D_F.D_F}{D_K.D_K.M.D_F.D_F+M.N.D_F.D_F} DK.DK.M.DF.DF+M.N.DF.DFDK.DK.M.N.DF.DF= 1 N + 1 D 2 \frac{1}{N}+\frac{1}{D^2} N1+D21
注释: D K D_K DK为输入图像大小,M为输入图像层数, D K D_K DK为输出图像大小,N为输出图像层数
二、单个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))