论文:《MobileNetV2: Inverted Residuals and Linear Bottlenecks》
论文地址:https://arxiv.org/abs/1801.04381
MobileNetV2是对MobileNetV1的改进,同样是一个轻量化卷积神经网络,它具有两个创新点:
1、Inverted residual block:先用1x1普通卷积将输入的feature map维度变大,然后用3x3 深度可分离卷积方式做卷积运算,最后使用1x1的普通卷积运算将其维度缩小,如下图所示:
2、Linear Bottlenecks:在最后的1x1卷积运算后,不再使用ReLU激活函数,而是使用线性激活函数,以保留更多特征信息,保证模型的表达能力。
当stride=1时,block内会有short cut连接;而当stride=2时,block没有short cut连接。
MobileNetV2网络整体结构:
tensorflow.keras.applications模块内置了许多模型,包括Xception、InceptionV3、VGG等,我们可以使用内置的MobileNetV2模型,只需修改最后的全连接层输出类别即可。
数据集地址:https://www.kaggle.com/slothkong/10-monkey-species
采用kaggle上的猴子数据集,包含两个文件:训练集和验证集。每个文件夹包含10个标记为n0-n9的猴子。图像尺寸为400x300像素或更大,并且为JPEG格式(近1400张图像)。
图片样本
图片类别标签,训练集,验证集划分说明
#导入相应的库
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import tensorflow as tf
#设置图片的高和宽,一次训练所选取的样本数,迭代次数
im_height = 224
im_width = 224
batch_size = 64
epochs = 13
image_path = "../input/10-monkey-species/" # monkey数据集路径
train_dir = image_path + "training/training" # 训练集路径
validation_dir = image_path + "validation/validation" # 验证集路径
# 定义训练集图像生成器,并进行图像增强
train_image_generator = ImageDataGenerator( rescale=1./255, # 归一化
rotation_range=40, #旋转范围
width_shift_range=0.2, #水平平移范围
height_shift_range=0.2, #垂直平移范围
shear_range=0.2, #剪切变换的程度
zoom_range=0.2, #缩放范围
horizontal_flip=True, #水平翻转
fill_mode='nearest')
# 使用图像生成器从文件夹train_dir中读取样本,对标签进行one-hot编码
train_data_gen = train_image_generator.flow_from_directory(directory=train_dir,
batch_size=batch_size,
shuffle=True, #打乱数据
target_size=(im_height, im_width),
class_mode='categorical')
# 训练集样本数
total_train = train_data_gen.n
# 定义验证集图像生成器,并对图像进行预处理
validation_image_generator = ImageDataGenerator(rescale=1./255) #归一化
# 使用图像生成器从验证集validation_dir中读取样本
val_data_gen = validation_image_generator.flow_from_directory(directory=validation_dir,
batch_size=batch_size,
shuffle=False, #不打乱数据
target_size=(im_height, im_width),
class_mode='categorical')
# 验证集样本数
total_val = val_data_gen.n
#使用tf.keras.applications中的MobileNetV2网络,并且使用官方的预训练模型
covn_base = tf.keras.applications.MobileNetV2(weights='imagenet',include_top=False)
covn_base.trainable = True
#冻结前面的层,训练最后五层
for layers in covn_base.layers[:-5]:
layers.trainable = False
#构建模型
model = tf.keras.Sequential()
model.add(covn_base)
model.add(tf.keras.layers.GlobalAveragePooling2D()) #加入全局平均池化层
model.add(tf.keras.layers.Dense(10,activation='softmax')) #加入输出层(10分类)
#编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), #使用adam优化器,学习率为0.0001
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False), #交叉熵损失函数
metrics=["accuracy"]) #评价函数
# 每层参数信息
model.summary()
#开始训练
history = model.fit(x=train_data_gen,
steps_per_epoch=total_train // batch_size,
epochs=epochs,
validation_data=val_data_gen,
validation_steps=total_val // batch_size)
# 记录训练集和验证集的准确率和损失值
history_dict = history.history
train_loss = history_dict["loss"]
train_accuracy = history_dict["accuracy"]
val_loss = history_dict["val_loss"]
val_accuracy = history_dict["val_accuracy"]
# 绘制损失值
plt.figure()
plt.plot(range(epochs), train_loss, label='train_loss')
plt.plot(range(epochs), val_loss, label='val_loss')
plt.legend()
plt.xlabel('epochs')
plt.ylabel('loss')
# 绘制准确率
plt.figure()
plt.plot(range(epochs), train_accuracy, label='train_accuracy')
plt.plot(range(epochs), val_accuracy, label='val_accuracy')
plt.legend()
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.show()
1.模型参数
由于大部分层被冻结了,所以可训练的参数很少,只有732,810个参数
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
mobilenetv2_1.00_224 (Model) (None, None, None, 1280) 2257984
_________________________________________________________________
global_average_pooling2d (Gl (None, 1280) 0
_________________________________________________________________
dense (Dense) (None, 10) 12810
=================================================================
Total params: 2,270,794
Trainable params: 732,810
Non-trainable params: 1,537,984
_________________________________________________________________
2.训练过程
从结果可以看出,使用迁移学习的时候模型收敛的速度很快,当训练第13个epoch时训练集准确率为98.36%,验证集的准确率为96.09%
Epoch 1/13
17/17 [==============================] - 91s 5s/step - loss: 1.6202 - accuracy: 0.5019 - val_loss: 0.8118 - val_accuracy: 0.7539
Epoch 2/13
17/17 [==============================] - 91s 5s/step - loss: 0.5115 - accuracy: 0.9168 - val_loss: 0.3875 - val_accuracy: 0.8945
Epoch 3/13
17/17 [==============================] - 90s 5s/step - loss: 0.2788 - accuracy: 0.9371 - val_loss: 0.2711 - val_accuracy: 0.9180
Epoch 4/13
17/17 [==============================] - 92s 5s/step - loss: 0.1982 - accuracy: 0.9568 - val_loss: 0.2426 - val_accuracy: 0.9297
Epoch 5/13
17/17 [==============================] - 90s 5s/step - loss: 0.1657 - accuracy: 0.9613 - val_loss: 0.2165 - val_accuracy: 0.9297
Epoch 6/13
17/17 [==============================] - 90s 5s/step - loss: 0.1348 - accuracy: 0.9720 - val_loss: 0.1942 - val_accuracy: 0.9219
Epoch 7/13
17/17 [==============================] - 90s 5s/step - loss: 0.1212 - accuracy: 0.9758 - val_loss: 0.1516 - val_accuracy: 0.9375
Epoch 8/13
17/17 [==============================] - 90s 5s/step - loss: 0.1197 - accuracy: 0.9729 - val_loss: 0.1303 - val_accuracy: 0.9570
Epoch 9/13
17/17 [==============================] - 91s 5s/step - loss: 0.1110 - accuracy: 0.9778 - val_loss: 0.1261 - val_accuracy: 0.9531
Epoch 10/13
17/17 [==============================] - 89s 5s/step - loss: 0.0912 - accuracy: 0.9874 - val_loss: 0.1293 - val_accuracy: 0.9531
Epoch 11/13
17/17 [==============================] - 93s 5s/step - loss: 0.0864 - accuracy: 0.9826 - val_loss: 0.1229 - val_accuracy: 0.9570
Epoch 12/13
17/17 [==============================] - 92s 5s/step - loss: 0.0738 - accuracy: 0.9855 - val_loss: 0.1174 - val_accuracy: 0.9609
Epoch 13/13
17/17 [==============================] - 90s 5s/step - loss: 0.0706 - accuracy: 0.9836 - val_loss: 0.1143 - val_accuracy: 0.9609
3.准确率曲线
记录每个epoch的训练集和验证集准确率并绘制出来进行对比,可以看到从第4个epoch开始逐渐趋于稳定
4.损失值曲线
记录每个epoch的训练集和验证集损失值并绘制出来进行对比,同样从4个epoch开始逐渐趋于稳定