python神經(jīng)網(wǎng)絡(luò)Inception?ResnetV2模型復(fù)現(xiàn)詳解
什么是Inception ResnetV2
Inception ResnetV2是Inception ResnetV1的一個(gè)加強(qiáng)版,兩者的結(jié)構(gòu)差距不大,如果大家想了解Inception ResnetV1可以看一下我的另一個(gè)blog。facenet的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)就是Inception ResnetV1。
神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)——facenet詳解及其keras實(shí)現(xiàn)
Inception-ResNetV2的網(wǎng)絡(luò)結(jié)構(gòu)
Inception-ResNetV2和Inception-ResNetV1采用同一個(gè)主干網(wǎng)絡(luò)。
它的結(jié)構(gòu)很有意思!
如圖所示為整個(gè)網(wǎng)絡(luò)的主干結(jié)構(gòu):
可以看到里面的結(jié)構(gòu)分為幾個(gè)重要的部分
1、stem
2、Inception-resnet-A
3、Inception-resnet-B
4、Inception-resnet-C
1、Stem的結(jié)構(gòu):
在Inception-ResNetV2里,它的Input為299x299x3大小,輸入后進(jìn)行:三次卷積 -> 最大池化 -> 兩次卷積 -> 最大池化 -> 四個(gè)分支 -> 堆疊python實(shí)現(xiàn)代碼如下:
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的結(jié)構(gòu):
Inception-resnet-A的結(jié)構(gòu)分為四個(gè)分支
1、未經(jīng)處理直接輸出
2、經(jīng)過(guò)一次1x1的32通道的卷積處理
3、經(jīng)過(guò)一次1x1的32通道的卷積處理和一次3x3的32通道的卷積處理
4、經(jīng)過(guò)一次1x1的32通道的卷積處理、一次3x3的48通道和一次3x3的64通道卷積處理
234步的結(jié)果堆疊后進(jìn)行一次卷積,并與第一步的結(jié)果相加,實(shí)質(zhì)上這是一個(gè)殘差網(wǎng)絡(luò)結(jié)構(gòu)。
實(shí)現(xiàn)代碼如下:
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的結(jié)構(gòu):
Inception-resnet-B的結(jié)構(gòu)分為四個(gè)分支
1、未經(jīng)處理直接輸出
2、經(jīng)過(guò)一次1x1的192通道的卷積處理
3、經(jīng)過(guò)一次1x1的128通道的卷積處理、一次1x7的160通道的卷積處理和一次7x1的192通道的卷積處理
23步的結(jié)果堆疊后進(jìn)行一次卷積,并與第一步的結(jié)果相加,實(shí)質(zhì)上這是一個(gè)殘差網(wǎng)絡(luò)結(jié)構(gòu)。
實(shí)現(xiàn)代碼如下:
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的結(jié)構(gòu):
Inception-resnet-B的結(jié)構(gòu)分為四個(gè)分支
1、未經(jīng)處理直接輸出
2、經(jīng)過(guò)一次1x1的192通道的卷積處理
3、經(jīng)過(guò)一次1x1的192通道的卷積處理、一次1x3的224通道的卷積處理和一次3x1的256通道的卷積處理
23步的結(jié)果堆疊后進(jìn)行一次卷積,并與第一步的結(jié)果相加,實(shí)質(zhì)上這是一個(gè)殘差網(wǎng)絡(luò)結(jié)構(gòu)。
實(shí)現(xiàn)代碼如下:
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 # 創(chuàng)建模型 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))
以上就是python神經(jīng)網(wǎng)絡(luò)Inception ResnetV2模型復(fù)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于Inception ResnetV2模型復(fù)現(xiàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Python機(jī)器學(xué)習(xí)利用鳶尾花數(shù)據(jù)繪制ROC和AUC曲線
- 利用Python畫ROC曲線和AUC值計(jì)算
- 一文詳解Python灰色預(yù)測(cè)模型實(shí)現(xiàn)示例
- python回歸分析邏輯斯蒂模型之多分類任務(wù)詳解
- python深度學(xué)習(xí)tensorflow訓(xùn)練好的模型進(jìn)行圖像分類
- Python實(shí)現(xiàn)自動(dòng)駕駛訓(xùn)練模型
- python神經(jīng)網(wǎng)絡(luò)Keras?GhostNet模型的實(shí)現(xiàn)
- python神經(jīng)網(wǎng)絡(luò)ShuffleNetV2模型復(fù)現(xiàn)詳解
- python神經(jīng)網(wǎng)絡(luò)Densenet模型復(fù)現(xiàn)詳解
- python神經(jīng)網(wǎng)絡(luò)MobileNetV3?small模型的復(fù)現(xiàn)詳解
- python神經(jīng)網(wǎng)絡(luò)MobileNetV3?large模型的復(fù)現(xiàn)詳解
- python模型性能ROC和AUC分析詳解
相關(guān)文章
Python3中zip()函數(shù)知識(shí)點(diǎn)小結(jié)
本文主要介紹了Python3中zip()函數(shù)知識(shí)點(diǎn)小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02python獲得文件創(chuàng)建時(shí)間和修改時(shí)間的方法
這篇文章主要介紹了python獲得文件創(chuàng)建時(shí)間和修改時(shí)間的方法,涉及Python針對(duì)文件屬性的相關(guān)操作技巧,需要的朋友可以參考下2015-06-06python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(六):Web客戶端訪問(wèn)
這篇文章主要介紹了python網(wǎng)絡(luò)編程之Web客戶端訪問(wèn) ,需要的朋友可以參考下2014-06-06Django接受前端數(shù)據(jù)的幾種方法總結(jié)
下面小編就為大家?guī)?lái)一篇Django接受前端數(shù)據(jù)的幾種方法總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11pytorch中permute()函數(shù)用法補(bǔ)充說(shuō)明(矩陣維度變化過(guò)程)
這篇文章主要給大家介紹了關(guān)于pytorch中permute()函數(shù)用法補(bǔ)充說(shuō)明的相關(guān)資料,本文詳細(xì)說(shuō)明了permute函數(shù)里維度變化的詳細(xì)過(guò)程,需要的朋友可以參考下2022-04-04python實(shí)現(xiàn)百度關(guān)鍵詞排名查詢
這篇文章主要介紹了python實(shí)現(xiàn)百度關(guān)鍵詞排名查詢,需要的朋友可以參考下2014-03-03使用matplotlib庫(kù)實(shí)現(xiàn)圖形局部數(shù)據(jù)放大顯示的實(shí)踐
本文主要介紹了使用matplotlib庫(kù)實(shí)現(xiàn)圖形局部數(shù)據(jù)放大顯示的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02