python神经网络Xception模型


Posted in Python onMay 06, 2022

Xception是继Inception后提出的对Inception v3的另一种改进,学一学总是好的

什么是Xception模型

Xception是谷歌公司继Inception后,提出的InceptionV3的一种改进模型,其改进的主要内容为采用depthwise separable convolution来替换原来Inception v3中的多尺寸卷积核特征响应操作。

在讲Xception模型之前,首先要讲一下什么是depthwise separable convolution(深度可分离卷积块)。

深度可分离卷积块由两个部分组成,分别是深度可分离卷积和1x1普通卷积,深度可分离卷积的卷积核大小一般是3x3的,便于理解的话我们可以把它当作是特征提取,1x1的普通卷积可以完成通道数的调整。

下图为深度可分离卷积块的结构示意图:

python神经网络Xception模型


深度可分离卷积块的目的是使用更少的参数来代替普通的3x3卷积。

我们可以进行一下普通卷积和深度可分离卷积块的对比:

假设有一个3×3大小的卷积层,其输入通道为16、输出通道为32。具体为,32个3×3大小的卷积核会遍历16个通道中的每个数据,最后可得到所需的32个输出通道,所需参数为16×32×3×3=4608个。

应用深度可分离卷积,用16个3×3大小的卷积核分别遍历16通道的数据,得到了16个特征图谱。在融合操作之前,接着用32个1×1大小的卷积核遍历这16个特征图谱,所需参数为16×3×3+16×32×1×1=656个。

可以看出来depthwise separable convolution可以减少模型的参数。

通俗地理解深度可分离卷积结构块,就是3x3的卷积核厚度只有一层,然后在输入张量上一层一层地滑动,每一次卷积完生成一个输出通道,当卷积完成后,再利用1x1的卷积调整厚度。

(视频中有些许错误,感谢zl960929的提醒,Xception使用的深度可分离卷积块SeparableConv2D也就是先深度可分离卷积再进行1x1卷积。)

对于Xception模型而言,其一共可以分为3个flow,分别是Entry flow、Middle flow、Exit flow;分为14个block,其中Entry flow中有4个、Middle flow中有8个、Exit flow中有2个。具体结构如下:

python神经网络Xception模型


其内部主要结构就是残差卷积网络搭配SeparableConv2D层实现一个个block,在Xception模型中,常见的两个block的结构如下。
这个主要在Entry flow和Exit flow中:

python神经网络Xception模型


这个主要在Middle flow中:

python神经网络Xception模型

Xception网络部分实现代码

#-------------------------------------------------------------#
#   Xception的网络部分
#-------------------------------------------------------------#
from keras.preprocessing import image

from keras.models import Model
from keras import layers
from keras.layers import Dense,Input,BatchNormalization,Activation,Conv2D,SeparableConv2D,MaxPooling2D
from keras.layers import GlobalAveragePooling2D,GlobalMaxPooling2D
from keras import backend as K
from keras.applications.imagenet_utils import decode_predictions


def Xception(input_shape = [299,299,3],classes=1000):


    img_input = Input(shape=input_shape)

    #--------------------------#
    # Entry flow
    #--------------------------#
    #--------------------#
    # block1
    #--------------------#
    # 299,299,3 -> 149,149,64
    x = Conv2D(32, (3, 3), strides=(2, 2), use_bias=False, name='block1_conv1')(img_input)
    x = BatchNormalization(name='block1_conv1_bn')(x)
    x = Activation('relu', name='block1_conv1_act')(x)
    x = Conv2D(64, (3, 3), use_bias=False, name='block1_conv2')(x)
    x = BatchNormalization(name='block1_conv2_bn')(x)
    x = Activation('relu', name='block1_conv2_act')(x)

    #--------------------#
    # block2
    #--------------------#
    # 149,149,64 -> 75,75,128
    residual = Conv2D(128, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    x = SeparableConv2D(128, (3, 3), padding='same', use_bias=False, name='block2_sepconv1')(x)
    x = BatchNormalization(name='block2_sepconv1_bn')(x)
    x = Activation('relu', name='block2_sepconv2_act')(x)
    x = SeparableConv2D(128, (3, 3), padding='same', use_bias=False, name='block2_sepconv2')(x)
    x = BatchNormalization(name='block2_sepconv2_bn')(x)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same', name='block2_pool')(x)
    x = layers.add([x, residual])

    #--------------------#
    # block3
    #--------------------#
    # 75,75,128 -> 38,38,256
    residual = Conv2D(256, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    x = Activation('relu', name='block3_sepconv1_act')(x)
    x = SeparableConv2D(256, (3, 3), padding='same', use_bias=False, name='block3_sepconv1')(x)
    x = BatchNormalization(name='block3_sepconv1_bn')(x)
    x = Activation('relu', name='block3_sepconv2_act')(x)
    x = SeparableConv2D(256, (3, 3), padding='same', use_bias=False, name='block3_sepconv2')(x)
    x = BatchNormalization(name='block3_sepconv2_bn')(x)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same', name='block3_pool')(x)
    x = layers.add([x, residual])

    #--------------------#
    # block4
    #--------------------#
    # 38,38,256 -> 19,19,728
    residual = Conv2D(728, (1, 1), strides=(2, 2),padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    x = Activation('relu', name='block4_sepconv1_act')(x)
    x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name='block4_sepconv1')(x)
    x = BatchNormalization(name='block4_sepconv1_bn')(x)
    x = Activation('relu', name='block4_sepconv2_act')(x)
    x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name='block4_sepconv2')(x)
    x = BatchNormalization(name='block4_sepconv2_bn')(x)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same', name='block4_pool')(x)
    x = layers.add([x, residual])

    #--------------------------#
    # Middle flow
    #--------------------------#
    #--------------------#
    # block5--block12
    #--------------------#
    # 19,19,728 -> 19,19,728
    for i in range(8):
        residual = x
        prefix = 'block' + str(i + 5)

        x = Activation('relu', name=prefix + '_sepconv1_act')(x)
        x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv1')(x)
        x = BatchNormalization(name=prefix + '_sepconv1_bn')(x)
        x = Activation('relu', name=prefix + '_sepconv2_act')(x)
        x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv2')(x)
        x = BatchNormalization(name=prefix + '_sepconv2_bn')(x)
        x = Activation('relu', name=prefix + '_sepconv3_act')(x)
        x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv3')(x)
        x = BatchNormalization(name=prefix + '_sepconv3_bn')(x)

        x = layers.add([x, residual])

    #--------------------------#
    # Exit flow
    #--------------------------#
    #--------------------#
    # block13
    #--------------------#
    # 19,19,728 -> 10,10,1024
    residual = Conv2D(1024, (1, 1), strides=(2, 2),
                      padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    x = Activation('relu', name='block13_sepconv1_act')(x)
    x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name='block13_sepconv1')(x)
    x = BatchNormalization(name='block13_sepconv1_bn')(x)
    x = Activation('relu', name='block13_sepconv2_act')(x)
    x = SeparableConv2D(1024, (3, 3), padding='same', use_bias=False, name='block13_sepconv2')(x)
    x = BatchNormalization(name='block13_sepconv2_bn')(x)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same', name='block13_pool')(x)
    x = layers.add([x, residual])

    #--------------------#
    # block14
    #--------------------#
    # 10,10,1024 -> 10,10,2048
    x = SeparableConv2D(1536, (3, 3), padding='same', use_bias=False, name='block14_sepconv1')(x)
    x = BatchNormalization(name='block14_sepconv1_bn')(x)
    x = Activation('relu', name='block14_sepconv1_act')(x)

    x = SeparableConv2D(2048, (3, 3), padding='same', use_bias=False, name='block14_sepconv2')(x)
    x = BatchNormalization(name='block14_sepconv2_bn')(x)
    x = Activation('relu', name='block14_sepconv2_act')(x)

    x = GlobalAveragePooling2D(name='avg_pool')(x)
    x = Dense(classes, activation='softmax', name='predictions')(x)

    inputs = img_input

    model = Model(inputs, x, name='xception')

    model.load_weights("xception_weights_tf_dim_ordering_tf_kernels.h5")

    return model

图片预测

建立网络后,可以用以下的代码进行预测。

def preprocess_input(x):
    x /= 255.
    x -= 0.5
    x *= 2.
    return x


if __name__ == '__main__':
    model = Xception()

    img_path = 'elephant.jpg'
    img = image.load_img(img_path, target_size=(299, 299))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    print('Input image shape:', x.shape)

    preds = model.predict(x)
    print(np.argmax(preds))
    print('Predicted:', decode_predictions(preds))

预测所需的已经训练好的Xception模型可以在https://github.com/fchollet/deep-learning-models/releases下载。非常方便。

预测结果为:

Predicted: [[('n02504458', 'African_elephant', 0.47570863), ('n01871265', 'tusker', 0.3173351), ('n02504013', 'Indian_elephant', 0.030323735), ('n02963159', 'cardigan', 0.0007877756), ('n02410509', 'bison', 0.00075616257)]]

以上就是python神经网络Xception模型详解的详细内容,更多关于Xception模型的复现详解的资料请关注三水点靠木其它相关文章!


Tags in this post...

Python 相关文章推荐
python实现数通设备tftp备份配置文件示例
Apr 02 Python
django自定义Field实现一个字段存储以逗号分隔的字符串
Apr 27 Python
浅析Python中的序列化存储的方法
Apr 28 Python
实例解析Python设计模式编程之桥接模式的运用
Mar 02 Python
Python语言描述机器学习之Logistic回归算法
Dec 21 Python
Python3多线程基础知识点
Feb 19 Python
Django REST framework 视图和路由详解
Jul 19 Python
python+pygame实现坦克大战
Sep 10 Python
Python操作Mongodb数据库的方法小结
Sep 10 Python
django框架中ajax的使用及避开CSRF 验证的方式详解
Dec 11 Python
django框架两个使用模板实例
Dec 11 Python
用python开发一款操作MySQL的小工具
May 12 Python
Python使用永中文档转换服务
May 06 #Python
Python tensorflow卷积神经Inception V3网络结构
May 06 #Python
Python实现Matplotlib,Seaborn动态数据图
May 06 #Python
PYTHON InceptionV3模型的复现详解
代码复现python目标检测yolo3详解预测
讲解Python实例练习逆序输出字符串
May 06 #Python
python turtle绘图
May 04 #Python
You might like
有关PHP中MVC的开发经验分享
2012/05/17 PHP
破解.net程序(dll文件)编译和反编译方法
2013/01/31 PHP
关于尾递归的使用详解
2013/05/02 PHP
利用PHP访问带有密码的Redis方法示例
2017/02/09 PHP
jQuery LigerUI 使用教程入门篇
2012/01/18 Javascript
javascript自动改变文字大小和颜色的效果的小例子
2013/08/02 Javascript
JavaScript Ajax Json实现上下级下拉框联动效果实例代码
2013/11/23 Javascript
javascript 事件处理示例分享
2014/12/31 Javascript
jQuery解析XML文件同时动态增加js文件的方法
2015/06/01 Javascript
jQuery实现列表内容的动态载入特效
2015/08/08 Javascript
js实现点击切换TAB标签实例
2015/08/21 Javascript
jQuery实现输入框下拉列表树插件特效代码分享
2015/08/27 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
JS简单实现点击复制链接的方法
2016/08/03 Javascript
JavaScript基于Dom操作实现查找、修改HTML元素的内容及属性的方法
2017/01/20 Javascript
BootStrap表单验证 FormValidation 调整反馈图标位置的实例代码
2017/05/17 Javascript
jQuery实现点击DIV同时点击CheckBox,并为DIV上背景色的实例
2017/12/18 jQuery
(模仿京东用户注册)用JQuery实现简单表单验证,初学者必看
2018/01/08 jQuery
详解vue添加删除元素的方法
2018/06/30 Javascript
利用JS实现一个同Excel表现的智能填充算法
2018/08/13 Javascript
对vue v-if v-else-if v-else 的简单使用详解
2018/09/29 Javascript
js继承的这6种方式!(上)
2019/04/23 Javascript
[01:06:59]完美世界DOTA2联赛PWL S2 Magma vs FTD 第一场 11.29
2020/12/02 DOTA
Python操作MySQL数据库9个实用实例
2015/12/11 Python
Python制作词云的方法
2018/01/03 Python
python读取和保存视频文件
2018/04/16 Python
使用Keras建立模型并训练等一系列操作方式
2020/07/02 Python
Django --Xadmin 判断登录者身份实例
2020/07/03 Python
瑞士香水购物网站:Parfumcity.ch
2017/01/14 全球购物
女性时尚在线:IVRose
2019/02/23 全球购物
2013年入党人员的自我鉴定
2013/10/25 职场文书
法制宣传标语集锦
2014/06/25 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
导游词之青岛太清宫
2019/12/13 职场文书
Golang全局变量加锁的问题解决
2021/05/08 Golang
Python使用OpenCV实现虚拟缩放效果
2022/02/28 Python