用PaddlePaddle实现图像分类-MobileNet-v2(动态图版)

项目简介

本项目使用paddle实现图像分类模型 MobileNet-V2网络的训练和预测。MobileNet-V2是对 MobileNet-V1 的改进,同样是一个轻量级卷积神经网络。关于深度可分离卷积等MobileNet-V1相关的基础理论可以查看:图像分类-MobileNet-V1。静态图版本请查看:用PaddlePaddle实现图像分类-MobileNet-v2

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

模型结构

MobileNet-V1的缺陷

  1. 结构问题: MobileNet-V1使用了传统的直筒结构,然而后续的ResNet等网络结构证明了通过Residual Connection等操作复用图像特征的融合操作可以给网络带来更大的性能提升。
  2. Depthwise Convolution的问题: 虽然理论上N x N的DepthWise+1 x 1的PointWise在性能方面能够接近N x N的普通卷积,但是由于DepthWise的每个kernel维度较小,再Rlue激活函数的影响下,神经元的输出很容易变为0,从而使DepthWise部分的卷积过于稀疏,并且这个问题在定点化低精度训练的时候会进一步放大。

MobileNet-V2的改进

  1. Inverted Residual Block 添加了Residual Connection,由于DepthWise Convolution的参数量较小,所以作者并没有采用类似与ResNet中的先降维、再卷积、再升维的沙漏型Residual Block。而是改为先升维、再卷积、再降维的柳叶型Residual Block,并起名为Inverted Residual Block。具体结构图下图所示,Residual Connection并未在图中画出。
    用PaddlePaddle实现图像分类-MobileNet-v2(动态图版)
  2. ReLU6 在MobileNet-V1中DepthWise Convolution中最后一个1*1的conv后面接着ReLU6激活函数,而Xception已经证明了再DepthWise卷积后再加ReLU效果会变差,所以V2中去掉了最后的ReLU激活函数,改为线性的输出,具体结构如下图所示,V2中的Residual Connection并未画出。
    用PaddlePaddle实现图像分类-MobileNet-v2(动态图版)

MobileNet-V2结构图

用PaddlePaddle实现图像分类-MobileNet-v2(动态图版)

参考链接

MobileNet V2 论文初读
MobileNetV2: Inverted Residuals and Linear Bottlenecks

数据介绍

使用公开鲜花据集,数据集压缩包里包含五个文件夹,每个文件夹一种花卉。分别是雏菊,蒲公英,玫瑰,向日葵,郁金香。每种各690-890张不等

 
#代码结构
├── config.py   # 参数脚本
├── train.py   # 模型训练脚本
├── mobilenet.py     # mobilinet-v2网络结构.
├── eval.py     # 模型评估脚本
├── reader.py     # 数据读取.
├── logs     # 日志文件夹
├── infer.py     # 模型预测脚本

In[1]

#解压花朵数据集
!cd data/data2815 && unzip -q flower_photos.zip

In[2]

# 预处理数据,将其转化为标准格式。同时将数据拆分成两份,以便训练和计算预估准确率
import codecs  
import os  
import random  
import shutil  
from PIL import Image  
  
train_ratio = 4.0 / 5  
  
all_file_dir = 'data/data2815'  
class_list = [c for c in os.listdir(all_file_dir) if os.path.isdir(os.path.join(all_file_dir, c)) and not c.endswith('Set') and not c.startswith('.')]  
class_list.sort()
print(class_list)  
train_image_dir = os.path.join(all_file_dir, "trainImageSet")  
if not os.path.exists(train_image_dir):  
    os.makedirs(train_image_dir)  
      
eval_image_dir = os.path.join(all_file_dir, "evalImageSet")  
if not os.path.exists(eval_image_dir):  
    os.makedirs(eval_image_dir)  
  
train_file = codecs.open(os.path.join(all_file_dir, "train.txt"), 'w')  
eval_file = codecs.open(os.path.join(all_file_dir, "eval.txt"), 'w')  
  
with codecs.open(os.path.join(all_file_dir, "label_list.txt"), "w") as label_list:  
    label_id = 0  
    for class_dir in class_list:  
        label_list.write("{0}/t{1}/n".format(label_id, class_dir))  
        image_path_pre = os.path.join(all_file_dir, class_dir)  
        for file in os.listdir(image_path_pre):  
            try:  
                img = Image.open(os.path.join(image_path_pre, file))  
                if random.uniform(0, 1) <= train_ratio:  
                    shutil.copyfile(os.path.join(image_path_pre, file), os.path.join(train_image_dir, file))  
                    train_file.write("{0}/t{1}/n".format(os.path.join(train_image_dir, file), label_id))  
                else:  
                    shutil.copyfile(os.path.join(image_path_pre, file), os.path.join(eval_image_dir, file))  
                    eval_file.write("{0}/t{1}/n".format(os.path.join(eval_image_dir, file), label_id))  
            except Exception as e:  
                pass  
                # 存在一些文件打不开,此处需要稍作清洗  
        label_id += 1  
              
train_file.close()  
eval_file.close() 
['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']

In[11]

#进行训练
!python train.py
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
2020-03-09 13:38:34,085-INFO: input_size: [3, 224, 224]
[2020-03-09 13:38:34,085.085] config.py [line:95] INFO: input_size: [3, 224, 224]
2020-03-09 13:38:34,085-INFO: class_dim: 5
[2020-03-09 13:38:34,085.085] config.py [line:96] INFO: class_dim: 5
2020-03-09 13:38:34,085-INFO: continue_train: True
[2020-03-09 13:38:34,085.085] config.py [line:97] INFO: continue_train: True
2020-03-09 13:38:34,086-INFO: train_image_count: 2956
[2020-03-09 13:38:34,086.086] config.py [line:98] INFO: train_image_count: 2956
2020-03-09 13:38:34,086-INFO: eval_image_count: 714
[2020-03-09 13:38:34,086.086] config.py [line:99] INFO: eval_image_count: 714
2020-03-09 13:38:34,086-INFO: num_epochs: 1
[2020-03-09 13:38:34,086.086] config.py [line:100] INFO: num_epochs: 1
2020-03-09 13:38:34,086-INFO: train_batch_size: 16
[2020-03-09 13:38:34,086.086] config.py [line:101] INFO: train_batch_size: 16
2020-03-09 13:38:34,086-INFO: mean_rgb: [127.5, 127.5, 127.5]
[2020-03-09 13:38:34,086.086] config.py [line:102] INFO: mean_rgb: [127.5, 127.5, 127.5]
2020-03-09 13:38:34,086-INFO: save_model_dir: ./save_model/net
[2020-03-09 13:38:34,086.086] config.py [line:103] INFO: save_model_dir: ./save_model/net
2020-03-09 13:38:34,087-INFO: start train
[2020-03-09 13:38:34,087.087] train.py [line:60] INFO: start train
2020-03-09 13:38:34,221-INFO: use Adam optimizer
[2020-03-09 13:38:34,221.221] train.py [line:32] INFO: use Adam optimizer
2020-03-09 13:38:34,221-INFO: load params from ./save_model/net
[2020-03-09 13:38:34,221.221] train.py [line:44] INFO: load params from ./save_model/net
2020-03-09 13:38:54,793-INFO: loss at epoch 0 step 5: [1.5690882], acc: [0.25]
[2020-03-09 13:38:54,793.793] train.py [line:100] INFO: loss at epoch 0 step 5: [1.5690882], acc: [0.25]
2020-03-09 13:39:11,469-INFO: loss at epoch 0 step 10: [1.5497278], acc: [0.3125]
[2020-03-09 13:39:11,469.469] train.py [line:100] INFO: loss at epoch 0 step 10: [1.5497278], acc: [0.3125]
2020-03-09 13:39:28,135-INFO: loss at epoch 0 step 15: [1.5301065], acc: [0.3125]
[2020-03-09 13:39:28,135.135] train.py [line:100] INFO: loss at epoch 0 step 15: [1.5301065], acc: [0.3125]
2020-03-09 13:39:44,716-INFO: loss at epoch 0 step 20: [1.6101253], acc: [0.25]
[2020-03-09 13:39:44,716.716] train.py [line:100] INFO: loss at epoch 0 step 20: [1.6101253], acc: [0.25]
2020-03-09 13:40:01,349-INFO: loss at epoch 0 step 25: [1.4919833], acc: [0.4375]
[2020-03-09 13:40:01,349.349] train.py [line:100] INFO: loss at epoch 0 step 25: [1.4919833], acc: [0.4375]
2020-03-09 13:40:17,987-INFO: loss at epoch 0 step 30: [1.5312201], acc: [0.3125]
[2020-03-09 13:40:17,987.987] train.py [line:100] INFO: loss at epoch 0 step 30: [1.5312201], acc: [0.3125]
2020-03-09 13:40:34,710-INFO: loss at epoch 0 step 35: [1.4426799], acc: [0.375]
[2020-03-09 13:40:34,710.710] train.py [line:100] INFO: loss at epoch 0 step 35: [1.4426799], acc: [0.375]
2020-03-09 13:40:51,455-INFO: loss at epoch 0 step 40: [1.508328], acc: [0.25]
[2020-03-09 13:40:51,455.455] train.py [line:100] INFO: loss at epoch 0 step 40: [1.508328], acc: [0.25]
2020-03-09 13:41:07,931-INFO: loss at epoch 0 step 45: [1.5291041], acc: [0.3125]
[2020-03-09 13:41:07,931.931] train.py [line:100] INFO: loss at epoch 0 step 45: [1.5291041], acc: [0.3125]
2020-03-09 13:41:24,598-INFO: loss at epoch 0 step 50: [1.4646168], acc: [0.375]
[2020-03-09 13:41:24,598.598] train.py [line:100] INFO: loss at epoch 0 step 50: [1.4646168], acc: [0.375]
2020-03-09 13:41:41,214-INFO: loss at epoch 0 step 55: [1.4388181], acc: [0.4375]
[2020-03-09 13:41:41,214.214] train.py [line:100] INFO: loss at epoch 0 step 55: [1.4388181], acc: [0.4375]
2020-03-09 13:41:57,767-INFO: loss at epoch 0 step 60: [1.5756712], acc: [0.1875]
[2020-03-09 13:41:57,767.767] train.py [line:100] INFO: loss at epoch 0 step 60: [1.5756712], acc: [0.1875]
2020-03-09 13:42:14,286-INFO: loss at epoch 0 step 65: [1.502065], acc: [0.3125]
[2020-03-09 13:42:14,286.286] train.py [line:100] INFO: loss at epoch 0 step 65: [1.502065], acc: [0.3125]
2020-03-09 13:42:30,897-INFO: loss at epoch 0 step 70: [1.4633939], acc: [0.3125]
[2020-03-09 13:42:30,897.897] train.py [line:100] INFO: loss at epoch 0 step 70: [1.4633939], acc: [0.3125]
2020-03-09 13:42:47,400-INFO: loss at epoch 0 step 75: [1.5570679], acc: [0.1875]
[2020-03-09 13:42:47,400.400] train.py [line:100] INFO: loss at epoch 0 step 75: [1.5570679], acc: [0.1875]
2020-03-09 13:43:03,643-INFO: loss at epoch 0 step 80: [1.5089277], acc: [0.25]
[2020-03-09 13:43:03,643.643] train.py [line:100] INFO: loss at epoch 0 step 80: [1.5089277], acc: [0.25]
2020-03-09 13:43:19,989-INFO: loss at epoch 0 step 85: [1.6048481], acc: [0.25]
[2020-03-09 13:43:19,989.989] train.py [line:100] INFO: loss at epoch 0 step 85: [1.6048481], acc: [0.25]
2020-03-09 13:43:36,267-INFO: loss at epoch 0 step 90: [1.5638185], acc: [0.1875]
[2020-03-09 13:43:36,267.267] train.py [line:100] INFO: loss at epoch 0 step 90: [1.5638185], acc: [0.1875]
2020-03-09 13:43:52,511-INFO: loss at epoch 0 step 95: [1.497062], acc: [0.4375]
[2020-03-09 13:43:52,511.511] train.py [line:100] INFO: loss at epoch 0 step 95: [1.497062], acc: [0.4375]
2020-03-09 13:44:08,711-INFO: loss at epoch 0 step 100: [1.3667636], acc: [0.3125]
[2020-03-09 13:44:08,711.711] train.py [line:100] INFO: loss at epoch 0 step 100: [1.3667636], acc: [0.3125]
2020-03-09 13:44:24,904-INFO: loss at epoch 0 step 105: [1.5431788], acc: [0.3125]
[2020-03-09 13:44:24,904.904] train.py [line:100] INFO: loss at epoch 0 step 105: [1.5431788], acc: [0.3125]
2020-03-09 13:44:41,087-INFO: loss at epoch 0 step 110: [1.3445642], acc: [0.5625]
[2020-03-09 13:44:41,087.087] train.py [line:100] INFO: loss at epoch 0 step 110: [1.3445642], acc: [0.5625]
2020-03-09 13:44:57,222-INFO: loss at epoch 0 step 115: [1.6147933], acc: [0.25]
[2020-03-09 13:44:57,222.222] train.py [line:100] INFO: loss at epoch 0 step 115: [1.6147933], acc: [0.25]
2020-03-09 13:45:13,487-INFO: loss at epoch 0 step 120: [1.3866949], acc: [0.5625]
[2020-03-09 13:45:13,487.487] train.py [line:100] INFO: loss at epoch 0 step 120: [1.3866949], acc: [0.5625]
2020-03-09 13:45:29,831-INFO: loss at epoch 0 step 125: [1.6603546], acc: [0.1875]
[2020-03-09 13:45:29,831.831] train.py [line:100] INFO: loss at epoch 0 step 125: [1.6603546], acc: [0.1875]
2020-03-09 13:45:46,120-INFO: loss at epoch 0 step 130: [1.5387032], acc: [0.25]
[2020-03-09 13:45:46,120.120] train.py [line:100] INFO: loss at epoch 0 step 130: [1.5387032], acc: [0.25]
2020-03-09 13:46:02,468-INFO: loss at epoch 0 step 135: [1.6344273], acc: [0.25]
[2020-03-09 13:46:02,468.468] train.py [line:100] INFO: loss at epoch 0 step 135: [1.6344273], acc: [0.25]
2020-03-09 13:46:19,258-INFO: loss at epoch 0 step 140: [1.4245522], acc: [0.375]
[2020-03-09 13:46:19,258.258] train.py [line:100] INFO: loss at epoch 0 step 140: [1.4245522], acc: [0.375]
2020-03-09 13:46:35,567-INFO: loss at epoch 0 step 145: [1.366779], acc: [0.5]
[2020-03-09 13:46:35,567.567] train.py [line:100] INFO: loss at epoch 0 step 145: [1.366779], acc: [0.5]
2020-03-09 13:46:52,113-INFO: loss at epoch 0 step 150: [1.4514699], acc: [0.3125]
[2020-03-09 13:46:52,113.113] train.py [line:100] INFO: loss at epoch 0 step 150: [1.4514699], acc: [0.3125]
2020-03-09 13:47:08,457-INFO: loss at epoch 0 step 155: [1.3940936], acc: [0.3125]
[2020-03-09 13:47:08,457.457] train.py [line:100] INFO: loss at epoch 0 step 155: [1.3940936], acc: [0.3125]
2020-03-09 13:47:24,925-INFO: loss at epoch 0 step 160: [1.2480397], acc: [0.4375]
[2020-03-09 13:47:24,925.925] train.py [line:100] INFO: loss at epoch 0 step 160: [1.2480397], acc: [0.4375]
2020-03-09 13:47:41,356-INFO: loss at epoch 0 step 165: [1.4148235], acc: [0.4375]
[2020-03-09 13:47:41,356.356] train.py [line:100] INFO: loss at epoch 0 step 165: [1.4148235], acc: [0.4375]
2020-03-09 13:47:57,652-INFO: loss at epoch 0 step 170: [1.5028722], acc: [0.125]
[2020-03-09 13:47:57,652.652] train.py [line:100] INFO: loss at epoch 0 step 170: [1.5028722], acc: [0.125]
2020-03-09 13:48:14,108-INFO: loss at epoch 0 step 175: [1.3406444], acc: [0.4375]
[2020-03-09 13:48:14,108.108] train.py [line:100] INFO: loss at epoch 0 step 175: [1.3406444], acc: [0.4375]
2020-03-09 13:48:30,419-INFO: loss at epoch 0 step 180: [1.5958593], acc: [0.25]
[2020-03-09 13:48:30,419.419] train.py [line:100] INFO: loss at epoch 0 step 180: [1.5958593], acc: [0.25]
2020-03-09 13:48:40,447-INFO: epoch 0 acc: [0.35461956]
[2020-03-09 13:48:40,447.447] train.py [line:103] INFO: epoch 0 acc: [0.35461956]
2020-03-09 13:48:40,447-INFO: current epoch 0 acc: [0.35461956] better than last acc: 0.0, save model
[2020-03-09 13:48:40,447.447] train.py [line:106] INFO: current epoch 0 acc: [0.35461956] better than last acc: 0.0, save model
2020-03-09 13:48:40,554-INFO: train till end
[2020-03-09 13:48:40,554.554] train.py [line:113] INFO: train till end

In[12]

#训练1轮,在验证集上评估
!python eval.py
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
[2020-03-09 13:49:42,402.402] config.py [line:91] INFO: input_size: [3, 224, 224]
[2020-03-09 13:49:42,402.402] config.py [line:92] INFO: class_dim: 5
[2020-03-09 13:49:42,402.402] config.py [line:93] INFO: continue_train: True
[2020-03-09 13:49:42,402.402] config.py [line:94] INFO: train_image_count: 2956
[2020-03-09 13:49:42,402.402] config.py [line:95] INFO: eval_image_count: 714
[2020-03-09 13:49:42,402.402] config.py [line:96] INFO: num_epochs: 1
[2020-03-09 13:49:42,402.402] config.py [line:97] INFO: train_batch_size: 16
[2020-03-09 13:49:42,402.402] config.py [line:98] INFO: mean_rgb: [127.5, 127.5, 127.5]
[2020-03-09 13:49:42,402.402] config.py [line:99] INFO: save_model_dir: ./save_model/net
[2020-03-09 13:49:42,403.403] eval.py [line:16] INFO: start eval
[2020-03-09 13:50:28,884.884] eval.py [line:45] INFO: test count: 714 , acc: 0.46078431606292725 cost time: 46.25327682495117

In[10]

#模型预测
!python infer.py
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
2020-03-09 13:35:37,587-INFO: input_size: [3, 224, 224]
[2020-03-09 13:35:37,587.587] config.py [line:95] INFO: input_size: [3, 224, 224]
2020-03-09 13:35:37,587-INFO: class_dim: 5
[2020-03-09 13:35:37,587.587] config.py [line:96] INFO: class_dim: 5
2020-03-09 13:35:37,587-INFO: continue_train: True
[2020-03-09 13:35:37,587.587] config.py [line:97] INFO: continue_train: True
2020-03-09 13:35:37,588-INFO: train_image_count: 2956
[2020-03-09 13:35:37,588.588] config.py [line:98] INFO: train_image_count: 2956
2020-03-09 13:35:37,588-INFO: eval_image_count: 714
[2020-03-09 13:35:37,588.588] config.py [line:99] INFO: eval_image_count: 714
2020-03-09 13:35:37,588-INFO: num_epochs: 1
[2020-03-09 13:35:37,588.588] config.py [line:100] INFO: num_epochs: 1
2020-03-09 13:35:37,588-INFO: train_batch_size: 16
[2020-03-09 13:35:37,588.588] config.py [line:101] INFO: train_batch_size: 16
2020-03-09 13:35:37,588-INFO: mean_rgb: [127.5, 127.5, 127.5]
[2020-03-09 13:35:37,588.588] config.py [line:102] INFO: mean_rgb: [127.5, 127.5, 127.5]
2020-03-09 13:35:37,588-INFO: save_model_dir: ./save_model/net
[2020-03-09 13:35:37,588.588] config.py [line:103] INFO: save_model_dir: ./save_model/net
2020-03-09 13:35:37,602-INFO: input_size: [3, 224, 224]
[2020-03-09 13:35:37,602.602] config.py [line:95] INFO: input_size: [3, 224, 224]
2020-03-09 13:35:37,603-INFO: class_dim: 5
[2020-03-09 13:35:37,603.603] config.py [line:96] INFO: class_dim: 5
2020-03-09 13:35:37,603-INFO: continue_train: True
[2020-03-09 13:35:37,603.603] config.py [line:97] INFO: continue_train: True
2020-03-09 13:35:37,603-INFO: train_image_count: 2956
[2020-03-09 13:35:37,603.603] config.py [line:98] INFO: train_image_count: 2956
2020-03-09 13:35:37,603-INFO: eval_image_count: 714
[2020-03-09 13:35:37,603.603] config.py [line:99] INFO: eval_image_count: 714
2020-03-09 13:35:37,603-INFO: num_epochs: 1
[2020-03-09 13:35:37,603.603] config.py [line:100] INFO: num_epochs: 1
2020-03-09 13:35:37,603-INFO: train_batch_size: 16
[2020-03-09 13:35:37,603.603] config.py [line:101] INFO: train_batch_size: 16
2020-03-09 13:35:37,603-INFO: mean_rgb: [127.5, 127.5, 127.5]
[2020-03-09 13:35:37,603.603] config.py [line:102] INFO: mean_rgb: [127.5, 127.5, 127.5]
2020-03-09 13:35:37,603-INFO: save_model_dir: ./save_model/net
[2020-03-09 13:35:37,603.603] config.py [line:103] INFO: save_model_dir: ./save_model/net
checkpoint loaded
image data/data2815/sunflowers/8192234807_fed4a46f1a_n.jpg Infer result is: sunflowers

点击链接,使用AI Studio一键上手实践项目吧:https://aistudio.baidu.com/aistudio/projectdetail/169403 

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

>> 访问 PaddlePaddle 官网,了解更多相关内容

{{o.name}}


{{m.name}}

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/103443.html

(0)
上一篇 2021年8月25日 10:21
下一篇 2021年8月25日 10:21

相关推荐

发表回复

登录后才能评论