Xception:使用Tensorflow从头开始实现

一、说明

        近年来,卷积神经网络已成为计算机视觉领域的主要算法,开发设计它们的方法一直是相当的关注。Inception模型似乎能够用更少的参数学习更丰富的表示。它们是如何工作的,以及它们与常规卷积有何不同?本文将用tensorflow实现,用具体实践展现它的结构。

图1.Xception架构 

        卷积神经网络(CNN)已经走了很长一段路,从LeNet风格的AlexNet,VGG模型,它使用简单的卷积层堆栈进行特征提取,最大池化层用于空间子采样,一个接一个地堆叠,到Inception和ResNet网络,它们在每层中使用跳过连接和多个卷积和最大池块。自推出以来,计算机视觉中最好的网络之一就是Inception网络。Inception 模型使用一堆模块,每个模块包含一堆特征提取器,这允许它们使用更少的参数学习更丰富的表示。

        Xception论文— https://arxiv.org/abs/1610.02357

        如图 1 所示,Xception 模块有 3 个主要部分。入口流、中间流(重复 8 次)和退出流。

图2.Xception架构的入口流程 

        入口流有两个卷积层块,然后是 ReLU 激活。该图还详细提到了过滤器的数量、过滤器大小(内核大小)和步长。

        还有各种可分离卷积层。还有最大池化层。当步幅与步幅不同时,还会提到步幅。还有 Skip 连接,我们使用“ADD”来合并两个张量。它还显示了每个流中输入张量的形状。例如,我们从 299x299x3 的图像大小开始,在输入流程之后,我们得到的图像大小为 19x19x728。

图3.Xception架构的中出流程 

同样,对于中间流和退出流,此图清楚地解释了图像大小、各个层、滤镜数量、滤镜形状、池化类型、重复次数以及最终添加全连接层的选项。

此外,所有卷积和可分离卷积层之后都经过批量归一化。

二、可分离卷积层

图4.可分离卷积层(来源:作者创建的图像)

可分离卷积包括首先执行深度空间卷积(分别作用于每个输入通道),然后是逐点卷积,混合生成的输出通道。 来自 Keras 文档

假设我们有一个大小为 (K, K,3) 的输入张量。K 是空间维度,3 是特征图/通道的数量。正如我们从上面的 Keras 文档中看到的,首先我们需要在每个输入通道上分别实现深度空间卷积。所以我们使用 K, K,1 — 图像/张量的第一个通道。假设我们使用大小为 3x3x1 的过滤器。并且此过滤器应用于输入张量的所有三个通道。由于有 3 个通道,所以我们得到的尺寸是 3x3x1x3。如图 4 的深度卷积部分所示。

在此之后,将所有 3 个输出放在一起,我们得到大小为 (L, L,3) 的张量。L 的维度可以与 K 相同,也可以不同,具体取决于先前卷积中使用的步幅和填充。

然后应用逐点卷积。滤波器尺寸为 1x1x3(3 个通道)。过滤器的数量可以是我们想要的任意数量的过滤器。假设我们使用 64 个过滤器。因此,总尺寸为 1x1x3x64。最后,我们得到大小为 LxLx64 的输出张量。 如图 4 的逐点卷积部分所示。

为什么可分离卷积比普通卷积更好?

如果我们在输入张量上使用法线卷积,并且我们使用 3x3x3 的过滤器/内核大小(内核大小 — (3,3) 和 3 个特征图)。我们想要的过滤器总数是 64。所以总共有 3x3x3x64。

相反,在可分离卷积中,我们首先在深度卷积中使用 3x3x1x3,在逐点卷积中使用 1x1x3x64。

区别在于过滤器的维度。

传统卷积层 = 3x3x3x64 = 1,728

可分离卷积层 = (3x3x1x3)+(1x1x3x64) = 27+192 = 219

正如我们所看到的,可分离卷积层在计算成本和内存方面都比传统的卷积层更具优势。主要区别在于,在正常卷积中,我们会多次转换图像。每次变换都会使用 3x3x3x64 = 1,728 次乘法。在可分离卷积中,我们只转换图像一次——在深度卷积中。然后,我们获取转换后的图像并将其简单地拉长到 64 个通道。无需一遍又一遍地转换图像,我们可以节省计算能力。

图5.Xception性能与ImageNet上的Inception(来源:图片来自原始论文)

Figure 6. Xception performance vs Inception on JFT dataset (Source: Image from the original paper)

Algorithm:

  1. 导入所有必要的图层
  2. 为以下各项编写所有必要的函数:

一个。转换-批处理范数块

b. 可分离卷积 - 批处理范数块

3. 为 3 个流(入口、中间和退出)中的每一个编写一个函数

4. 使用这些函数构建完整的模型

三、使用 Tensorflow 创建 Xception

#import necessary librariesimport tensorflow as tf
from tensorflow.keras.layers import Input,Dense,Conv2D,Add
from tensorflow.keras.layers import SeparableConv2D,ReLU
from tensorflow.keras.layers import BatchNormalization,MaxPool2D
from tensorflow.keras.layers import GlobalAvgPool2D
from tensorflow.keras import Model

创建 Conv-BatchNorm 块:

# creating the Conv-Batch Norm blockdef conv_bn(x, filters, kernel_size, strides=1):x = Conv2D(filters=filters, kernel_size = kernel_size, strides=strides, padding = 'same', use_bias = False)(x)x = BatchNormalization()(x)
return x

Conv-Batch 范数块将张量 — x、过滤器数量 — 过滤器、卷积层的核大小 — kernel_size, 卷积层的步幅作为输入。然后我们将卷积层应用于 x,然后应用批量归一化。我们加上use_bias = False,这样最终模型的参数数量,将与原始论文的参数数量相同。

创建可分离的Conv-BatchNorm块:

# creating separableConv-Batch Norm blockdef sep_bn(x, filters, kernel_size, strides=1):x = SeparableConv2D(filters=filters, kernel_size = kernel_size, strides=strides, padding = 'same', use_bias = False)(x)x = BatchNormalization()(x)
return x

与 Conv-Batch Norm 块的结构类似,只是我们使用 SeparableConv2D 而不是 Conv2D。

入口、中间和退出流的函数:

# entry flowdef entry_flow(x):x = conv_bn(x, filters =32, kernel_size =3, strides=2)x = ReLU()(x)x = conv_bn(x, filters =64, kernel_size =3, strides=1)tensor = ReLU()(x)x = sep_bn(tensor, filters = 128, kernel_size =3)x = ReLU()(x)x = sep_bn(x, filters = 128, kernel_size =3)x = MaxPool2D(pool_size=3, strides=2, padding = 'same')(x)tensor = conv_bn(tensor, filters=128, kernel_size = 1,strides=2)x = Add()([tensor,x])x = ReLU()(x)x = sep_bn(x, filters =256, kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters =256, kernel_size=3)x = MaxPool2D(pool_size=3, strides=2, padding = 'same')(x)tensor = conv_bn(tensor, filters=256, kernel_size = 1,strides=2)x = Add()([tensor,x])x = ReLU()(x)x = sep_bn(x, filters =728, kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters =728, kernel_size=3)x = MaxPool2D(pool_size=3, strides=2, padding = 'same')(x)tensor = conv_bn(tensor, filters=728, kernel_size = 1,strides=2)x = Add()([tensor,x])
return x

        这里我们只遵循图 2。它从两个分别具有 32 个和 64 个过滤器的 Conv 层开始。每个之后都有一个 ReLU 激活。

        然后有一个跳过连接,这是通过使用 Add 完成的。

        在每个跳过连接块中,有两个可分离的 Conv 层,后跟 MaxPooling。跳过连接本身具有 1x1 的 Conv 层,步幅为 2。

图7.中流(来源:原文图片)

# middle flowdef middle_flow(tensor):for _ in range(8):x = ReLU()(tensor)x = sep_bn(x, filters = 728, kernel_size = 3)x = ReLU()(x)x = sep_bn(x, filters = 728, kernel_size = 3)x = ReLU()(x)x = sep_bn(x, filters = 728, kernel_size = 3)x = ReLU()(x)tensor = Add()([tensor,x])return tensor

中间流程遵循图 7 中所示的步骤。

图8.退出流程(来源:图片来自原文)

# exit flowdef exit_flow(tensor):x = ReLU()(tensor)x = sep_bn(x, filters = 728,  kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters = 1024,  kernel_size=3)x = MaxPool2D(pool_size = 3, strides = 2, padding ='same')(x)tensor = conv_bn(tensor, filters =1024, kernel_size=1, strides =2)x = Add()([tensor,x])x = sep_bn(x, filters = 1536,  kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters = 2048,  kernel_size=3)x = GlobalAvgPool2D()(x)x = Dense (units = 1000, activation = 'softmax')(x)return x

退出流程遵循如图 8 所示的步骤。

四、创建Xception模型:

# model codeinput = Input(shape = (299,299,3))
x = entry_flow(input)
x = middle_flow(x)
output = exit_flow(x)model = Model (inputs=input, outputs=output)
model.summary()

输出代码段:

from tensorflow.python.keras.utils.vis_utils import model_to_dot
from IPython.display import SVG
import pydot
import graphvizSVG(model_to_dot(model, show_shapes=True, show_layer_names=True, rankdir='TB',expand_nested=False, dpi=60, subgraph=False).create(prog='dot',format='svg'))

输出代码段:

import numpy as np 
import tensorflow.keras.backend as K 
np.sum([K.count_params(p) for p in model.trainable_weights])

输出:22855952

上面的代码显示了可训练参数的数量。

五、完整代码

使用Tensorflow从头开始创建Xception模型的完整代码:

#import necessary librariesimport tensorflow as tf
from tensorflow.keras.layers import Input,Dense,Conv2D,Add
from tensorflow.keras.layers import SeparableConv2D,ReLU
from tensorflow.keras.layers import BatchNormalization,MaxPool2D
from tensorflow.keras.layers import GlobalAvgPool2D
from tensorflow.keras import Model
# creating the Conv-Batch Norm blockdef conv_bn(x, filters, kernel_size, strides=1):x = Conv2D(filters=filters, kernel_size = kernel_size, strides=strides, padding = 'same', use_bias = False)(x)x = BatchNormalization()(x)
return x
# creating separableConv-Batch Norm blockdef sep_bn(x, filters, kernel_size, strides=1):x = SeparableConv2D(filters=filters, kernel_size = kernel_size, strides=strides, padding = 'same', use_bias = False)(x)x = BatchNormalization()(x)
return x
# entry flowdef entry_flow(x):x = conv_bn(x, filters =32, kernel_size =3, strides=2)x = ReLU()(x)x = conv_bn(x, filters =64, kernel_size =3, strides=1)tensor = ReLU()(x)x = sep_bn(tensor, filters = 128, kernel_size =3)x = ReLU()(x)x = sep_bn(x, filters = 128, kernel_size =3)x = MaxPool2D(pool_size=3, strides=2, padding = 'same')(x)tensor = conv_bn(tensor, filters=128, kernel_size = 1,strides=2)x = Add()([tensor,x])x = ReLU()(x)x = sep_bn(x, filters =256, kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters =256, kernel_size=3)x = MaxPool2D(pool_size=3, strides=2, padding = 'same')(x)tensor = conv_bn(tensor, filters=256, kernel_size = 1,strides=2)x = Add()([tensor,x])x = ReLU()(x)x = sep_bn(x, filters =728, kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters =728, kernel_size=3)x = MaxPool2D(pool_size=3, strides=2, padding = 'same')(x)tensor = conv_bn(tensor, filters=728, kernel_size = 1,strides=2)x = Add()([tensor,x])
return x
# middle flowdef middle_flow(tensor):for _ in range(8):x = ReLU()(tensor)x = sep_bn(x, filters = 728, kernel_size = 3)x = ReLU()(x)x = sep_bn(x, filters = 728, kernel_size = 3)x = ReLU()(x)x = sep_bn(x, filters = 728, kernel_size = 3)x = ReLU()(x)tensor = Add()([tensor,x])return tensor
# exit flowdef exit_flow(tensor):x = ReLU()(tensor)x = sep_bn(x, filters = 728,  kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters = 1024,  kernel_size=3)x = MaxPool2D(pool_size = 3, strides = 2, padding ='same')(x)tensor = conv_bn(tensor, filters =1024, kernel_size=1, strides =2)x = Add()([tensor,x])x = sep_bn(x, filters = 1536,  kernel_size=3)x = ReLU()(x)x = sep_bn(x, filters = 2048,  kernel_size=3)x = GlobalAvgPool2D()(x)x = Dense (units = 1000, activation = 'softmax')(x)return x
# model codeinput = Input(shape = (299,299,3))
x = entry_flow(input)
x = middle_flow(x)
output = exit_flow(x)model = Model (inputs=input, outputs=output)
model.summary()

六、结论 

        如图 5 和图 6 所示,与 ImageNet 数据集相比,Xception 架构在 JFT 数据集上的性能改进比 Inception 网络要好得多。Xception的作者认为,这是因为Inception被设计为专注于ImageNet,因此可能过于适合特定任务。另一方面,这两种架构都没有针对JFT数据集进行调优。

        此外,Inception 有大约 23 万个参数,而 Xception 有 6 万个参数。

        如图 1 所示,Xception 架构在论文中很容易解释,这使得使用 TensorFlow 实现网络架构变得非常容易。

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

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

相关文章

基本微信小程序的购物商城系统

项目介绍 随着互联网的趋势的到来,各行各业都在考虑利用互联网将自己的信息推广出去,最好方式就是建立自己的平台信息,并对其进行管理,随着现在智能手机的普及,人们对于智能手机里面的应用购物平台小程序也在不断的使…

谷歌浏览器 ERR_MANDATORY_PROXY_CONFIGURATION_FAILED 报错的处理方式

今天早上到公司 还是和往常一样 电脑开机 打开谷歌浏览器 搜索资料结果给我报错了 2.原先我的谷歌浏览器配置的搜索引擎为百度 3.电脑上面的火狐 ie浏览器都是可以的排除电脑网络方面的问题(dns也有解析谷歌路径的这个有兴趣的可以研究) 最终还是刷新了电脑的dns ,清除了谷歌…

嵌入式Linux裸机开发(六)EPIT 定时器

系列文章目录 文章目录 系列文章目录前言介绍配置过程前言 前面学的快崩溃了,这也太底层了,感觉学好至少得坚持一整年,我决定这节先把EPIT学了,下面把常见三种通信大概学一下,直接跳过其他的先学移植了,有些太多了内容。 介绍 EPIT(Enhanced Periodic Interrupt Timer…

CSS 中::after的妙用(实现在margin中显示内容)

效果图如下: 背景: 如上图,之前只是当纯的写一个参考货架平面图,用作物料系统的在库状态可视化,当完成页面body分成10等份时,货架之间需要有通道,为了实现实际的样式,我给每个等份都…

并发编程的三大特性

重要通知: 本人获得了一个运维的上市公司offer,问了一下就业的老师,都推荐能去就去,因为当下的环境,我这种专业需要985211学历才比较好找,所以我要去实习了(今年挺多是实习完才给签三方&#x…

SXSSFWorkbook-MinIo-大数据-流式导出

文章目录 前言业务现状架构思路技术细节生成摘要IDSXSSFWorkbookMinIomybatis 流查询PipedInputStream 保存到minio 总结 前言 由于业务涉及到数据比较大,用户对导出功能使用频繁,每次导出数据两10万以上。 为了减少数据库压力,及应用服务器…

docker搭建rocketmq集群

单机搭建 1 拉取rocketMq镜像 docker pull rocketmqinc/rocketmq:4.3.2 2 创建挂在目录 mkdir -p /mydata/rocketmq/data/namesrv/logs /mydata/rocketmq/data/namesrv/store mkdir -p /mydata/rocketmq/data/broker/logs /mydata/rocketmq/data/broker/store mkd…

使用LLM在KG上进行复杂的逻辑推理10.12

使用LLM在KG上进行复杂的逻辑推理 摘要介绍相关工作 摘要 在知识图谱上进行推理是一项具有挑战性的任务,这需要深度理解实体之间复杂的关系和它们关系的逻辑。而当前的方法通常依赖于学习 几何形状 以将实体嵌入到向量空间中进行逻辑查询操作,但在复杂查…

必知必会的22种设计模式(GO语言)

日常工作中免不了使用设计模式,那么你使用了哪些设计模式呢? 设计模式是什么? 设计模式是一种在软件设计中对常见问题的通用解决方案。 它们是经过验证的、可重用的设计思想,可以帮助解决开发过程中遇到的各种问题。 设计模式…

三次挥手和四次握手

TCP建立连接(三次握手) 经过DNS域名解析后,获取到了服务器的IP地址,在获取到IP地址后,便会开始建立一次连接,这是由TCP协议完成的,主要通过三次握手进行连接。 第一次握手: 建立连…

整理mongodb文档:副本集成员可以为偶数

个人博客 整理mongodb文档:副本集成员可以为偶数 想了下,仲裁节点还是不想直接说太多,怕有的同学想太多,且本身副本集就偏向运维的,新手基本也没什么权限操作,就不多废话了。 文章概叙 文章从MongoDB是否可以用偶数…

Hi3516DV500 SVP_NNN添加opencv库记录

默认没有带opencv库,但是实际项目中需要用到opencv库,因此添加一下此库; 1:编译opencv源码,这里具体可以参考 海思Hi3516移植opencv以及错误调试_海思hi3516摄像头开发-CSDN博客 2:在工程的根目录下新建…

地下城堡3魂之诗阵容搭配攻略

在地下城堡3魂之诗游戏中,拥有一个合理搭配的阵容非常关键,可以让角色能力发挥最大化。以下是建议的阵容搭配及攻略: 关注【娱乐天梯】,获取内部福利号 1.核心成员(2名) 在阵容中选择两个输出型角色作为核心成员,他们的…

SettingsView/设置页 的实现

1. 创建设置视图 SettingsView.swift import SwiftUI/// 设置页面 struct SettingsView: View {/// 环境变量,呈现方式:显示或者关闭Environment(\.presentationMode) var presentationMode/// 默认网址let defaultURL URL(string: "https://www.…

v-model绑定input、textarea、checkbox、radio、select

1.input <div><!-- v-model绑定input --><input type"text" v-model"message"><h2>{{message}}</h2></div><script>const App{template:#my-app,data() {return {message:Hello World,}},}Vue.createApp(App).…

扁圆头带榫螺栓

声明 本文是学习GB-T 15-2013 扁圆头带榫螺栓. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了螺纹规格为M6&#xff5e;M24、 产品等级为C 级的扁圆头带榫螺栓。 2 规范性引用文件 下列文件对于本文件的应用是必不可少的。凡是…

IP真人识别方法与代理IP检测技术

随着互联网的发展&#xff0c;IP地址在网络安全和数据分析中扮演着重要的角色。为了维护网络的安全性和识别真实用户&#xff0c;IP地址的真实性和来源成为了一个关键问题。 什么是IP真人识别&#xff1f; IP真人识别是一种技术&#xff0c;旨在确定IP地址背后的用户是否为真实…

【Node.js】路由

基础使用 写法一&#xff1a; // server.js const http require(http); const fs require(fs); const route require(./route) http.createServer(function (req, res) {const myURL new URL(req.url, http://127.0.0.1)route(res, myURL.pathname)res.end() }).listen…

Java内存空间(学习随笔)

1、程序运行中栈可能会出现两种错误 StackOverFlowError&#xff1a; 若栈的内存大小不允许动态扩展&#xff0c;那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候&#xff0c;就抛出 StackOverFlowError 错误。OutOfMemoryError&#xff1a; 如果栈的内存大小可…

Zookeeper-JavaApI操作

JavaApI操作 JavaApI操作1) Curator 介绍2) Curator API 常用操作a) 建立连接与CRUD基本操作b) Watch事件监听c) 分布式锁c.1) 介绍c.2) Zookeeper分布式锁原理c.3) 案例&#xff1a;模拟12306售票 JavaApI操作 1) Curator 介绍 Curator 是 Apache ZooKeeper 的Java客户端库。…