MobileNet V2 复现
生活随笔
收集整理的這篇文章主要介紹了
MobileNet V2 复现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
MobileNet V2 復現
Windows 10
python 3.7.6
tensorflow 2.1
cuda 10.2
?
模型文件 model.py
# -*- coding:utf-8 _*- """ # @Author: DongHao # @Date: 2020/11/6 13:38 # @File: model.py # MobileNet V2 """ from tensorflow.keras import Model, layers, Sequential, activationsclass Bottleneck(layers.Layer):def __init__(self, output, strides=1, shortcut=False, **kwargs):super(Bottleneck, self).__init__(**kwargs)# ---------------------------------------------------------------------------------------------------------# PW, 只改變通道數,不改變寬度和高度,所以 strides=1self.conv1 = layers.Conv2D(filters=output, kernel_size=1, strides=1, padding='SAME', use_bias=False)self.bn1 = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)self.relu1 = layers.ReLU(max_value=6)# ---------------------------------------------------------------------------------------------------------# DW, 只改變寬度和高度,不改變通道數self.conv2 = layers.DepthwiseConv2D(kernel_size=3, strides=strides, padding='SAME', use_bias=False)self.bn2 = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)self.relu2 = layers.ReLU(max_value=6)# ---------------------------------------------------------------------------------------------------------# PW, 只改變通道數,不改變寬度和高度,所以 strides=1self.conv3 = layers.Conv2D(filters=output, kernel_size=1, strides=1, padding='SAME', use_bias=False)self.bn3 = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)self.linear = activations.linear# ---------------------------------------------------------------------------------------------------------self.shortcut = shortcutself.add = layers.Add()def call(self, inputs, training=False, **kwargs):x = self.conv1(inputs)x = self.bn1(x, training=training)x = self.relu1(x)x = self.conv2(x)x = self.bn2(x, training=training)x = self.relu2(x)x = self.conv3(x)x = self.bn3(x, training=training)x = self.linear(x)if self.shortcut is True:x = self.add([inputs, x])return xclass MobileNet(Model):def __init__(self, block, block_num, num_classes=1000, **kwargs):super(MobileNet, self).__init__(**kwargs)# ---------------------------------------------------------------------------------------------------------self.conv1 = layers.Conv2D(filters=32, kernel_size=3, strides=2, padding='SAME', use_bias=False)self.bn1 = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)self.relu1 = layers.ReLU(max_value=6)# ---------------------------------------------------------------------------------------------------------self.bottleneck1 = self.make_layer(block, block_num[0], 16, strides=1, shortcut=False)self.bottleneck2 = self.make_layer(block, block_num[1], 24, strides=2, shortcut=False)self.bottleneck3 = self.make_layer(block, block_num[2], 32, strides=2, shortcut=False)self.bottleneck4 = self.make_layer(block, block_num[3], 64, strides=2, shortcut=False)self.bottleneck5 = self.make_layer(block, block_num[4], 96, strides=1, shortcut=False)self.bottleneck6 = self.make_layer(block, block_num[5], 160, strides=2, shortcut=False)self.bottleneck7 = self.make_layer(block, block_num[6], 320, strides=1, shortcut=False)# ---------------------------------------------------------------------------------------------------------self.conv2 = layers.Conv2D(filters=1280, kernel_size=1, strides=1, padding='SAME', use_bias=False)self.bn2 = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)self.relu2 = layers.ReLU(max_value=6)# ---------------------------------------------------------------------------------------------------------self.avgpool = layers.GlobalAvgPool2D() # pool + flattenself.fc = layers.Dense(num_classes, activation='softmax')def make_layer(self, block, block_num, channel, strides, shortcut=False):layer_list = [(block(channel, strides=strides, shortcut=shortcut))]for i in range(1, block_num):layer_list.append(block(channel, strides=1, shortcut=True))return Sequential(layer_list)def call(self, inputs, training=False, **kwargs):x = self.conv1(inputs)x = self.bn1(x, training=training)x = self.relu1(x)x = self.bottleneck1(x, training=training)x = self.bottleneck2(x, training=training)x = self.bottleneck3(x, training=training)x = self.bottleneck4(x, training=training)x = self.bottleneck5(x, training=training)x = self.bottleneck6(x, training=training)x = self.bottleneck7(x, training=training)x = self.conv2(x)x = self.bn2(x, training=training)x = self.relu2(x)x = self.avgpool(x)x = self.fc(x)return xdef mobilenet(num_classes=1000):blocks_num = [1, 2, 3, 4, 3, 3, 1]return MobileNet(Bottleneck, blocks_num, num_classes)# dw卷積如何實現的 DepthwiseConv2D # 線性激活如何實現的 activations.linear(x) # shutcut如何實現的 shortcut=False, 每個規模一樣的bottleneck除第一個外其余都有shutcut,每個不同bottleneck的第一個,都沒有shutcut,因為前后通道都會改變(在此例中) # 每個不同bottleneck的第一個中,第一個pw實現通道改變,后面所有pw都只是維持,Dw進行改變大小,后面的Dw都是維持?
?
訓練文件 train.py
# -*- coding:utf-8 _*- """ # @Author: DongHao # @Date: 2020/11/3 15:29 # @File: train.py """ from tensorflow.keras.preprocessing.image import ImageDataGenerator import matplotlib.pyplot as plt from model import mobilenet import tensorflow as tf from PIL import Image import numpy as np import json import osos.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"] = "3"im_height = 224 im_width = 224 classical_path = "./class_indices.json" checkpoint_save_path = "./checkpoint/MobileNet.ckpt" test_data_path = os.path.abspath(os.getcwd() + "/../DataSet/testdata") train_dir = os.path.abspath(os.getcwd() + "/../DataSet/flower_data/train") validation_dir = os.path.abspath(os.getcwd() + "/../DataSet/flower_data/val")print("\n=============================這里是 MobileNet ===========================\n")train_image_generator = ImageDataGenerator(horizontal_flip=True) train_data_gen = train_image_generator.flow_from_directory(directory=train_dir, batch_size=3306, shuffle=True,target_size=(im_height, im_width), class_mode='categorical')class_indices = train_data_gen.class_indices # get class dict inverse_dict = dict((val, key) for key, val in class_indices.items()) json_str = json.dumps(inverse_dict, indent=4) with open(classical_path, 'w') as json_file:json_file.write(json_str)validation_image_generator = ImageDataGenerator() val_data_gen = validation_image_generator.flow_from_directory(directory=validation_dir, batch_size=364, shuffle=False,target_size=(im_height, im_width), class_mode='categorical')print("class_indices : ", class_indices) print("total_train : ", train_data_gen.n) print("total_val : ", val_data_gen.n)print("===============================數據加載中===========================") train_x, train_y = next(train_data_gen) validation_x, validation_y = next(val_data_gen) print("=============================數據加載完畢===========================\n")print("=============================模型加載中===========================") model = mobilenet(num_classes=5) model.build((None, 224, 224, 3)) model.summary() # model.build(input_shape) # `input_shape` is the shape of the input data, e.g. input_shape = (None, 32, 32, 3) model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),metrics=["accuracy"]) print("=============================模型加載完畢===========================\n")print("=============================模型訓練中===========================") cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path, save_weights_only=True, save_best_only=True) model.fit(train_x, train_y, batch_size=32, epochs=450, validation_data=(validation_x, validation_y), callbacks=[cp_callback]) model.summary() print("=============================模型訓練完畢===========================\n")?
預測文件 predict.py
# -*- coding:utf-8 _*- """ # @Author: DongHao # @Date: 2020/11/3 22:30 # @File: predict.py """ from tensorflow.keras.preprocessing.image import ImageDataGenerator import matplotlib.pyplot as plt from MobileNet.model import mobilenet import tensorflow as tf from PIL import Image import numpy as np import json import osos.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"] = "-1"im_height = 224 im_width = 224 modelname = "MobileNet" classical_path = "./" + modelname + "/class_indices.json" checkpoint_save_path = "./" + modelname + "/checkpoint/" + modelname + ".ckpt" test_data_path = os.path.abspath(os.getcwd() + "/DataSet/testdata")print("=============================這里是 " + modelname + " ===========================\n") with open(classical_path, 'r') as json_file:class_indict = json.load(json_file)print("=============================模型加載中===========================") model = mobilenet(num_classes=5) model.load_weights(checkpoint_save_path) print("checkpoint path is ", checkpoint_save_path) print("=============================模型加載完畢===========================\n")print("=============================模型預測中===========================") files = os.listdir(test_data_path) for name in files:path = test_data_path + "\\" + str(name)img = Image.open(path)img = img.resize((im_width, im_height))img = np.array(img).astype(np.float32)img = (np.expand_dims(img, 0))result = model.predict(img)prediction = np.squeeze(result)predict_class = np.argmax(result)print(name)print(class_indict[str(predict_class)], prediction[predict_class])print("result is :", result) print("=============================模型預測完畢===========================\n")?
?
模型文件是根據自己對mobilenet 的理解自己編寫的,如果有錯誤,請大家指出,我隨時糾正,大家共同進步
總結
以上是生活随笔為你收集整理的MobileNet V2 复现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ResNet50 复现
- 下一篇: Python 将视频 截取 成图片