【小白学PyTorch】13 EfficientNet详解及PyTorch实现
参考目录:
文章来自微信公众号【机器学习炼丹术】。我是炼丹兄,如果有疑问或者想要和炼丹兄交流的可以加微信:cyx645016617.
efficientNet的论文原文链接: https://arxiv.org/pdf/1905.11946.pdf
模型扩展Model scaling一直以来都是提高卷积神经网络效果的重要方法。
比如说,ResNet可以增加层数从ResNet18扩展到ResNet200。这次,我们要介绍的是最新的网络结构——EfficientNet,就是一种标准化的模型扩展结果,通过下面的图,我们可以i只管的体会到EfficientNet b0-b7在ImageNet上的效果:对于ImageNet历史上的各种网络而言,可以说EfficientNet在效果上实现了碾压
1 EfficientNet
1.1 概述
一般我们在扩展网络的时候,一般通过调成输入图像的大小、网络的深度和宽度(卷积通道数,也就是channel数)。在EfficientNet之前,没有研究工作只是针对这三个维度中的某一个维度进行调整,因为没钱啊!!有限的计算能力,很少有研究对这三个维度进行综合调整的。
EfficientNet的设想就是能否设计一个标准化的卷积网络扩展方法,既可以实现较高的准确率,又可以充分的节省算力资源。因而问题可以描述成,如何平衡分辨率、深度和宽度这三个维度,来实现拘拿及网络在效率和准确率上的优化
EfficientNet给出的解决方案是提出了这个模型复合缩放方法 (compound scaling methed)
图a是一个基线网络,也就是我们所说的baseline,图b,c,d三个网络分别对该基线网络的宽度、深度、和输入分辨率进行了扩展,而最右边的e图,就是EfficientNet的主要思想,综合宽度、深度和分辨率对网络进行符合扩展。
1.2 把扩展问题用数学来描述
首先,我们把整个卷积网络称为N,他的第i个卷积层可以看作下面的函数映射:
Yi是输出张量,Xi是输入张量,假设这个Xi的维度是<Hi,Wi,Ci>(这里省略了Batch的维度),那么这个整个卷积网络N,是由k个卷积层组成的,因此可以表示为:
通常情况,一个神经网络会有多个相同的卷积层存在,因此,我们称多个结构相同的卷积层为一个stage。举个例子:ResNet可以分为5个stage,每一个stage中的卷积层结构相同(除了第一层为降采样层),前四个stage都是baseblock,第五个stage是fc层。不太理解的可以看这个:【从零学习PyTorch】 如何残差网络resnet作为pre-model +代码讲解+残差网络resnet是个啥
总之,我们以stage为单位,将上面的卷积网络N改成为:
其中,下表1...s表示stage的讯号,Fi表示对第i层的卷积运算,Li的意思是Fi在第i个stage中有Li个一样结构的卷积层。<Hi, Wi, Ci>表示第i层输入的shape。
为了减小搜索空间,作者先固定了网络的基本结构,而只改变上面公式中的三个缩放维度。还记得之前我们提高的分辨率,宽度,深度吗?
- Li就是深度,Li越大重复的卷积层越多,网络越深;
- Ci就是channel数目,也就是网络的宽度
- Hi和Wi就是图片的分辨率
就算如此,这也有三个参数要调整,搜索空间也是非常的大,因此EfficientNet的设想是一个卷积网络所有的卷积层必须通过相同的比例常数进行统一扩展,这句话的意思是,三个参数乘上常熟倍率。所以个一个模型的扩展问题,就用数学语言描述为:
其中,d、w和r分别表示网络深度、宽度和分辨率的倍率。这个算式表现为在给定计算内存和效率的约束下,如何优化参数d、w和r来实现最好的模型准确率。
1.3 实验内容
上面问题的难点在于,三个倍率之间是由内在联系的,比如更高分辨率的图片就需要更深的网络来增大感受野的捕捉特征。因此作者做了两个实验(实际应该是做了很多的实验)来说明:
(1) 第一个实验,对三个维度固定了两个,只方法其中一个,得到的结果如下:
从左到右分别是只放大了网络宽度(width,w为放大倍率)、网络深度(depth,d为放大倍率)和图像分辨率(resolution, r为放大倍率)。我们可以看到,单个维度的放大最高精度只有80左右,本次实验,作者得出一个管带你:三个维度中任一维度的放大都可以带来精度的提升,但是随着倍率的越来越大,提升越来越小。
(2)于是作者做了第二个实验,尝试在不同的d,r组合下变动w,得到下图:
从实验结果来看,最高精度相比之前已经有所提升,突破了80大关。而且组合不同,效果不同。作者又得到了一个观点:得到了更高的精度以及效率的关键是平衡网络的宽度,网络深度,网络分辨率三个维度的缩放倍率
1.4 compound scaling method
这时候作者提出了这个方法
EfficientNet的规范化复合调参方法使用了一个复合系数\(\phi\),来对三个参数进行符合调整:
其中的\(\alpha, \beta, \gamma\)都是常数,可以通过网格搜索获得。复合系数通过人工调节。考虑到如果网络深度翻番那么对应的计算量翻番,网络宽度和图像分辨率翻番对应的计算量会翻4番,卷积操作的计算量与\(d,w^2 ,r^2\)成正比,。在这个约束下,网络的计算量大约是之前的\(2^\phi\)倍
以上就是EfficientNet的复合扩展的方式,但是这仅仅是一种模型扩展方式,我们还没有讲到EfficientNet到底是一个什么样的网络。
1.5 EfficientNet的基线模型
EfficientNet使用了MobileNet V2中的MBCConv作为模型的主干网络,同时也是用了SENet中的squeeze and excitation方法对网络结构进行了优化。 MBCConv是mobileNet中的基本结构,关于什么是MBCconv在百度上很少有解释,通过阅读论文和Google这里有一个比较好的解释:
The MBConv block is nothing fancy but an Inverted Residual Block (used in MobileNetV2) with a Squeeze and Excite block injected sometimes.
MBCconv就是一个MobileNet的倒残差模块,但是这个模块中还封装了Squeeze and Excite的方法。
总之呢,综合了MBConv和squeeze and excitation方法的EfficientNet-B0的网络结构如下表所示:
对于EfficientNet-B0这样的一个基线网络,如何使用复合扩展发对该网络进行扩展呢?这里主要是分两步走:还记得这个规划问题吗?
(1)第一步,先将复合系数\(\phi\)固定为1,先假设有两倍以上的计算资源可以用,然后对\(\alpha, \beta, \gamma\)进行网络搜索。对于EfficientNet-B0网络,在约束条件为
\]
时,\(\alpha, \beta, \gamma\)分别取1.2,1.1和1.15时效果最佳。第二步是固定\(\alpha, \beta, \gamma\),通过复合调整公式对基线网络进行扩展,得到B1到B7网络。于是就有了开头的这一张图片,EfficientNet在ImageNet上的效果碾压,而且模型规模比此前的GPipe小了8.4倍。
普通人来训练和扩展EfficientNet实在过于昂贵,所以对于我们来说,最好的方法就是迁移学习,下面我们来看如何用PyTorch来做迁移学习。
2 PyTorch实现
之前也提到了,在torchvision中并没有加入efficientNet所以这里我们使用某一位大佬贡献的API。有一个这样的文件Efficient_PyTorch,里面存放了b0到b8的预训练模型存储文件,我们将会调用这个API。因为这里我们没有直接使用pip进行安装,所以需要将这个库函数设置成系统路径。Pycharm中很多朋友会踩着个坑,不知道如何设置成系统路径:
点击Sources Root之后,就可以直接import了。
整个代码非常少,因为都写成API接口了嘛:
from efficientnet_pytorch import EfficientNet
model = EfficientNet.from_name('efficientnet-b0')
print(model)
打印的模型可以看,我加了详细的注解(快夸我):
整个b0的结构和论文中的结构相同:
从上图中可以知道,总共有16个MBConv模块;在第16个时候的输出通道为320个通道;
从运行结果来看,结构相同。总之这就是EfficientNet的结构,原理和调用方式。
【小白学PyTorch】13 EfficientNet详解及PyTorch实现的更多相关文章
- 【小白学PyTorch】11 MobileNet详解及PyTorch实现
文章来自微信公众号[机器学习炼丹术].我是炼丹兄,欢迎加我微信好友交流学习:cyx645016617. @ 目录 1 背景 2 深度可分离卷积 2.2 一般卷积计算量 2.2 深度可分离卷积计算量 2 ...
- Pytorch autograd,backward详解
平常都是无脑使用backward,每次看到别人的代码里使用诸如autograd.grad这种方法的时候就有点抵触,今天花了点时间了解了一下原理,写下笔记以供以后参考.以下笔记基于Pytorch1.0 ...
- 【小白学PyTorch】10 pytorch常见运算详解
参考目录: 目录 1 矩阵与标量 2 哈达玛积 3 矩阵乘法 4 幂与开方 5 对数运算 6 近似值运算 7 剪裁运算 这一课主要是讲解PyTorch中的一些运算,加减乘除这些,当然还有矩阵的乘法这些 ...
- 【小白学PyTorch】12 SENet详解及PyTorch实现
文章来自微信公众号[机器学习炼丹术].我是炼丹兄,有什么问题都可以来找我交流,近期建立了微信交流群,也在朋友圈抽奖赠书十多本了.我的微信是cyx645016617,欢迎各位朋友. 参考目录: @ 目录 ...
- 在CentOS上编译安装MySQL 5.7.13步骤详解
MySQL 5.7主要特性 更好的性能 对于多核CPU.固态硬盘.锁有着更好的优化,每秒100W QPS已不再是MySQL的追求,下个版本能否上200W QPS才是用户更关心的. 更好的InnoDB存 ...
- 一起学SpringMVC之RequestMapping详解
本文以一个简单的小例子,简述SpringMVC开发中RequestMapping的相关应用,仅供学习分享使用,如有不足之处,还请指正. 什么是RequestMapping? RequestMappin ...
- Pytorch数据读取详解
原文:http://studyai.com/article/11efc2bf#%E9%87%87%E6%A0%B7%E5%99%A8%20Sampler%20&%20BatchSampler ...
- 【Linux】一步一步学Linux——Linux系统目录详解(09)
目录 00. 目录 01. 文件系统介绍 02. 常用目录介绍 03. /etc目录文件 04. /dev目录文件 05. /usr目录文件 06. /var目录文件 07. /proc 08. 比较 ...
- Appium自动化(13) - 详解 Keyboard 类里的方法和源码分析
如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 Keyboard 类在 a ...
随机推荐
- Java GUI 图书管理系统
01 概述 一款功能强大的图书馆管理系统,功能齐全,小白/大学生项目实训,学习的不二之选. 02 技术 此系统使用 java awt 实现.java.awt是一个软件包,包含用于创建用户界面和绘制图形 ...
- java父类子类代码
import java.util.Scanner;import java.util.*; class PersonF{ public void print(String ID,String Workc ...
- 起源seo为何要做seo培训
http://www.wocaoseo.com/thread-91-1-1.html 焦大,在2010年末左右开始接触seo,2011年3月份正式开始做seo,到如今做seo已经3年了,实话说我没有其 ...
- Excel—TIME函数简介与用法
问题场景 算员工饱和度时,需要从实际考勤打卡时间中减去午休时间1.5个小时: 导出的时间时分秒是分开的,连接时分秒. 场景一 计算员工饱和度,需要减去午休时间,用下班打卡时间减去午休的1.5小时算出的 ...
- win环境下安装配置openCV-4.3.0
win环境下安装openCV-4.3.0 首先下载 推荐国内镜像 官网太太太慢了 附上 下载地址 下载之后打开exe解压到目录都是常规操作 环境变量的配置 依次打开到系统变量的path 新建一个路径为 ...
- 快速幂 (C++)
typedef long long LL; using namespace std; //求a^b%m,递归写法 LL binaryPow(LL a,LL b,LL m){ if(b==){ //如果 ...
- Python编程进阶,Python如何实现多进程?
进程part1 一.进程介绍 1.获取子父进程 2.进程的基本使用 2.创建带有参数的进程 3.进程之间的数据彼此隔离 4.多个进程之间的异步并发 二.join 1.基本语法 2.使用自定义类的方法创 ...
- vue、react等SPA应用页脚组件闪烁的解决办法
大家好,我是木瓜太香.大家在开发单页应用的时候,经常会遇到这样的需求,头部和尾部两个组件是大多数组件公用的,而中间的内容区域则是单独存在的,而且一般内容组件逻辑会比较多,如果我们不停刷新页面可能会出现 ...
- xAxis&yAxis
const option = { color: ['#546570', '#2f4554', '#61a0a8'], xAxis: { type: 'category', data: ['Mon', ...
- Spring security OAuth2.0认证授权学习第二天(基础概念-RBAC)
RBAC 基于角色的访问控制 基于角色的访问控制用代码实现一下其实就是一个if的问题if(如果有角色1){ } 如果某个角色可以访问某个功能,当某一天其他的另一个角色也可以访问了,那么代码就需要变化, ...