python神经网络InceptionV3模型复现详解

作者:Bubbliiiing 时间:2021-05-29 16:53:01 

学习前言

Inception系列的结构和其它的前向神经网络的结构不太一样,每一层的内容不是直直向下的,而是分了很多的块

什么是InceptionV3模型

InceptionV3模型是谷歌Inception系列里面的第三代模型,其模型结构与InceptionV2模型放在了同一篇论文里,其实二者模型结构差距不大,相比于其它神经网络模型,Inception网络最大的特

点在于将神经网络层与层之间的卷积运算进行了拓展。

如VGG,AlexNet网络,它就是一直卷积下来的,一层接着一层;

ResNet则是创新性的引入了残差网络的概念,使得靠前若干层的某一层数据输出直接跳过多层引入到后面数据层的输入部分,后面的特征层的内容会有一部分由其前面的某一层线性贡献。

而Inception网络则是采用不同大小的卷积核,使得存在不同大小的感受野,最后实现拼接达到不同尺度特征的融合。

对于InceptionV3而言,其网络中存在着如下的结构。

这个结构使用不同大小的卷积核对输入进行卷积(这个结构主要在代码中的block1使用)。

python神经网络InceptionV3模型复现详解

还存在着这样的结构,利用1x7的卷积和7x1的卷积代替7x7的卷积,这样可以只使用约(1x7 + 7x1) / (7x7) = 28.6%的计算开销;

利用1x3的卷积和3x1的卷积代替3x3的卷积,这样可以只使用约(1x3 + 3x1) / (3x3) = 67%的计算开销。

下图利用1x7的卷积和7x1的卷积代替7x7的卷积(这个结构主要在代码中的block2使用)。

python神经网络InceptionV3模型复现详解

下图利用1x3的卷积和3x1的卷积代替3x3的卷积(这个结构主要在代码中的block3使用)。

python神经网络InceptionV3模型复现详解

InceptionV3网络部分实现代码

我一共将InceptionV3划分为3个block,对应着35x35、17x17,8x8维度大小的图像。每个block中间有许多的part,对应着不同的特征层深度,用于特征提取。

#-------------------------------------------------------------#
#   InceptionV3的网络部分
#-------------------------------------------------------------#
from __future__ import print_function
from __future__ import absolute_import
import warnings
import numpy as np
from keras.models import Model
from keras import layers
from keras.layers import Activation,Dense,Input,BatchNormalization,Conv2D,MaxPooling2D,AveragePooling2D
from keras.layers import GlobalAveragePooling2D,GlobalMaxPooling2D
from keras.engine.topology import get_source_inputs
from keras.utils.layer_utils import convert_all_kernels_in_model
from keras.utils.data_utils import get_file
from keras import backend as K
from keras.applications.imagenet_utils import decode_predictions
from keras.preprocessing import image
def conv2d_bn(x,
             filters,
             num_row,
             num_col,
             padding='same',
             strides=(1, 1),
             name=None):
   if name is not None:
       bn_name = name + '_bn'
       conv_name = name + '_conv'
   else:
       bn_name = None
       conv_name = None
   x = Conv2D(
       filters, (num_row, num_col),
       strides=strides,
       padding=padding,
       use_bias=False,
       name=conv_name)(x)
   x = BatchNormalization(scale=False, name=bn_name)(x)
   x = Activation('relu', name=name)(x)
   return x
def InceptionV3(input_shape=[299,299,3],
               classes=1000):
   img_input = Input(shape=input_shape)
   x = conv2d_bn(img_input, 32, 3, 3, strides=(2, 2), padding='valid')
   x = conv2d_bn(x, 32, 3, 3, padding='valid')
   x = conv2d_bn(x, 64, 3, 3)
   x = MaxPooling2D((3, 3), strides=(2, 2))(x)
   x = conv2d_bn(x, 80, 1, 1, padding='valid')
   x = conv2d_bn(x, 192, 3, 3, padding='valid')
   x = MaxPooling2D((3, 3), strides=(2, 2))(x)
   #--------------------------------#
   #   Block1 35x35
   #--------------------------------#
   # Block1 part1
   # 35 x 35 x 192 -> 35 x 35 x 256
   branch1x1 = conv2d_bn(x, 64, 1, 1)
   branch5x5 = conv2d_bn(x, 48, 1, 1)
   branch5x5 = conv2d_bn(branch5x5, 64, 5, 5)
   branch3x3dbl = conv2d_bn(x, 64, 1, 1)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
   branch_pool = conv2d_bn(branch_pool, 32, 1, 1)
   x = layers.concatenate(
       [branch1x1, branch5x5, branch3x3dbl, branch_pool],
       axis=3,
       name='mixed0')
   # Block1 part2
   # 35 x 35 x 256 -> 35 x 35 x 288
   branch1x1 = conv2d_bn(x, 64, 1, 1)
   branch5x5 = conv2d_bn(x, 48, 1, 1)
   branch5x5 = conv2d_bn(branch5x5, 64, 5, 5)
   branch3x3dbl = conv2d_bn(x, 64, 1, 1)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
   branch_pool = conv2d_bn(branch_pool, 64, 1, 1)
   x = layers.concatenate(
       [branch1x1, branch5x5, branch3x3dbl, branch_pool],
       axis=3,
       name='mixed1')
   # Block1 part3
   # 35 x 35 x 288 -> 35 x 35 x 288
   branch1x1 = conv2d_bn(x, 64, 1, 1)
   branch5x5 = conv2d_bn(x, 48, 1, 1)
   branch5x5 = conv2d_bn(branch5x5, 64, 5, 5)
   branch3x3dbl = conv2d_bn(x, 64, 1, 1)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
   branch_pool = conv2d_bn(branch_pool, 64, 1, 1)
   x = layers.concatenate(
       [branch1x1, branch5x5, branch3x3dbl, branch_pool],
       axis=3,
       name='mixed2')
   #--------------------------------#
   #   Block2 17x17
   #--------------------------------#
   # Block2 part1
   # 35 x 35 x 288 -> 17 x 17 x 768
   branch3x3 = conv2d_bn(x, 384, 3, 3, strides=(2, 2), padding='valid')
   branch3x3dbl = conv2d_bn(x, 64, 1, 1)
   branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
   branch3x3dbl = conv2d_bn(
       branch3x3dbl, 96, 3, 3, strides=(2, 2), padding='valid')
   branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
   x = layers.concatenate(
       [branch3x3, branch3x3dbl, branch_pool], axis=3, name='mixed3')
   # Block2 part2
   # 17 x 17 x 768 -> 17 x 17 x 768
   branch1x1 = conv2d_bn(x, 192, 1, 1)
   branch7x7 = conv2d_bn(x, 128, 1, 1)
   branch7x7 = conv2d_bn(branch7x7, 128, 1, 7)
   branch7x7 = conv2d_bn(branch7x7, 192, 7, 1)
   branch7x7dbl = conv2d_bn(x, 128, 1, 1)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 1, 7)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
   branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
   branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
   x = layers.concatenate(
       [branch1x1, branch7x7, branch7x7dbl, branch_pool],
       axis=3,
       name='mixed4')
   # Block2 part3 and part4
   # 17 x 17 x 768 -> 17 x 17 x 768 -> 17 x 17 x 768
   for i in range(2):
       branch1x1 = conv2d_bn(x, 192, 1, 1)
       branch7x7 = conv2d_bn(x, 160, 1, 1)
       branch7x7 = conv2d_bn(branch7x7, 160, 1, 7)
       branch7x7 = conv2d_bn(branch7x7, 192, 7, 1)
       branch7x7dbl = conv2d_bn(x, 160, 1, 1)
       branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1)
       branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 1, 7)
       branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1)
       branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
       branch_pool = AveragePooling2D(
           (3, 3), strides=(1, 1), padding='same')(x)
       branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
       x = layers.concatenate(
           [branch1x1, branch7x7, branch7x7dbl, branch_pool],
           axis=3,
           name='mixed' + str(5 + i))
   # Block2 part5
   # 17 x 17 x 768 -> 17 x 17 x 768
   branch1x1 = conv2d_bn(x, 192, 1, 1)
   branch7x7 = conv2d_bn(x, 192, 1, 1)
   branch7x7 = conv2d_bn(branch7x7, 192, 1, 7)
   branch7x7 = conv2d_bn(branch7x7, 192, 7, 1)
   branch7x7dbl = conv2d_bn(x, 192, 1, 1)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1)
   branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
   branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
   branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
   x = layers.concatenate(
       [branch1x1, branch7x7, branch7x7dbl, branch_pool],
       axis=3,
       name='mixed7')
   #--------------------------------#
   #   Block3 8x8
   #--------------------------------#
   # Block3 part1
   # 17 x 17 x 768 -> 8 x 8 x 1280
   branch3x3 = conv2d_bn(x, 192, 1, 1)
   branch3x3 = conv2d_bn(branch3x3, 320, 3, 3,
                         strides=(2, 2), padding='valid')
   branch7x7x3 = conv2d_bn(x, 192, 1, 1)
   branch7x7x3 = conv2d_bn(branch7x7x3, 192, 1, 7)
   branch7x7x3 = conv2d_bn(branch7x7x3, 192, 7, 1)
   branch7x7x3 = conv2d_bn(
       branch7x7x3, 192, 3, 3, strides=(2, 2), padding='valid')
   branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
   x = layers.concatenate(
       [branch3x3, branch7x7x3, branch_pool], axis=3, name='mixed8')
   # Block3 part2 part3
   # 8 x 8 x 1280 -> 8 x 8 x 2048 -> 8 x 8 x 2048
   for i in range(2):
       branch1x1 = conv2d_bn(x, 320, 1, 1)
       branch3x3 = conv2d_bn(x, 384, 1, 1)
       branch3x3_1 = conv2d_bn(branch3x3, 384, 1, 3)
       branch3x3_2 = conv2d_bn(branch3x3, 384, 3, 1)
       branch3x3 = layers.concatenate(
           [branch3x3_1, branch3x3_2], axis=3, name='mixed9_' + str(i))
       branch3x3dbl = conv2d_bn(x, 448, 1, 1)
       branch3x3dbl = conv2d_bn(branch3x3dbl, 384, 3, 3)
       branch3x3dbl_1 = conv2d_bn(branch3x3dbl, 384, 1, 3)
       branch3x3dbl_2 = conv2d_bn(branch3x3dbl, 384, 3, 1)
       branch3x3dbl = layers.concatenate(
           [branch3x3dbl_1, branch3x3dbl_2], axis=3)
       branch_pool = AveragePooling2D(
           (3, 3), strides=(1, 1), padding='same')(x)
       branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
       x = layers.concatenate(
           [branch1x1, branch3x3, branch3x3dbl, branch_pool],
           axis=3,
           name='mixed' + str(9 + i))
   # 平均池化后全连接。
   x = GlobalAveragePooling2D(name='avg_pool')(x)
   x = Dense(classes, activation='softmax', name='predictions')(x)
   inputs = img_input
   model = Model(inputs, x, name='inception_v3')
   return model

图片预测

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

def preprocess_input(x):
   x /= 255.
   x -= 0.5
   x *= 2.
   return x
if __name__ == '__main__':
   model = InceptionV3()
   model.load_weights("inception_v3_weights_tf_dim_ordering_tf_kernels.h5")
   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)
   preds = model.predict(x)
   print('Predicted:', decode_predictions(preds))

预测所需的已经训练好的InceptionV3模型可以在github下载非常方便。

预测结果为:

Predicted: [[('n02504458', 'African_elephant', 0.50874853), ('n01871265', 'tusker', 0.19524273), ('n02504013', 'Indian_elephant', 0.1566972), ('n01917289', 'brain_coral', 0.0008956835), ('n01695060', 'Komodo_dragon', 0.0008260256)]]

这里我推荐一个很不错的讲InceptionV3结构的深度神经网络Google Inception Net-V3结构图里面有每一层的结构图,非常清晰。

来源:https://blog.csdn.net/weixin_44791964/article/details/102802866

标签:python,神经网络,InceptionV3,模型
0
投稿

猜你喜欢

  • Python实现批量翻译的示例代码

    2023-02-27 04:24:12
  • vue实现父子组件之间的通信以及兄弟组件的通信功能示例

    2024-05-21 10:15:43
  • True or False,明明白白你的If语句流程

    2008-01-25 19:00:00
  • Python使用CMD模块更优雅的运行脚本

    2022-05-16 03:53:50
  • 使用python实现个性化词云的方法

    2021-08-27 03:46:59
  • Python异步操作MySQL示例【使用aiomysql】

    2024-01-16 20:22:07
  • Python json读写方式和字典相互转化

    2021-03-25 05:28:19
  • Java连接MYSQL数据库的实现步骤

    2024-01-24 01:23:33
  • Python HTML解析模块HTMLParser用法分析【爬虫工具】

    2023-10-04 02:07:09
  • Python使用Plotly绘制常见5种动态交互式图表

    2023-06-08 06:27:59
  • [译]Javascript风格要素(一)

    2008-02-28 12:58:00
  • Mysql分区表的管理与维护

    2024-01-17 09:22:09
  • python 进程 进程池 进程间通信实现解析

    2022-07-05 07:38:28
  • python pip安装的包目录(site-packages目录的位置)

    2022-08-23 13:20:38
  • mysql 8.0.22 zip压缩包版(免安装)下载、安装配置步骤详解

    2024-01-15 21:19:16
  • oracle 常用的几个SQL

    2009-12-01 12:36:00
  • Django自定义过滤器定义与用法示例

    2022-07-24 13:09:00
  • Python+Socket实现基于TCP协议的客户与服务端中文自动回复聊天功能示例

    2023-07-18 20:11:01
  • python实现查找两个字符串中相同字符并输出的方法

    2023-09-01 04:03:42
  • Pycharm导入anaconda环境的教程图解

    2022-12-15 04:26:40
  • asp之家 网络编程 m.aspxhome.com