python神經(jīng)網(wǎng)絡(luò)MobileNet模型的復(fù)現(xiàn)詳解
什么是MobileNet模型
MobileNet是一種輕量級網(wǎng)絡(luò),相比于其它結(jié)構(gòu)網(wǎng)絡(luò),它不一定是最準(zhǔn)的,但是它真的很輕
MobileNet模型是Google針對手機(jī)等嵌入式設(shè)備提出的一種輕量級的深層神經(jīng)網(wǎng)絡(luò),其使用的核心思想便是depthwise separable convolution。
對于一個(gè)卷積點(diǎn)而言:
假設(shè)有一個(gè)3×3大小的卷積層,其輸入通道為16、輸出通道為32。具體為,32個(gè)3×3大小的卷積核會(huì)遍歷16個(gè)通道中的每個(gè)數(shù)據(jù),最后可得到所需的32個(gè)輸出通道,所需參數(shù)為16×32×3×3=4608個(gè)。
應(yīng)用深度可分離卷積,用16個(gè)3×3大小的卷積核分別遍歷16通道的數(shù)據(jù),得到了16個(gè)特征圖譜。在融合操作之前,接著用32個(gè)1×1大小的卷積核遍歷這16個(gè)特征圖譜,所需參數(shù)為16×3×3+16×32×1×1=656個(gè)。
可以看出來depthwise separable convolution可以減少模型的參數(shù)。
如下這張圖就是depthwise separable convolution的結(jié)構(gòu)
在建立模型的時(shí)候,可以使用Keras中的DepthwiseConv2D層實(shí)現(xiàn)深度可分離卷積,然后再利用1x1卷積調(diào)整channels數(shù)。
通俗地理解就是3x3的卷積核厚度只有一層,然后在輸入張量上一層一層地滑動(dòng),每一次卷積完生成一個(gè)輸出通道,當(dāng)卷積完成后,在利用1x1的卷積調(diào)整厚度。
如下就是MobileNet的結(jié)構(gòu),其中Conv dw就是分層卷積,在其之后都會(huì)接一個(gè)1x1的卷積進(jìn)行通道處理,
MobileNet網(wǎng)絡(luò)部分實(shí)現(xiàn)代碼
#-------------------------------------------------------------# # MobileNet的網(wǎng)絡(luò)部分 #-------------------------------------------------------------# import warnings import numpy as np from keras.preprocessing import image from keras.models import Model from keras.layers import DepthwiseConv2D,Input,Activation,Dropout,Reshape,BatchNormalization,GlobalAveragePooling2D,GlobalMaxPooling2D,Conv2D from keras.applications.imagenet_utils import decode_predictions from keras import backend as K def MobileNet(input_shape=[224,224,3], depth_multiplier=1, dropout=1e-3, classes=1000): img_input = Input(shape=input_shape) # 224,224,3 -> 112,112,32 x = _conv_block(img_input, 32, strides=(2, 2)) # 112,112,32 -> 112,112,64 x = _depthwise_conv_block(x, 64, depth_multiplier, block_id=1) # 112,112,64 -> 56,56,128 x = _depthwise_conv_block(x, 128, depth_multiplier, strides=(2, 2), block_id=2) # 56,56,128 -> 56,56,128 x = _depthwise_conv_block(x, 128, depth_multiplier, block_id=3) # 56,56,128 -> 28,28,256 x = _depthwise_conv_block(x, 256, depth_multiplier, strides=(2, 2), block_id=4) # 28,28,256 -> 28,28,256 x = _depthwise_conv_block(x, 256, depth_multiplier, block_id=5) # 28,28,256 -> 14,14,512 x = _depthwise_conv_block(x, 512, depth_multiplier, strides=(2, 2), block_id=6) # 14,14,512 -> 14,14,512 x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=7) x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=8) x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=9) x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=10) x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=11) # 14,14,512 -> 7,7,1024 x = _depthwise_conv_block(x, 1024, depth_multiplier, strides=(2, 2), block_id=12) x = _depthwise_conv_block(x, 1024, depth_multiplier, block_id=13) # 7,7,1024 -> 1,1,1024 x = GlobalAveragePooling2D()(x) x = Reshape((1, 1, 1024), name='reshape_1')(x) x = Dropout(dropout, name='dropout')(x) x = Conv2D(classes, (1, 1),padding='same', name='conv_preds')(x) x = Activation('softmax', name='act_softmax')(x) x = Reshape((classes,), name='reshape_2')(x) inputs = img_input model = Model(inputs, x, name='mobilenet_1_0_224_tf') model_name = 'mobilenet_1_0_224_tf.h5' model.load_weights(model_name) return model def _conv_block(inputs, filters, kernel=(3, 3), strides=(1, 1)): x = Conv2D(filters, kernel, padding='same', use_bias=False, strides=strides, name='conv1')(inputs) x = BatchNormalization(name='conv1_bn')(x) return Activation(relu6, name='conv1_relu')(x) def _depthwise_conv_block(inputs, pointwise_conv_filters, depth_multiplier=1, strides=(1, 1), block_id=1): x = DepthwiseConv2D((3, 3), padding='same', depth_multiplier=depth_multiplier, strides=strides, use_bias=False, name='conv_dw_%d' % block_id)(inputs) x = BatchNormalization(name='conv_dw_%d_bn' % block_id)(x) x = Activation(relu6, name='conv_dw_%d_relu' % block_id)(x) x = Conv2D(pointwise_conv_filters, (1, 1), padding='same', use_bias=False, strides=(1, 1), name='conv_pw_%d' % block_id)(x) x = BatchNormalization(name='conv_pw_%d_bn' % block_id)(x) return Activation(relu6, name='conv_pw_%d_relu' % block_id)(x) def relu6(x): return K.relu(x, max_value=6)
圖片預(yù)測
建立網(wǎng)絡(luò)后,可以用以下的代碼進(jìn)行預(yù)測。
def preprocess_input(x): x /= 255. x -= 0.5 x *= 2. return x if __name__ == '__main__': model = MobileNet(input_shape=(224, 224, 3)) img_path = 'elephant.jpg' img = image.load_img(img_path, target_size=(224, 224)) 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, 1))
預(yù)測所需的已經(jīng)訓(xùn)練好的Xception模型可以在https://github.com/fchollet/deep-learning-models/releases下載。非常方便。預(yù)測結(jié)果為:
Predicted: [[('n02504458', 'African_elephant', 0.7590296)]]
以上就是python神經(jīng)網(wǎng)絡(luò)MobileNet模型的復(fù)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于MobileNet模型復(fù)現(xiàn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決Python安裝時(shí)報(bào)缺少DLL問題【兩種解決方法】
這篇文章主要介紹了解決Python安裝時(shí)報(bào)缺少DLL問題,本文通過兩種方法給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07Python比較文件夾比另一同名文件夾多出的文件并復(fù)制出來的方法
這篇文章主要介紹了Python比較文件夾比另一同名文件夾多出的文件并復(fù)制出來的方法,涉及Python針對文件與文件夾的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03利用python求解物理學(xué)中的雙彈簧質(zhì)能系統(tǒng)詳解
這篇文章主要給大家介紹了關(guān)于利用python如何求解物理學(xué)中的雙彈簧質(zhì)能系統(tǒng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09opencv調(diào)用yolov3模型深度學(xué)習(xí)目標(biāo)檢測實(shí)例詳解
這篇文章主要為大家介紹了opencv調(diào)用yolov3模型深度學(xué)習(xí)目標(biāo)檢測實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Python學(xué)習(xí)小技巧之列表項(xiàng)的排序
這篇文章主要給大家介紹了Python學(xué)習(xí)小技巧之列表項(xiàng)排序的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友們可以參借鑒,下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-05-05