Xception:使用Tensorflow从头开始实现

news2024/11/13 16:09:07

一、说明

        近年来,卷积神经网络已成为计算机视觉领域的主要算法,开发设计它们的方法一直是相当的关注。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 libraries

import 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 block

def 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 block

def 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 flow

def 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 flow

def 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 flow

def 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 code

input = 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 graphviz

SVG(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 libraries

import 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 block

def 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 block

def 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 flow

def 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 flow

def 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 flow

def 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 code

input = 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.coloradmin.cn/o/1080549.html

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

相关文章

Linux 网络编程 tcp server 笔记

一、TCP 服务器的创建 在 Linux 上创建一个简单的 tcp 服务器步骤如下: ①创建套接字 ②将套接字绑定到 IP 地址和端口号 ③监听来自客户端的连接 ④接受连接并创建新的套接字用于与客户端通信 ⑤通过新建的套接字发送和接收数据 ⑥关闭套接字 流程框图如下&#xf…

AI 法律助手与原创奇幻小说生成 | 开源专题 No.33

eosphoros-ai/DB-GPT Stars: 6.4k License: MIT DB-GPT是一个实验性的开源项目,利用本地化的GPT大型模型与数据和环境进行交互,旨在提供私密性和安全性的数据处理解决方案。 主要功能: SQL语言能力SQL生成和诊断私有领域问答和数据处理知识管理&#x…

AIGC Excel办公应用实现行与列交叉多条件求和

这样的一个多条件求和函数的应用,我们可以使用ChatGPT,OpenAI,人工智能来实现。 Prompt提示词: 有一个表格A3至A186为部门,B3至B186为月份,D3至D186为费用,请根据G2单元格的月份与F3的部门汇总费用,写出Excel函数公式,并且加上绝对引用与相对引用,可以向右填充与向…

在北欧设计中,有种轻奢叫石膏线。福州中宅装饰,福州装修

很多人在追求精致的路上, 大都选择一个喜欢的城市, 小到睫毛也要刷出太阳花。 在家装中,我们也追求更精致的家居生活。 现如今石膏线的运用也很广泛 有一个不起眼的东西, 它对于家装的精致感提升, 起到了画龙点…

Echarts图例图标和文字居中

前言:设置了verticalAlign:"middle",lineHeight,效果没有生效,然后通过设置文本的padding,实现居中。 代码实现:

FPGA面试题(3)

一.FPGA和CPLD区别 FPGA:现场可编程门阵列CPLD:复杂可编程逻辑器件 二.多位异步信号如何同步 单比特异步信号 慢时钟域->快时钟域:同步打拍快时钟域->慢时钟域:先拓展位宽再同步打拍 多比特异步信号 1.异步FIFO2.保持…

vs code 添加vue3代码模板方法

最终效果 vs code 添加vue文件模板用于通过简写自动生成代码 操作步骤如下 1.找到vue模板代码编写入口 2.修改模板内容 2.1 vue.json内容 {// Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and// description. T…

生信学院|10月13日《SOLIDWORKS参数化应用——DriveWorksXpress》

课程主题:SOLIDWORKS参数化应用——DriveWorksXpress 课程时间:2023年10月13日 14:00-14:30 主讲人:温晓露 生信科技 售后服务工程师 1、DriveWorks的作用 2、用 DriveWorksXpress 自动化您的设计过程 3、Drive Works Xpress最佳做法 4…

Matlab地理信息绘图—研究区域绘制

文章目录 m_map工具箱Matlab绘制研究区域结果显示 m_map工具箱 m_map是 MATLAB 中用于制作地图和地理数据可视化的工具包。这个工具包提供了一组函数和工具,使得用户能够在 MATLAB 中轻松创建地图,并在地图上显示各种地理和气象数据。以下是 m_map 工具包…

nginx在windows下按照

Windows下Nginx的启动、停止等命令 可以进入到nginx的安装根目录,执行nginx.exe -h 在Windows下使用Nginx,我们需要掌握一些基本的操作命令,比如:启动、停止Nginx服务,重新载入Nginx等,下面我就进行一些简…

数仓面试题(1)

1.数据库的三范式是什么? 答: 第一范式(1NF) 强调的是列的原子性,即列不能够再分成其他几列。 第二范式(2NF) 第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列…

海豚调度器集群安装DolphinScheduler(3.1.8)

一、前置准备工作 JDK:下载JDK (1.8),安装并配置 JAVA_HOME 环境变量,并将其下的 bin 目录追加到 PATH 环境变量中。如果你的环境中已存在,可以跳过这步。海豚调度器二进制包:下载 DolphinScheduler(3.1.8) 二进制包数据库: MySQL (5.7)注册中心:ZooKeeper (3.9.0)进程树…

CPU性能分析--火焰图使用

记录工具使用说明,火焰图原理网上分析很多。主要用来分析函数调用栈占用的cpu利用率,分析函数性能。 perf安装: sudo apt-get install linux-tools-common sudo apt-get install linux-tools-"(uname -r)" sudo apt-get install …

【广州华锐互动】铝厂事故3D仿真还原让员工深刻认识事故严重性

铝厂作为高风险行业,安全问题一直备受关注。随着3D技术的不断发展,铝厂开始采用3D警示动画进行安全教育,取得了显著的成效。这种逼真的画面能够让员工深刻认识到事故的严重性和危害性,从而更加重视安全问题。 1.分析事故原因和后果…

用netty实现简易rpc

文章目录 rpc介绍:rpc调用流程:代码: rpc介绍: RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接…

群晖内安装的windows虚拟机如何扩展磁盘(虚拟机如何扩展磁盘,解决扩展磁盘不生效的问题)

文章目录 问题解决问题问题 在群晖的虚拟机中创建了一个Win7x64的虚拟机,由于配置低的原因,但是容量只设置了30G,但是现在要满了,所以现在要迁移和扩容 迁移很简单,直接选择迁移就行,扩容的话也就是选择扩容到指定的容量 (注意:这里容量扩大是不可逆的,扩大了不能再变…

银河麒麟安装arm架构mysql8

1. 准备工作 2. 查看麒麟系统版本 使用命令 Linux version 4.19.90-25.21.v2101.ky10.aarch64 (KYLINSOFTlocalhost.localdomain) (gcc version 7.3.0 (GCC)) #1 SMP Wed Sep 28 16:37:42 CST 2022可以看出这是麒麟 v10 ,aarch64 (ARM 架构的&#xff…

A股风格因子看板 (2023.10 第02期)

该因子看板跟踪A股风格因子,该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子,用以分析市场风格切换、组合风格暴露等。 今日为该因子跟踪第02期,指数组合数据截止日2023-09-30,要点如下 1) 近1年A股风格因子检…

聊一聊 Spring 6 面向切面AOP

Java全能学习面试指南:https://javaxiaobear.cn 今天我们一起看看Spring AOP的相关操作! 1、场景模拟 搭建子模块:spring6-aop 1.1、声明接口 声明计算器接口Calculator,包含加减乘除的抽象方法 public interface Calculator…

tailwindcss安装完插件代码不提示

安装完插件鼠标滑过tailwindcss类名claa不提示 vscode版本太低.需要安装最新的vscode插件扩展设置中的Tailwind CSS :Emmet Completions默认是未勾选的,需要手动勾选