大家好,今天和各位分享一下如何使用 Pytorch 构建 ShuffleNetV2 卷积神经网络模型。
ShuffleNetV2 的原理和 TensorFlow2 实现方法可以看我下面这篇博文,建议大家看一下
https://blog.youkuaiyun.com/dgvv4/article/details/123598847
1. 模型介绍
EfficientNetV2 网络主要采用神经结构搜索技术(Neural Architecture Search, NAS)结合复合模型扩张方法获得了一组最优的复合系数,自动将网络的深度、宽度和输入图像分辨率三个参数进行合理的配置,提升了网络的性能,在 ImageNet ILSVRC2012 的 Top-1 上达到 87.3%的准确率,且 EfficientNetV2 减少了模型的参数量并且进一步提升了模型的训练速度。
EfficientNetV1 存在三个问题:
(1)若训练图片的尺寸很大,训练时间非常长;
(2)即使深度卷积结构的参数相比于普通卷积更少,但是在网络浅层中使用深度卷积训练速度仍然很慢,通常不能充分利用现有的加速器;
(3)在 EfficientNetV1中,各阶段都同等放大宽度和深度,但是每一个阶段的参数数量和训练速度都是不同的,所以使用同等放大的方法不是最优的选择。
所以针对以上的问题,EfficientNetV2 网络不论在训练速度还是所用参数数量都优于之前的网络,并且验证了不同的图像尺寸应该使用不同的正则方法,并且设计了一种渐进学习方法,该方法自动调节不同的图像尺寸使用动态的正则方法,并且不仅提高了模型预测准确率,同时还提升了训练速度。
2. Stochastic Depth dropout
网络结构中的 Droupout 层是随机深度,即有可能只剩捷径分支,随机丢掉整个模块的主干,相当于这个模块消失了,减少了网络的深度。随机深度不是使用随机失活方式,而是将其设置与倒残差层数 𝑙 相关的线性函数。假设总共有 L 个倒残差块,那么存活概率从 线性逐渐递减到第 L 个倒残差网络
。公式如(4-30)所示:
使用线性失活方式的主要是因为较浅的层会提取低级特征,而后期的深层特征都是和这些低级特征紧密相联的,所以较浅的层应该尽可能提取更多的低级特征、尽量减少丢弃概率,那么最终 𝑝 产生的线性下图所示。
代码展示:
'''
-------------------------------------------
模块(1)
-------------------------------------------
'''
import torch
from torch import nn
from functools import partial # 传参
from torchstat import stat # 查看网络参数
# -------------------------------------- #
# Stochastic Depth dropout 方法,随机丢弃输出层
# -------------------------------------- #
def drop_path(x, drop_prob: float=0., training: bool=False): # drop_prob代表丢弃概率
# (1)测试时不做 drop path 方法
if drop_prob == 0. or training is False:
return x
# (2)训练时使用
keep_prob = 1 - drop_prob # 网络每个特征层的输出结果的保留概率
shape = (x.shape[0],) + (1,) * (x.ndim-1)
random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)
random_tensor.floor_()
output = x.div(keep_prob) * random_tensor
return output
class DropPath(nn.Module):
def __init__(self, drop_prob=None):
super(DropPath, self).__init__()
self.drop_prob = drop_prob
def forward(self, x):
out = drop_path(x, self.drop_prob, self.training)
return out
3. SE通道注意力机制
SE注意力机制基于不同的数据集和任务环境,调节捷径分支上每一个通道的权重值,提高或降低不同通道在训练过程中的重要程度。其原理如下图所示。