1.MobileNetv3网络详解
提出了MobileNetv3-Large和MobileNetv3-Small两种不同大小的网络结构,主要的区别是通道数的变化与bneck的次数。
网络的创新点:
(1)更新Block(bneck)
(2)使用NAS搜索参数(Neural Architecture Search)
(3)重新设计耗时层结构
(1)更新Block
MobileNetv2的倒残差结构:

MobileNetv3的倒残差结构:
NL表示非线性激活函数

与MobileNetv2相比,MobileNetv3的倒残差结构加入了轻量级的注意力机制:

注意力机制的作用方式是调整每个通道的权重(对得到的特征矩阵的每一个channel进行池化处理)。
调整方式:特征矩阵的channel等于多少,得到的一维向量就有多少个元素;然后通过两个全连接层得到输出的向量。第一个全连接层,其节点个数为特征矩阵的channel的1/4;。第二个全连接层,其节点个数等于特征矩阵的channel;输出的向量可以理解为对特征矩阵的每一个channel分析出的一个权重关系,对于重要的channel就赋予一个比较大的权重。
利用h-swish代替swish函数:


(2)使用NAS搜索参数(Neural Architecture Search)
略
(3)重新设计耗时层结构
(a)减少第一个卷积层的卷积核个数(32减为16)
原论文中作者说减少卷积核后准确率不变且能够减少计算量,节省2毫秒时间
(b)精简Last Stage

使用NAS搜索出来的网络结构的最后一部分为Original Last Stage,但作者在使用过程中发现这一部分比较耗时,因此对其进行精简为Efficient Last Stage,精简后准确率不变且节省7毫秒时间。
2.MobileNetv3(large)网络结构

第一列Input代表mobilenetV3每个特征层的shape变化;
第二列Operator代表每次特征层即将经历的block结构,在MobileNetV3中,特征提取经过了许多的bneck结构,NBN为不适用BN层;
第三、四列分别代表了bneck内倒残差结构升维后的通道数、输入到bneck时特征层的通道数。
第五列SE代表了是否在这一层引入注意力机制。
第六列NL代表了激活函数的种类,HS代表h-swish,RE代表RELU。
第七列s代表了每一次block结构所用的步长。
注:112x112x16这一层,输入特征矩阵的channel等于exp size,所以在这一层的倒残差结构里不需要升维,没有1x1的卷积层
3.MobileNetv3(small)网络结构

与MobileNetV3(large)相比,bneck的次数与通道数都有一定的下降。
4.使用Pytorch搭建MobileNetv3网络
文件结构:
MobileNetv2
├── model_v2.py: MobileNetv2模型搭建
├── model_v3.py: MobileNetv3模型搭建
├── train.py: 训练脚本
└── predict.py: 图像预测脚本
(1)model_v3.py
定义卷积结构:
class ConvBNActivation(nn.Sequential): #定义结构:Conv+BN+激活函数
def __init__(self,
in_planes: int, #输入特征矩阵channel
out_planes: int, #输出特征矩阵channel
kernel_size: int = 3,
stride: int = 1,
groups: int = 1,
norm_layer: Optional[Callable[..., nn.Module]] = None, #卷积后接的BN层
activation_layer: Optional[Callable[..., nn.Module]] = None): #激活函数
padding = (kernel_size - 1) // 2
if norm_layer is None: #如果没有传入norm_layer就默认设置为BN
norm_layer = nn.BatchNorm2d
if activation_layer is None: #如果没有传入激活函数寄默认使用ReLU6
activation_layer = nn.ReLU6
super(ConvBNActivation, self).__init__(nn.Conv2d(in_channels=in_planes,
out_channels=out_planes,
kernel_size=kernel_size,
stride=stride,
padding=padding,
groups=groups,
bias=False),
norm_layer(out_planes),
activation_layer(inplace=True))
定义注意力机制模块:
class SqueezeExcitation(nn.Module): #定义注意力机制模块,此处注意对比上文讲到的注意力机制
def __init__(self, input_c: int, squeeze_factor: int = 4): #squeeze_factor为第一个全连接层的节点个数为输入特征矩阵channel的1/4,所以int=4
super(SqueezeExcitation, self).__init__()
squeeze_c = _make_divisible(input_c // squeeze_factor, 8) #计算第一个全连接层的节点个数:输出特征矩阵channel/4,计算完成后调整到8最近的整数倍
self.fc1 = nn.Conv2d(input_c, squeeze_c, 1) #全连接层1,输入输出的channel
self.fc2 = nn.Conv2d(squeeze_c, input_c

2万+

被折叠的 条评论
为什么被折叠?



