转载:【AI系统】SqueezeNet 系列

news/2024/12/12 10:35:45/文章来源:https://www.cnblogs.com/ewr67/p/18601838

本文将介绍 SqueezeNet 系列网络,在轻量化模型这个范畴中,Squeezenet 是最早的研究。主要针对了一些组件进行轻量化。与以往的网络都只讲网络如何设计不同。SqueezeNext 则从硬件角度分析如何加速,从而更全面地了解网络结构的设计。

SqueezeNet 模型

SqueezeNet:是轻量化主干网络中比较著名的,它发表于 ICLR 2017,在达到了 AlexNet 相同的精度的同时,只用了 AlexNet 1/50 的参数量。SqueezeNet 核心贡献在于使用 Fire Module(如下图所示),即由 Squeeze 部分和 Expand 部分组成,Squeeze 部分是一组连续的 $1 \times 1$ 卷积组成,Expand 部分则是由一组连续的 $1 \times 1$ 卷积和 $3 \times 3$ 卷积 cancatnate 组成,在 Fire 模块中,Squeeze 部分的 $1\times1$ 卷积的通道数记做 $s_{1\times 1}$,Expand 部分 $1 \times 1$ 卷积和 $3 \times 3$ 卷积的通道数分别记做 $e_{1 \times 1}$ 和 $e_{3 \times 3}$。

在 Fire 中文章作者建议 $s_{1\times 1}$<$e_{1 \times 1}$+$e_{3 \times 3}$,这么做相当于两个 $3 \times 3$ 卷积中加入了瓶颈层。

image

压缩策略

SqueezeNet 算法的主要目标是构建轻量参数的 CNN 架构,同时不损失精度。为了实现这一目标,作者总共采用了三种策略来设计 CNN 架构,具体如下:

  1. 减少卷积核大小:将 3×3 卷积替换成 1×1 卷积,可以使参数量减少 9 倍;
  2. 减少卷积通道:减少 3×3 卷积通道数,一个 3×3 卷积的计算量是 3 × 3 × M × N ,通过将 M 和 N 减少以降低参数数量;
  3. 下采样延后:将下采样操作延后,这样卷积层就有了大的激活图,保留更多信息。

Fire 模块

Fire 模块组成:主要包括挤压层(squeeze)和拓展层(expand);

  • Squeeze:只有 1×1 卷积滤波器;
  • Expand:混合有 1×1 和 3×3 卷积滤波器;

并引入了三个调节维度的超参数:

  • $s_{1\times1}$:squeeze 中 1 x 1 卷积滤波器个数;
  • $e_{1\times1}$:expand 中 1 x 1 卷积滤波器个数;
  • $e_{3\times3}$:expand 中 3 x 3 卷积滤波器个数;
#Fire Module
class fire(nn.Module):def __init__(self,in_channel, out_channel):super(fire, self).__init__()self.conv1 = nn.Conv2d(in_channel,out_channel//8,kernel_size=1)        #  1x1 卷积self.conv2_1 = nn.Conv2d(out_channel//8,out_channel//2,kernel_size=1)   # 1x1 卷积self.conv2_2 = nn.Conv2d(out_channel//8,out_channel//2,kernel_size=3,padding= 3//2)   # 3x3 卷积self.BN1 = nn.BatchNorm2d(out_channel//4) # BNself.ReLU = nn.ReLU() #ReLU 激活函数#Fire Module 前向过程def forward(self,x):out = self.ReLU(self.BN1(self.conv1(x)))out1 = self.conv2_1(out)out2 = self.conv2_2(out)out  = self.ReLU(torch.cat([out1,out2],1)) # cat 进行拼接特征图return out

网络结构实现

Fire Module的基础上搭建 SqueezeNet 神经网络,结构如下图所示。以卷积层开始,后面是 8 个 Fire Module,最后以卷积层结束,激活函数默认使用 ReLU,每个 Fire Module 中的通道数目逐渐增加,另外网络在 conv1、fire4、fire8、conv10 的后面使用了最大池化。

相同分辨率的 Fire Module 数量前面要少一点,后面要多一点,通道数通常以 32 或 64 的倍数增加。在通道数相同的层之间,添加旁路相加结构(short-cut)可以明显提升准确性(top-1 和 top-5 分别提升 2.9% 和 2.2%)。带有卷积的旁路结构可以在任意层之间添加(1*1 卷积调控 depth),准确性提升较小,模型增大。

image

#导入所需的 pytorch 库
import torch
import torch.nn as nn#SqueezeNet 网络
class SQUEEZENET(nn.Module):#初始化一些层和变量def __init__(self,in_channel, classses):super(SQUEEZENET, self).__init__()channels = [96,128,128,256,256,384,384,512,512]self.conv1 = nn.Conv2d(in_channel,channels[0],7,2,padding=7//2) #7x7 卷积self.pool1 = nn.MaxPool2d(kernel_size=3,stride=2) #最大池化self.BN1 = nn.BatchNorm2d(channels[0])self.block = fire  #fire Moduleself.block1 = nn.ModuleList([])#block 叠加for i in range(7):self.block1.append(self.block(in_channel = channels[i],out_channel = channels[i+1]))if i in [3,6]:self.block1.append(nn.MaxPool2d(kernel_size=3,stride=2))self.block1.append(self.block(channels[-2],channels[-1]))#Dropout 1x1 卷积激活函数self.conv10 = nn.Sequential(nn.Dropout(0.5),nn.Conv2d(channels[-1],classses,kernel_size=1,stride=1),nn.ReLU())self.pool2 = nn.MaxPool2d(kernel_size=13) #最大池化#SQUEEZENET 前向过程def forward(self,x):x = self.conv1(x)x = self.pool1(x)x = self.BN1(x)for block in self.block1:x = block(x)x = self.conv10(x)out = self.pool2(x)return out

SqueezeNext 模型

SqueezeNext:现有神经网络需要大的内存和计算资源是将其部署到嵌入式设备上的最大障碍。SqueezeNext 引入了神经网络加速技术。本文介绍的 SqueezeNext 可以达到 AlexNet 的准确度且参数数量比前者少 112 倍。另一版本的 SqueezeNext 模型可以达到 VGG-19 的精度且参数数量比原始 VGG-19 网络少 31 倍,仅为 4.4 Million。

SqueezeNext 在比 MobeilNet 参数数量少 1.3 倍的情况下取得了比其更好的 Top-5 分类精度,同时也没有使用在很多移动式设备上不足够高效的分离卷积。作者在相比 SqueezeNet/AlexNet 没有精度损失的情况下,设计出了比其运算速度快 2.59/8.26 倍的网络,且耗能比原来少 2.25/7.5 倍。

Bottle 模块

Bottle 模块,加入 Shortcut ,Bottleneck module 和 Low Rank Filter 。改进如下:

  • 将 expand 层的 3x3 卷积替换为 1x3 + 3x1 卷积,同时移除了 expand 层的拼接 1x1 卷积、添加了 1x1 卷积来恢复通道数。
  • 通过两阶段的 squeeze 得到更激进的通道缩减,每个阶段的 squeeze 都将通道数减半。
class Bottle(nn.Module):def __init__(self,in_channel,out_channel, stride):super(Bottle, self).__init__()'''3x3 卷积替换为 1x3 + 3x1 卷积,同时移除了 expand 层的拼接 1x1 卷积、添加了 1x1 卷积来恢复通道数。'''self.block = nn.Sequential(CONV_BN_RELU(in_channel, in_channel // 2, kernel_size=1,stride = stride,padding=0),CONV_BN_RELU(in_channel // 2, in_channel // 4, kernel_size=1,padding=0),CONV_BN_RELU(in_channel // 4, in_channel // 2, kernel_size=(1,3), padding=(0,3//2)),CONV_BN_RELU(in_channel // 2, in_channel//2, kernel_size=(3,1),padding=(3//2,0)),CONV_BN_RELU(in_channel//2 , out_channel, kernel_size=1,padding=0),)self.shortcut = nn.Sequential()'''Shortcut'''if stride==2 or out_channel!=in_channel:self.shortcut = nn.Sequential(nn.Conv2d(in_channel, out_channel, kernel_size=3,stride = stride, padding=1),nn.BatchNorm2d(out_channel))def forward(self,x):out1 = self.block(x)out2 = self.shortcut(x)x = out1+out2return x

两阶段 Bottleneck

每一个卷积层中的参数数量正比于 $C_{i}$ 和 $C_{o}$ 的乘积。所以,减少输入通道的数量可以有效减少模型的大小。一种思路是使用分离卷积减少参数数量,但是某些嵌入式系统由于其用于计算的带宽的限制,分离卷积的性能较差。另一种思路是 squeezeNet 中提出的在 $3 \times 3$ 卷积之前使用 squeeze 层以减少 $3 \times3$ 卷积的输入通道数目。这里作者在 SqueezeNet 的基础上进行了演化,使用了如下图所示的两层 squeeze 层。

在 SqueezeNext 模块中,使用了两层 bottleneck,每一层都将通道数减小为原来的 1/2,然后使用了两个分离卷积层。最后使用了一层 $1 \times 1$ 卷积的扩充层,进一步减少了分离卷积输出数据的通道数。

image

低秩过滤器

假设网络第 $i$ 层的输入为 $x∈R^{H\times W \times C_{i}}$,卷积核大小为 $K \times K$,输出大小为 $y∈R^{H\times W \times C_{o}}$,这里假设输入和输出的空间尺寸相同,输入和输出的通道数分别是 $C_{i}$ 和 $C_{o}$。该层的总的参数数量为 $K^{2}C_{i}C_{o}$,即 $C_{o}$ 个大小为 $K \times K \times C_{i}$ 的卷积核。

在对已有模型进行压缩的实现中,尝试对现有参数 W 压缩成 $\hat{W}$ 可以通过 CP 或者 Tucker 分解获取 $ \hat{W}$。通过这些方法减小的参数量正比于原始参数矩阵 W 的秩。

然而,检查当前各主流模型的参数 W,可以发现其都有比较高的秩。所以,当前模型压缩方法都进行了一定的重训练以恢复准确率。主流的模型压缩方法包括对参数进行剪枝以减少非零参数的数量,或者减小参数的精度。

另外一种思路是使用低秩参数矩阵 $\hat{W}$ 重新设计网络,这也是本文作者所采用的方法。作者所作的第一个变化是将 $K \times K$ 的矩阵分解为两个独立的 $1 \times K$ 和 $ K \times 1$ 卷积。这样做有效地将参数数量从 $K^2$ 减少成了 2K,同时增加了网络的深度。两个卷积层后都使用了 ReLu 激活函数和 BN 层。

网络结构实现

AlexNet 96% 的参数来自于全连接层,SqueezeNet 和 ResNet 中都只包含一个全连接层。假设输入数据为 $H \times W \times C_{i}$ ,那么最后的全连接层的参数数量为 $H \times W \times C_{i} \times L_{i}$,L 表示输出的类别数。SqueezeNext 在最后一个全连接层之前使用了一个 bottleneck 层,进一步减少了参数数量。

image

SqueezeNext 的设计就是不断的堆叠上图的 block,在模拟硬件性能实验结果中发现,维度越低,计算性能也越低效,于是将更多的层操作集中在维度较高的 block。

SqueezeNext-23 结构如下图所示:

image

其代码实现具体如下所示:

import torch
import torch.nn as nn#卷积+BN+激活函数
class CONV_BN_RELU(nn.Module):def __init__(self,in_channel,out_channel,kernel_size,padding,stride=1):super(CONV_BN_RELU, self).__init__()self.conv = nn.Sequential(nn.Conv2d(in_channel,out_channel,kernel_size,stride = stride, padding = padding),nn.BatchNorm2d(out_channel),nn.ReLU())def forward(self,x):x = self.conv(x)return x#SqueezeNext 网络
class SQUEEZENEXT(nn.Module):#初始化一些层和变量def __init__(self, in_channel, classes):super(SQUEEZENEXT, self).__init__()channels = [64,32,64,128,256]depth = [6,6,8,1]self.conv1 = nn.Sequential(nn.Conv2d(in_channel,channels[0],7,2,padding=7//2),nn.MaxPool2d(kernel_size=3,stride=2),nn.BatchNorm2d(channels[0]),nn.ReLU())self.block = Bottleself.stage1 = self._make_stage(6,channels[0],channels[1],stride = 1)self.stage2 = self._make_stage(6, channels[1], channels[2], stride=2)self.stage3 = self._make_stage(8, channels[2], channels[3], stride=2)self.stage4 = self._make_stage(1, channels[3], channels[4], stride=2)self.pool = nn.MaxPool2d(7)self.fc = nn.Linear(channels[4],classes)#每个 stage 层中所含的 blockdef _make_stage(self, num_stage, inchannel, ouchannel, stride):strides = [stride] + [1]*(num_stage-1)layer = []for i in range(num_stage):layer.append(self.block(inchannel,ouchannel,strides[i]))inchannel = ouchannelreturn nn.Sequential(*layer)#前向传播过程def forward(self,x):x = self.conv1(x)x = self.stage1(x)x = self.stage2(x)x = self.stage3(x)x = self.stage4(x)x = self.pool(x)x = x.view(x.size(0),-1)x = self.fc(x)return x

如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~
转载自:| https://www.cnblogs.com/ZOMI/articles/18561094 | header |
| ---------------------------------------------- | ------ |
| | |

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/851268.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows系统下Apollo搭建MQTT服务

第一步 准备部署文件 第二步 把jdk解压到位置 C:\Program Files 第三步 添加系统变量 变量:JAVA_HOME 值: C:\Program Files\jdk1.8.0_65 ClassPath Path 可直接用命令: Set JAVA_HOME=C:\Program Files\jdk1.8.0_65 Set classpath=%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\l…

转载:【AI系统】AI 编译器基本架构

在上篇文章中将 AI 编译器的发展大致分为了 3 个阶段,分别为 1)朴素编译器、2)专用编译器以及 3)通用编译器。 本文作为上一节 AI 编译器架构的一个延续,着重讨论 AI 编译器的通用架构。首先将回顾现有 AI 编译器架构(以 PyTorch 作为标杆),随后引出通用 AI 编译器的架…

转载:【AI系统】推理流程全景

本文介绍神经网络模型在部署态中的两种方式:云侧部署和边缘侧部署。其中,云侧部署适用于云服务器等具备强大计算能力和存储空间的环境,可以实现高吞吐量和集中的数据管理,但可能面临高成本、网络延迟和数据隐私等挑战。 边缘侧部署适用于边缘设备和移动设备等资源受限的环境…

删除文章后仍然能够动态浏览 plus/view.php?aid=*

问题描述 删除文章后,仍然能够通过 plus/view.php?aid=* 动态浏览文章。 解决方法检查伪静态设置登录DedeCMS后台,进入“系统” -> “系统基本参数” -> “核心设置”。 找到“是否启用伪静态”选项,将其设置为“否”。 保存设置。清空缓存登录DedeCMS后台,进入“系…

帝国CMS前台文章列表分页不显示怎么办

检查模板文件:确保模板文件中分页代码正确,例如[!–page–]。 检查分页设置:在后台的“系统设置”中检查分页设置是否正确。 检查SQL查询:确保SQL查询语句正确,特别是分页相关的查询。【遇到问题?加我解决】 专业团队,3分钟极速响应,为您解决疑难问题。 本文来自博客园…

修改帝国CMS网站根目录,如何操作? 如何修改帝国CMS网站根目录

备份数据:在进行任何修改之前,请确保备份了数据库和重要文件,以防万一出现问题可以快速恢复。 登录后台:通过浏览器访问您的帝国CMS后台管理界面,通常地址为 http://yourdomain/e/admin。 进入系统设置:在后台左侧菜单中找到“系统”选项,点击进入“系统参数设置”。 修…

静态网站模板如何修改,如何高效地调整静态网站模板以优化用户体验

静态网站模板的修改通常涉及HTML、CSS和JavaScript文件的编辑。为了高效地进行这些修改,可以遵循以下步骤:备份现有文件:在开始任何修改之前,确保备份当前的网站文件。这可以在本地硬盘或云端存储服务中完成,以防修改过程中出现错误。确定修改目标:明确你需要修改的具体内…

PbootCMS网站出现“非法访问”错误,可能的原因有哪些?

当你在访问PbootCMS网站时遇到“非法访问”错误,这可能是由多种原因引起的。以下是一些常见的错误原因及相应的解决方法:权限问题:文件和目录权限:服务器上的文件和目录权限设置不当可能导致“非法访问”错误。确保所有文件和目录的权限设置正确。通常,文件权限应设置为64…

Z-BlogPHP 的 ZC_PERMANENT_DOMAIN_FORCED_URL 配置项有什么作用?

在 Z-BlogPHP 中,ZC_PERMANENT_DOMAIN_FORCED_URL 配置项用于强制开启固定域名功能并直接指定一个固定的域名。这个配置项对于确保所有访问请求都通过一个特定的域名进行非常有用,有助于提升用户体验和 SEO 效果。以下是详细的说明和应用场景: 作用强制开启固定域名功能:启…

宝塔面板推荐使用的操作系统有哪些?

宝塔面板推荐使用的操作系统包括以下几种:Debian-12:Debian 是一个非常稳定和可靠的Linux发行版,Debian-12 版本提供了最新的软件包和技术支持,非常适合用于生产环境。 Ubuntu-22:Ubuntu 是另一个非常流行的Linux发行版,Ubuntu-22 版本同样提供了最新的软件包和技术支持,…

冬季节假日跨境电商忙碌期,哪些团队软件助力运营效率飞升?

在跨境电商行业,冬季节假日往往是订单的高峰期。这个时期,跨境电商团队需要高效地协调运营、营销、客服、物流等多个环节。可视化团队协作办公软件成为了提升工作效率和确保业务顺利运转的关键因素。今天,我们将站在 J 人跨境电商行业团队公司的角度,为大家盘点 5 款可视化…

Hex文件格式解析

BIN文件和HEX文件是两种常见的文件格式,尤其在嵌入式系统和软件开发领域有广泛应用。以下是对这两种文件的详细介绍以及它们之间的区别:一、介绍 BIN文件和HEX文件是两种常见的文件格式,尤其在嵌入式系统和软件开发领域有广泛应用。以下是对这两种文件的详细介绍以及它们之间…