您现在的位置是:网站首页> 编程资料编程资料

python神经网络Inception ResnetV2模型复现详解_python_

2023-05-26 338人已围观

简介 python神经网络Inception ResnetV2模型复现详解_python_

什么是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
                
                

-六神源码网