python神经网络Inception ResnetV2模型复现详解
作者:Bubbliiiing 发布时间:2023-02-28 08:51:35
什么是Inception ResnetV2
Inception ResnetV2是Inception ResnetV1的一个加强版,两者的结构差距不大,如果大家想了解Inception ResnetV1可以看一下我的另一个blog。facenet的神经网络结构就是Inception ResnetV1。
神经网络学习——facenet详解及其keras实现
源码下载
Inception-ResNetV2的网络结构
Inception-ResNetV2和Inception-ResNetV1采用同一个主干网络。
它的结构很有意思!
如图所示为整个网络的主干结构:
可以看到里面的结构分为几个重要的部分
1、stem
2、Inception-resnet-A
3、Inception-resnet-B
4、Inception-resnet-C
1、Stem的结构:
在Inception-ResNetV2里,它的Input为299x299x3大小,输入后进行:三次卷积 -> 最大池化 -> 两次卷积 -> 最大池化 -> 四个分支 -> 堆叠python实现代码如下:
input_shape = [299,299,3]
img_input = Input(shape=input_shape)
# Stem block: 299,299,3 -> 35 x 35 x 192
x = conv2d_bn(img_input, 32, 3, strides=2, padding='valid')
x = conv2d_bn(x, 32, 3, padding='valid')
x = conv2d_bn(x, 64, 3)
x = MaxPooling2D(3, strides=2)(x)
x = conv2d_bn(x, 80, 1, padding='valid')
x = conv2d_bn(x, 192, 3, padding='valid')
x = MaxPooling2D(3, strides=2)(x)
# Mixed 5b (Inception-A block):35 x 35 x 192 -> 35 x 35 x 320
branch_0 = conv2d_bn(x, 96, 1)
branch_1 = conv2d_bn(x, 48, 1)
branch_1 = conv2d_bn(branch_1, 64, 5)
branch_2 = conv2d_bn(x, 64, 1)
branch_2 = conv2d_bn(branch_2, 96, 3)
branch_2 = conv2d_bn(branch_2, 96, 3)
branch_pool = AveragePooling2D(3, strides=1, padding='same')(x)
branch_pool = conv2d_bn(branch_pool, 64, 1)
branches = [branch_0, branch_1, branch_2, branch_pool]
x = Concatenate(name='mixed_5b')(branches)
2、Inception-resnet-A的结构:
Inception-resnet-A的结构分为四个分支
1、未经处理直接输出
2、经过一次1x1的32通道的卷积处理
3、经过一次1x1的32通道的卷积处理和一次3x3的32通道的卷积处理
4、经过一次1x1的32通道的卷积处理、一次3x3的48通道和一次3x3的64通道卷积处理
234步的结果堆叠后进行一次卷积,并与第一步的结果相加,实质上这是一个残差网络结构。
实现代码如下:
branch_0 = conv2d_bn(x, 32, 1)
branch_1 = conv2d_bn(x, 32, 1)
branch_1 = conv2d_bn(branch_1, 32, 3)
branch_2 = conv2d_bn(x, 32, 1)
branch_2 = conv2d_bn(branch_2, 48, 3)
branch_2 = conv2d_bn(branch_2, 64, 3)
branches = [branch_0, branch_1, branch_2]
block_name = block_type + '_' + str(block_idx)
mixed = Concatenate(name=block_name + '_mixed')(branches)
up = conv2d_bn(mixed,K.int_shape(x)[3],1,activation=None,se_bias=True,name=block_name + '_conv')
x = Lambda(lambda inputs, scale: inputs[0] + inputs[1] * scale,
output_shape=K.int_shape(x)[1:],
arguments={'scale': scale},
name=block_name)([x, up])
if activation is not None:
x = Activation(activation, name=block_name + '_ac')(x)
3、Inception-resnet-B的结构:
Inception-resnet-B的结构分为四个分支
1、未经处理直接输出
2、经过一次1x1的192通道的卷积处理
3、经过一次1x1的128通道的卷积处理、一次1x7的160通道的卷积处理和一次7x1的192通道的卷积处理
23步的结果堆叠后进行一次卷积,并与第一步的结果相加,实质上这是一个残差网络结构。
实现代码如下:
branch_0 = conv2d_bn(x, 192, 1)
branch_1 = conv2d_bn(x, 128, 1)
branch_1 = conv2d_bn(branch_1, 160, [1, 7])
branch_1 = conv2d_bn(branch_1, 192, [7, 1])
branches = [branch_0, branch_1]
block_name = block_type + '_' + str(block_idx)
mixed = Concatenate(name=block_name + '_mixed')(branches)
up = conv2d_bn(mixed,K.int_shape(x)[3],1,activation=None,se_bias=True,name=block_name + '_conv')
x = Lambda(lambda inputs, scale: inputs[0] + inputs[1] * scale,
output_shape=K.int_shape(x)[1:],
arguments={'scale': scale},
name=block_name)([x, up])
if activation is not None:
x = Activation(activation, name=block_name + '_ac')(x)
4、Inception-resnet-C的结构:
Inception-resnet-B的结构分为四个分支
1、未经处理直接输出
2、经过一次1x1的192通道的卷积处理
3、经过一次1x1的192通道的卷积处理、一次1x3的224通道的卷积处理和一次3x1的256通道的卷积处理
23步的结果堆叠后进行一次卷积,并与第一步的结果相加,实质上这是一个残差网络结构。
实现代码如下:
branch_0 = conv2d_bn(x, 192, 1)
branch_1 = conv2d_bn(x, 192, 1)
branch_1 = conv2d_bn(branch_1, 224, [1, 3])
branch_1 = conv2d_bn(branch_1, 256, [3, 1])
branches = [branch_0, branch_1]
block_name = block_type + '_' + str(block_idx)
mixed = Concatenate(name=block_name + '_mixed')(branches)
up = conv2d_bn(mixed,K.int_shape(x)[3],1,activation=None,se_bias=True,name=block_name + '_conv')
x = Lambda(lambda inputs, scale: inputs[0] + inputs[1] * scale,
output_shape=K.int_shape(x)[1:],
arguments={'scale': scale},
name=block_name)([x, up])
if activation is not None:
x = Activation(activation, name=block_name + '_ac')(x)
全部代码
import warnings
import numpy as np
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Activation,AveragePooling2D,BatchNormalization,Concatenate
from keras.layers import Conv2D,Dense,GlobalAveragePooling2D,GlobalMaxPooling2D,Input,Lambda,MaxPooling2D
from keras.applications.imagenet_utils import decode_predictions
from keras.utils.data_utils import get_file
from keras import backend as K
BASE_WEIGHT_URL = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.7/'
def conv2d_bn(x,filters,kernel_size,strides=1,padding='same',activation='relu',use_bias=False,name=None):
x = Conv2D(filters,
kernel_size,
strides=strides,
padding=padding,
use_bias=use_bias,
name=name)(x)
if not use_bias:
bn_axis = 1 if K.image_data_format() == 'channels_first' else 3
bn_name = None if name is None else name + '_bn'
x = BatchNormalization(axis=bn_axis, scale=False, name=bn_name)(x)
if activation is not None:
ac_name = None if name is None else name + '_ac'
x = Activation(activation, name=ac_name)(x)
return x
def inception_resnet_block(x, scale, block_type, block_idx, activation='relu'):
if block_type == 'block35':
branch_0 = conv2d_bn(x, 32, 1)
branch_1 = conv2d_bn(x, 32, 1)
branch_1 = conv2d_bn(branch_1, 32, 3)
branch_2 = conv2d_bn(x, 32, 1)
branch_2 = conv2d_bn(branch_2, 48, 3)
branch_2 = conv2d_bn(branch_2, 64, 3)
branches = [branch_0, branch_1, branch_2]
elif block_type == 'block17':
branch_0 = conv2d_bn(x, 192, 1)
branch_1 = conv2d_bn(x, 128, 1)
branch_1 = conv2d_bn(branch_1, 160, [1, 7])
branch_1 = conv2d_bn(branch_1, 192, [7, 1])
branches = [branch_0, branch_1]
elif block_type == 'block8':
branch_0 = conv2d_bn(x, 192, 1)
branch_1 = conv2d_bn(x, 192, 1)
branch_1 = conv2d_bn(branch_1, 224, [1, 3])
branch_1 = conv2d_bn(branch_1, 256, [3, 1])
branches = [branch_0, branch_1]
else:
raise ValueError('Unknown Inception-ResNet block type. '
'Expects "block35", "block17" or "block8", '
'but got: ' + str(block_type))
block_name = block_type + '_' + str(block_idx)
mixed = Concatenate(name=block_name + '_mixed')(branches)
up = conv2d_bn(mixed,K.int_shape(x)[3],1,activation=None,use_bias=True,name=block_name + '_conv')
x = Lambda(lambda inputs, scale: inputs[0] + inputs[1] * scale,
output_shape=K.int_shape(x)[1:],
arguments={'scale': scale},
name=block_name)([x, up])
if activation is not None:
x = Activation(activation, name=block_name + '_ac')(x)
return x
def InceptionResNetV2(input_shape=[299,299,3],
classes=1000):
input_shape = [299,299,3]
img_input = Input(shape=input_shape)
# Stem block: 299,299,3 -> 35 x 35 x 192
x = conv2d_bn(img_input, 32, 3, strides=2, padding='valid')
x = conv2d_bn(x, 32, 3, padding='valid')
x = conv2d_bn(x, 64, 3)
x = MaxPooling2D(3, strides=2)(x)
x = conv2d_bn(x, 80, 1, padding='valid')
x = conv2d_bn(x, 192, 3, padding='valid')
x = MaxPooling2D(3, strides=2)(x)
# Mixed 5b (Inception-A block):35 x 35 x 192 -> 35 x 35 x 320
branch_0 = conv2d_bn(x, 96, 1)
branch_1 = conv2d_bn(x, 48, 1)
branch_1 = conv2d_bn(branch_1, 64, 5)
branch_2 = conv2d_bn(x, 64, 1)
branch_2 = conv2d_bn(branch_2, 96, 3)
branch_2 = conv2d_bn(branch_2, 96, 3)
branch_pool = AveragePooling2D(3, strides=1, padding='same')(x)
branch_pool = conv2d_bn(branch_pool, 64, 1)
branches = [branch_0, branch_1, branch_2, branch_pool]
x = Concatenate(name='mixed_5b')(branches)
# 10次Inception-ResNet-A block:35 x 35 x 320 -> 35 x 35 x 320
for block_idx in range(1, 11):
x = inception_resnet_block(x,
scale=0.17,
block_type='block35',
block_idx=block_idx)
# Reduction-A block:35 x 35 x 320 -> 17 x 17 x 1088
branch_0 = conv2d_bn(x, 384, 3, strides=2, padding='valid')
branch_1 = conv2d_bn(x, 256, 1)
branch_1 = conv2d_bn(branch_1, 256, 3)
branch_1 = conv2d_bn(branch_1, 384, 3, strides=2, padding='valid')
branch_pool = MaxPooling2D(3, strides=2, padding='valid')(x)
branches = [branch_0, branch_1, branch_pool]
x = Concatenate(name='mixed_6a')(branches)
# 20次Inception-ResNet-B block: 17 x 17 x 1088 -> 17 x 17 x 1088
for block_idx in range(1, 21):
x = inception_resnet_block(x,
scale=0.1,
block_type='block17',
block_idx=block_idx)
# Reduction-B block: 17 x 17 x 1088 -> 8 x 8 x 2080
branch_0 = conv2d_bn(x, 256, 1)
branch_0 = conv2d_bn(branch_0, 384, 3, strides=2, padding='valid')
branch_1 = conv2d_bn(x, 256, 1)
branch_1 = conv2d_bn(branch_1, 288, 3, strides=2, padding='valid')
branch_2 = conv2d_bn(x, 256, 1)
branch_2 = conv2d_bn(branch_2, 288, 3)
branch_2 = conv2d_bn(branch_2, 320, 3, strides=2, padding='valid')
branch_pool = MaxPooling2D(3, strides=2, padding='valid')(x)
branches = [branch_0, branch_1, branch_2, branch_pool]
x = Concatenate(name='mixed_7a')(branches)
# 10次Inception-ResNet-C block: 8 x 8 x 2080 -> 8 x 8 x 2080
for block_idx in range(1, 10):
x = inception_resnet_block(x,
scale=0.2,
block_type='block8',
block_idx=block_idx)
x = inception_resnet_block(x,
scale=1.,
activation=None,
block_type='block8',
block_idx=10)
# 8 x 8 x 2080 -> 8 x 8 x 1536
x = conv2d_bn(x, 1536, 1, name='conv_7b')
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dense(classes, activation='softmax', name='predictions')(x)
inputs = img_input
# 创建模型
model = Model(inputs, x, name='inception_resnet_v2')
return model
def preprocess_input(x):
x /= 255.
x -= 0.5
x *= 2.
return x
if __name__ == '__main__':
model = InceptionResNetV2()
fname = 'inception_resnet_v2_weights_tf_dim_ordering_tf_kernels.h5'
weights_path = get_file(fname,BASE_WEIGHT_URL + fname,cache_subdir='models',file_hash='e693bd0210a403b3192acc6073ad2e96')
model.load_weights(fname)
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))
来源:https://blog.csdn.net/weixin_44791964/article/details/103732720
猜你喜欢
- Python numpy和scipy中没有直接插0的函数和方法,这里使用numpy.insert来实现。1,numpy.inser
- 一、前言春节即将来临,大家肯定各种掏腰包花花花,小编相信大家在支付时候,微信、支付宝支付肯定是优先选择。今天小编心血来潮,为大家带来一个很有
- 本文实例为大家分享了Python KNN分类算法的具体代码,供大家参考,具体内容如下KNN分类算法应该算得上是机器学习中最简单的分类算法了,
- 显示大图和隐藏大图的js代码:<script type="text/javascript"> &n
- 本文实例讲述了PHP与Web页面交互操作。分享给大家供大家参考,具体如下:Web交互1.Web表单交互当表单的method属性提交方式为PO
- 我的电脑本来是有手动CMake+make安装的OpenCV3的,以及系统自带的python2.x,但是现在想用python3+OpenCV3
- 函数式编程是使用一系列函数去解决问题,按照一般编程思维,面对问题时我们的思考方式是“怎么干”,而函数函数式编程的思考方式是我要“干什么”。
- 本文介绍了多个 Python IDE,并评价其优缺点。读者可以参考此文列举的 Python IDE 列表,选择适合自己的编辑器。写 Pyth
- 目录1. threding模块创建线程对象2. threding模块创建多线程3. 多线程的参数传递4. 线程产生的资源竞争1. thred
- 调试程序的过程中,发现通过os.path.join拼接的路径出现了反斜杠directory1='/opt/apps/upgradeP
- 你甚至可以在一行内将多个值赋值给多个变量>>> a , b = 45, 54>>> a45>>
- “位置:首页 第一屏通栏 格式:jpg 尺寸:960*90 ……”在工作我们经常会接到这样的banner设计需求,由
- 一个网站程序,在添加新闻时出现错误以下是错误提示: Microsoft OLE DB Provide
- 本文实例讲述了python连接、操作mongodb数据库的方法。分享给大家供大家参考,具体如下:数据库连接 from pymongo imp
- 前言:NumPy 是 Python 语言的一个扩充程序库,支持大量高维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。同时NumP
- 本文实例讲述了Python lxml模块的基本使用方法。分享给大家供大家参考,具体如下:1 lxml的安装安装方式:pip install
- 如何使用Pytorch实现two-head(多输出)模型1. two-head模型定义先放一张我要实现的模型结构图:如上图,就是一个two-
- 今天照着样例搞了下tensorboard,发现自己无法显示scalar,而graph却可以正常显示。出现这种情况就说明,tensorfboa
- 本文实例讲述了Python面向对象封装操作。分享给大家供大家参考,具体如下:目标士兵突击案例身份运算符封装封装 是面向对象编程的一大特点面向
- 以下是一些python的list和set的基本操作1. list的一些操作list = [1, 2, 3]list.append(5)pri