Xception 算法详解

news2024/11/24 20:54:11

📮 本次重点(模型轻量化):
● Inception设计理念
● 点卷积
● 深度可分离卷积
● Bottleneck结构
注:Xception算法整体结构是其次,主要是了解以上四个结构。

今天详解Xception算法,由于Xception模型在极大的减少了网络参数量和计算复杂度的同时,可以保持卓越的性能表现。因此,Xception模型已经被广泛地应用与图像分类、目标检测等任务中。

一、理论基础

1.前言

在计算机视觉领域,卷积神经网络(CNN)已经成为最主流的方法,比如GoogLenet,VGG-16,Incepetion等模型。CNN史上的一个里程碑事件是ResNet模型的出现,ResNet可以训练出更深的CNN模型,从而实现更高的准确度。ResNet模型的核心是通过建立前面层与后面层之间的“短路连接”,进而训练出更深的CNN网络。

随着图像分类的准确率不断提高,网络的深度越来越深,图像分类的错误率也越来越低,从2012的AlexNet,2013年的ZFNet,2014年的GoogLeNet,再到后面2015年的ResNet,准确率已经超过了人类的水平,所以单纯从准确率方面考虑的话已经很难提升了;因此人们就开始从其他方面考虑,比如参数量和计算量,软硬件协同等。

今天我们要介绍的是Xception模型,Xception是Google继Inception后提出的对Inception V3的另一种改进,主要是采用深度可分离卷积(Depthwise Separable Convolution)来替换原来Inception V3中的卷积操作。
在这里插入图片描述

论文原文:Xception.pdf

2.设计理念

前面说了,由于CNN模型的精度已经很难进一步提升,所以研究者们就把注意力放到了减少模型参数量和计算量上,因此Xception应运而生。而Xception就是研究者们在Inception V3模型上的进一步改进,通过用深度可分离卷积替换Inception V3中的多尺寸卷积核特征响应操作,最终达到了精度的略微提升和参数量的减少。在讲解Xception之前,我们先对它的前身Inception进行一番了解,然后再一步步往Xception方面讲述。

2.1多尺度卷积核
Inception 最初提出的版本,其核心思想就是使用多尺寸卷积核去观察输入数据。

举个例子,我们看某个景象由于远近不同,同一个物体的大小也会有所不同,那么不同尺度的卷积核观察的特征就会有这样的结果。于是就有了如下的网络结构图:
在这里插入图片描述
于是我们的网络就变胖了,增加了网络的宽度,同时也提高了对于不同尺度的适应程度。

2.2 点卷积(Pointwise Conv)
但是我们的网络变胖了的同时,计算量也变大了,所以我们就要想办法减少参数量来减少计算量,于是在Inception v1 中的最终版本加上了1x1 卷积核。

在这里插入图片描述

使用 1x1 卷积核对输入的特征图进行降维处理,这样就会极大得减少参数量,从而减少计算。

举例,输入数据的维度是256维,经过1x1 卷积之后,我们输出的维度是64维,参数量是原来的 1 4 \frac{1}{4} 41

这就是 Pointwise Convolution,俗称叫做 1x1 卷积,简写为 PW,主要用于数据降维,减少参数量。

2.3 卷积核替换

就算有了 PW ,由于 5x5 和 7x7 卷积核直接计算参数量还是非常大,训练时间还是比较长,我们还要再优化。

人类的智慧是无穷的,于是就想出了使用多个小卷积核替代大卷积核 的方法,这就是 Inception v3,如图3所示:
在这里插入图片描述
使用两个 3x3 卷积核来代替 5x5 卷积,效果上差不多,但参数量减少很多,达到了优化的目的。不仅参数量少,层数也多了,深度也变深了。

除了规整的的正方形,我们还有分解版本的 3x3 = 3x1 + 1x3,这个效果在深度较深的情况下比规整的卷积核更好。

在这里插入图片描述
我们假设输入 256 维,输出 512 维,计算一下参数量:

5x5 卷积核: 256 × 5 × 5 × 512 = 3276800 256\times5\times5\times512=3276800 256×5×5×512=3276800
两个 3x3 卷积核: 256 × 3 × 3 × 256 + 256 × 3 × 3 × 512 = 589824 + 1179648 = 1769472 256\times3\times3\times256+256\times3\times3\times512=589824+1179648=1769472 256×3×3×256+256×3×3×512=589824+1179648=1769472

结果对比: 1769472 3276800 = 0.54 \frac{1769472}{3276800}=0.54 32768001769472=0.54
我们可以看到参数量对比,两个 3x3 的卷积核的参数量是 5x5 一半,可以大大加快训练速度。

2.4 Bottleneck

我们发现就算用了上面的结构和方法,我们的参数量还是很大,于是乎我们结合上面的方法创造出了 Bottleneck 的结构降低参数量。

Bottleneck 三步走是先 PW卷积 对数据进行降维,再进行常规卷积核的卷积,最后 PW 卷积对数据进行升维。我们举个例子,方便我们了解:
在这里插入图片描述
根据上图,我们来做个对比计算,假设输入 feature map 的维度为 256 维,要求输出维度也是 256 维。有以下两种操作:
● 直接使用 3x3 的卷积核。256 维的输入直接经过一个 3×3×256 的卷积层,输出一个 256 维的 feature map ,那么参数量为:256×3×3×256 = 589,824 。
● 先经过 1x1 的卷积核,再经过 3x3 卷积核,最后经过一个 1x1 卷积核。 256 维的输入先经过一个 1×1×64 的卷积层,再经过一个 3x3x64 的卷积层,最后经过 1x1x256 的卷积层,则总参数量为:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632 。
经过两种方式的对比,我们可以很明显的看到后者的参数量远小于前者的。

2.5 深度可分离卷积(Depthwise Separable Convolutions)

深度可分离卷积(Depthwise Separable Convolutions)不同之处在于,其不仅仅涉及空间维度,还涉及深度维度(即 channel 维度)相较于常规卷积操作,其参数数量和运算成本比较低。通常输入图像会具有3个channel:R、G、B。在经过一系列卷积操作后,输入特征图就会变为多个channel。对于每个channel而言,我们可以将其想成对该图像某种特定特征的解释说明。例如输入图像中,“红色” channel 解释描述了图像中的“红色”特征,“绿色” channel 解释描述了图像中的“绿色”特征,“蓝色” channel 解释描述了图像中的“蓝色”特征。又例如 channel 数量为64的输出特征图,就相当于对原始输入图像的64种不同的特征进行了解释说明。
在这里插入图片描述
类似空间可分离卷积,深度可分离卷积也是将卷积核分成两个单独的小卷积核,分别进行2种卷积运算:深度卷积运算和逐点卷积运算。 首先,让我们看看正常的卷积是如何工作的。

1)标准卷积
假设我们有一个 12 × 12 × 3 12\times12\times3 12×12×3的输入图像,即图像尺寸为 12 × 12 12\times12 12×12,通道数为 3 3 3,对图像进行 5 × 5 5\times5 5×5卷积,没有填充(padding)且步长为1。如果我们只考虑图像的宽度和高度,使用 5 × 5 5\times5 5×5卷积来处理 12 × 12 12\times12 12×12大小的输入图像,最终可以得到一个 8 × 8 8\times8 8×8的输出特征图。至于如何计算的就涉及到卷积运算了,这里给出一个动图1解释如下:
在这里插入图片描述
图1 单通道卷积运算

然而,由于图像有3个通道,我们的卷积核也需要有3个通道。 这就意味着,卷积核在每个位置进行计算时,实际上会执行 5 × 5 × 3 = 75 5\times5\times3=75 5×5×3=75次乘法。如图2所示,我们使用一个 5 × 5 × 3 5\times5\times3 5×5×3的卷积核进行运算,最终可以得到 8 × 8 × 1 8\times8\times1 8×8×1的输出特征图。
在这里插入图片描述
单个三通道特征图卷积计算过程也可以用一张动图3解释如下:
在这里插入图片描述
图3 单个三通道特征图卷积运算

如果我们想增加输出的 channel 数量让网络学习更多种特征呢?这时我们可以创建多个卷积核,比如256个卷积核来学习256个不同类别的特征。此时,256个卷积核会分别进行运算,得到256个 8 × 8 × 1 8\times8\times1 8×8×1的输出特征图。如 图4 所示。

在这里插入图片描述
图4 输出通道为256的标准卷积

2)深度卷积运算
我们第二个已经讲解过了DW卷积,而深度可分离卷积就运用到了DW卷积。首先,我们对输入图像进行深度卷积运算,这里的深度卷积运算其实就是逐通道进行卷积运算。对于一副 12 × 12 × 3 12\times12\times3 12×12×3的输入图像而言,我们使用大小为 5 × 5 5\times5 5×5的卷积核进行逐通道计算,计算方式如图5所示:
在这里插入图片描述
图5 深度卷积运算

这里其实就是使用3个 5 × 5 × 1 5\times5\times1 5×5×1的卷积核分别提取输入图像中3个 channel 的特征,每个卷积核计算完成后,会得到3个 8 × 8 × 1 8\times8\times1 8×8×1的输出特征图,将这些特征图堆叠在一起就可以得到大小为 8 × 8 × 3 8\times8\times3 8×8×3的最终输出特征图。这里我们可以发现深度卷积运算的一个缺点,即深度卷积运算缺少通道间的特征融合 ,并且运算前后通道数无法改变。

因此,接下来就需要连接一个逐点卷积来弥补它的缺点。

3)逐点卷积运算

前面我们使用深度卷积运算完成了从一幅 12 × 12 × 3 12\times12\times3 12×12×3的输入图像中得到 8 × 8 × 3 8\times8\times3 8×8×3的输出特征图,并且发现仅使用深度卷积无法实现不同通道间的特征融合,而且也无法得到与标准卷积运算一致的 8 × 8 × 256 8\times8\times256 8×8×256的特征图。那么,接下来就让我们看一下如何使用逐点卷积实现这两个任务。逐点卷积其实就是 1 × 1 1\times1 1×1卷积,因为其会遍历每个点,所以我们称之为逐点卷积。 1 × 1 1\times1 1×1卷积在前面的内容中已经详细介绍了,这里我们还是结合上边的例子看一下它的具体作用。

我们使用一个3通道的 1 × 1 1\times1 1×1卷积对上文中得到的 8 × 8 × 3 8\times8\times3 8×8×3的特征图进行运算,可以得到一个 8 × 8 × 1 8\times8\times1 8×8×1的输出特征图。如 图6 所示。此时,我们就使用逐点卷积实现了融合3个通道间特征的功能。

在这里插入图片描述
此外,我们可以创建256个3通道的 1 × 1 1\times1 1×1卷积对上文中得到的 8 × 8 × 3 8\times8\times3 8×8×3的特征图进行运算,这样,就可以实现得到与标准卷积运算一致的 8 × 8 × 256 8\times8\times256 8×8×256的特征图的功能。如 图7 所示。
在这里插入图片描述
图7 输出通道为256的逐点卷积

4)深度可分离卷积的意义
上文中,我们给出了深度可分离卷积的具体计算方式,那么使用深度可分离卷积代替标准卷积有什么意义呢?

这里我们看一下上文例子中标准卷积的乘法运算个数,我们创建了256个 5 × 5 × 3 5\times5\times3 5×5×3的卷积核进行卷积运算,每个卷积核会在输入图片上移动 8 × 8 8\times8 8×8次,因此总的乘法运算个数为:

256 × 3 × 5 × 5 × 8 × 8 = 1228800 256\times3\times5\times5\times8\times8=1228800 256×3×5×5×8×8=1228800

而换成深度可分离卷积后,在深度卷积运算时,我们使用3个 5 × 5 × 1 5\times5\times1 5×5×1的卷积核在输入图片上移动 8 × 8 8\times8 8×8次,此时乘法运算个数为:

$3\times5\times5\times8\times8=4800

在逐点卷积运算时,我们使用256个 1 × 1 × 3 1\times1\times3 1×1×3的卷积在输入特征图上移动 8 × 8 8\times8 8×8次,此时乘法运算个数为:

256 × 1 × 1 × 3 × 8 × 8 = 49152 256\times1\times1\times3\times8\times8=49152 256×1×1×3×8×8=49152

将这两步运算相加,即可得到,使用深度可分离卷积后,总的乘法运算个数变为:53952。可以看到,深度可分离卷积的运算量相较标准卷积而言,计算量少了很多。

3.网络结构

Xception的具体网络结构如图11所示:
在这里插入图片描述
图11 Xception网络结构

Xception包含三个部分:输入部分(Entry flow),中间部分(Middle flow)和结尾部分(Exit flow);其中所有卷积层和可分离卷积层后面都使用Batch Normalization处理,所有的可分离卷积层使用一个深度乘数1(深度方向并不进行扩充)。

对于Entry flow,首先使用了两个3x3卷积(conv1,conv2)降低特征图尺寸,同时增加了特征图个数;接着是3个含跳连的深度可分离卷积堆叠模块。

对于Middle flow,包含了8个一模一样的含跳连的深度可分离卷积堆叠模块。

对于Exit flow,首先是一个含跳连的深度可分离卷积堆叠模块,接着是一些深度可分离卷积层以及全局平均池化层,最后用全连接层输出分类结果。

二、搭建网络模型

🏡 我的环境:
● 语言环境:Python3.8
● 编译器:Jupyter Lab
● 深度学习环境:Pytorch
○ torch1.12.1+cu113
○ torchvision
0.13.1+cu113

1. SeparableConv模块定义
结构图中的SeparableConv组件就是depthwise separable convolution(深度可分离卷积),它是由depthwise conv(dw)和pointwise conv(pw)组成。根据原论文描述,dw与pw的先后顺序对最终效果并无影响,其结构定义如下

class SeparableConv(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
        super(SeparableConv, self).__init__()
        self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groups=in_channels)
        self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1)
        
    def forward(self, x):
        x = self.depthwise(x)
        x = self.pointwise(x)
        return x

2. XceptionBlock_1定义
根据结构图,Entry flow由两个卷积层和三个相同的子模块构成,我们将这个子模块命名为XceptionBlock_1,其结构如上图。可以看出,XceptionBlock_1的两个分支以残差的的形式进行连接,其中主分支需要经过两个SeparableConv层和一个最大池化层,残差分支则经过步距为2的1*1卷积层。XceptionBlock_1模块的定义如下

在这里插入图片描述

class XceptionBlock_1(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(XceptionBlock_1, self).__init__()
        self.relu = nn.ReLU()
        self.sepconv1 = SeparableConv(in_channels, out_channels, kernel_size=3, padding=

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

优思学院|精益生产3大特征:拉动式生产、消除浪费、自働化

在现代制造业中,精益生产作为一种高效的生产方式,受到了广泛的关注和应用。它的核心理念是通过最大程度地减少浪费和提高效率来实现生产过程的优化。经典的精益体系从中提炼出了精益生产的三大特征,分别是拉动式生产、消除浪费以及自働化。让…

JSON.stringify循环引用问题

前端使用到对象的深度复制通常会简单的使用JSON.parse(JSON.stringify(obj))实现 (浅表复制会用Array.from、Object.assign、Object.create静态方法实现),但在对象存在循环引用的情况下(比如:树结构中子对象存在parent…

使用JavaScript实现页面滑动切换效果

使用JavaScript实现页面滑动切换效果 在现代Web页面设计中,页面滑动切换效果已经成为了一种常见的设计要求,能够提升用户体验,增加页面的交互性。本文将通过JavaScript来实现这一效果。 首先,我们需要在HTML中添加一些基础结构和…

Linux 环境 nginx安装

这里写自定义目录标题 前言安装nginx依赖下载并解压nginx安装包和ngx_http_proxy_connect_module模块解压nginx安装包 和 ngx_http_proxy_connect_module模块编译ngx_http_proxy_connect_module模块和安装nginx感谢 前言 确定环境是有网的环境,且yum源可用&#xf…

【广州华锐视点】VR燃气轮机故障判断模拟演练系统

VR燃气轮机故障判断模拟演练系统由广州华锐视点开发,是一款基于虚拟现实技术的教育工具,旨在为学生提供一个安全、高效、互动的学习环境,帮助他们更好地掌握燃气轮机的故障诊断技能。 这款VR实训软件能够模拟真实的燃气轮机故障诊断场景&…

一种水文水利行业满管非满管双声道流量计安装调试

供电电源 用户应该特别注意:若是交流(AC220V)供电的主机插入直流电源,或者直流(DC24V)供电的主机接入AC220V电源,就会把流量计烧毁。 普通主机(包括固定式主机、盘装式主机&#x…

Android之消除APP图标的白色边框

有问题的效果: 解决方案: 第一步:app右键—>new—>Image Asset 第二步:上传Logo图标,选择每种分辨率,预览看效果,选择Resize,可以微调 第三步:点击 Next&#xff…

RFID工业识别技术:供应链智能化的科技颠覆

RFID工业识别技术,作为物联网的先锋,正在供应链管理领域展现着前所未有的科技颠覆。从物料追踪到库存管理,再到物流配送,RFID技术以其高效的数据采集和智能的自动化处理,彻底改变着传统供应链的运营方式。 RFID在物料追…

C++之std::pair与vector<pair>用法(一百七十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

传统图像算法 - 运动目标检测之KNN运动背景分割算法

以下代码用OpenCV实现了视频中背景消除和提取的建模,涉及到KNN(K近邻算法),整体效果比较好,可以用来进行运动状态分析。 原理如下: 背景建模:在背景分割的开始阶段,建立背景模型。 …

【C语言】扫雷 小游戏

文章目录 一、游戏规则二、 代码逻辑三、游戏实现1. 游戏菜单设计2.设计雷区并随机布置雷(1) 设置雷区(2) 布置雷 3.排查雷 四、源码 一、游戏规则 1. 在9*9的小格子中,任意选取一个坐标(格子),选择后发现,如果没点中雷…

UE5、CesiumForUnreal接入WMTS格式地图瓦片,如ArcGIS、Mapbox、天地图

文章目录 1.实现目标2.实现过程2.1 WMTS与TMS2.2 cesium-native改造2.3 CesiumForUnreal插件改造2.4 WMTS瓦片加载测试2.5 EPSG:3857与43263.参考资料1.实现目标 通过改造cesium-native和CesiumForUnreal插件,参考tms的栅格瓦片地图加载逻辑,实现在UE5中通过CesiumForUnreal…

问道管理:信创概念走势活跃,恒银科技斩获四连板

信创概念9日盘中走势活泼,截至发稿,新晨科技、竞业达、恒银科技等涨停,宇信科技涨近10%,中孚信息涨近9%,华是科技、神州数码涨超7%。 新晨科技今天“20cm”涨停,公司昨日晚间公告,近来收到投标代…

HarmonyOS应用开发者基础认证考试题库

此博文为HarmonyOS应用开发者基础认证考试的最后的大考,要求100分取得90分方可获取证书、现将考试的题库进行分享,希望能帮到大家。但是需要注意的是,题库会不定时的进行题目删减,但是大概的内容是不会进行改变的。真心希望这篇博…

ModaHub魔搭社区——GPTCache是如何工作的?

在线服务通常表现出数据局部性,用户经常访问流行或趋势内容。缓存系统通过存储通常访问的数据来利用这种行为,这反过来减少了数据检索时间,提高了响应时间,并减轻了后端服务器的负担。传统缓存系统通常利用新查询和缓存查询之间的精确匹配来确定请求的内容在获取数据之前是…

SRS视频媒体服务器-docker启动:更换默认端口时的错误

一、概述 在使用srs视频服务器时,一直都是使用默认的端口配置。但是,这些默认端口在某些时候可能已经被占用了,就需要更改端口了。 注意注意注意:使用docker启动srs,在更换端口一定要下面的内容。 二、使用docker启动…

环保行业如何开发废品回收微信小程序

废品回收是近年来受到越来越多人关注的环保行动。为了推动废品回收的普及和方便,我们可以利用微信小程序进行制作,方便人们随时随地参与废品回收。 首先,我们需要注册并登录乔拓云账号,并进入后台。乔拓云是一个提供微信小程序制作…

【网络通信】socket编程——TCP套接字

TCP依旧使用代码来熟悉对应的套接字,很多接口都是在udp中使用过的 所以就不会单独把他们拿出来作为标题了,只会把第一次出现的接口作为标题 文章目录 服务端 tcp_servertcpserver.hpp(封装)初始化 initServer1. 创建socket2. 绑定 bindhtons —— 主机序…

Cortex-M3的双堆栈MSP和PSP(学习)

M3的栈,先进后出。 是局部变量内存的开销,函数的调用都离不开栈。 Cortex-M3内核使用了双堆栈,即MSP和PSP。 MSP:Main_Stack_Pointer,即主栈。 PSP:Process_Stack_Pointer,即任务栈。 SP&#…

如何在win7的右键菜单栏上添加“在此处打开Powershell”

打开regedit.exe 找到计算机\HKEY_CLASSES_ROOT\Directory\Background\shell。 在项下建立新项Powershell,并且在Powershell项下建立新项command,如图所示: 在Powershell的默认的项中填写名称在此处打开Powershell窗口。 新建字符串值Ex…