基于tensorflow_slim模型调参的flower102鲜花分类过程

基于tensorflow_slim模型调参的flower102鲜花分类过程

实验软件环境如下
windows10
tensorflow-gpu 1.11
python3.5

1.数据分析工作

1.1数据介绍

该数据集由102类产自英国的花卉组成。每类由40-258张图片组成。具体示例如下图所示:
![png] (https://my-picture-bed-1256685253.cos.ap-shanghai.myqcloud.com/201812/%E8%8A%B1%E7%A4%BA%E4%BE%8B.PNG)
下载地址为:http://www.robots.ox.ac.uk/~vgg/data/flowers/102/
其中有两个mat文件标记了整个数据集的label,具体结构如下:

-imagelabels.mat

总共有8189列,每列上的数字代表类别号。

-setid.mat

-trnid字段:总共有1020列,每10列为一类花卉的图片,每列上的数字代表图片号。    
-valid字段:总共有1020列,每10列为一类花卉的图片,每列上的数字代表图片号。    
-tstid字段:总共有6149列,每一类花卉的列数不定,每列上的数字代表图片号。

2.数据预处理

tensorflow-slim 程序包是由谷歌公司提供的图像分类工具包,其中预训练的比较流行的图像分类的神经网络,比如VGG16,VGG19,InceptionV1~V4,残差网络等等,实验中我们使用了比较新的InceptionV3模型进行训练.

2.1数据集图像格式处理

对于InceptionV3网络,要求输入的图片分辨率保持一致,由于数据集中的图片大小不一,所以需要修改分辨率后保存,这里将图片统一保存为256*256的jpg格式,具体代码如下:

    #flower_dir[tid]为原图片的绝对地址
    img=Image.open(flower_dir[tid])
    img = img.resize((256, 256),Image.ANTIALIAS)
    #despath为生成标准图片的保存地址
    img.save(despath)

2.2数据集存储路径处理

在slim框架中,对于数据集的存储路径以及存储格式是由要求的,具体示例如下:

data_prepare/
    pic/
        train/
            class1/
                img1
                img2
                ...
            class2
                img1
                img2
                ...
        validation/
            class1/
                img1
                img2
                ...
            class2
                img1
                img2
                ...

所以需要根据数据集提供的标签规整图片的路径.总体代码如下:

import scipy.io
import numpy as np
import os
from PIL import Image
import shutil

########取出 imagelabels 文件的值############

imagelabels_path='I:\\dataSet\\imagelabels.mat'
labels = scipy.io.loadmat(imagelabels_path)
labels = np.array(labels['labels'][0])-1

######## 取出 flower dataset: train test valid 数据id标识 ########
setid_path='I:\\dataSet\\setid.mat'
setid = scipy.io.loadmat(setid_path)

validation = np.array(setid['valid'][0]) - 1
np.random.shuffle(validation)

train = np.array(setid['trnid'][0]) - 1
np.random.shuffle(train)

test=np.array(setid['tstid'][0]) -1
np.random.shuffle(test)
######## flower data path 数据保存路径 ########
flower_dir = list()

######## flower data dirs 生成保存数据的绝对路径和名称 ########
for img in os.listdir("I:\\dataSet\\102flowers"):
    
    ######## flower data ########
    flower_dir.append(os.path.join("I:\\dataSet\\102flowers", img))

######## flower data dirs sort 数据的绝对路径和名称排序 从小到大 ########
flower_dir.sort()

#print(flower_dir)

#####生成flower data train的分类数据 #######
des_folder_train="I:\\dataSet\\prepare_pic\\train"
for tid in train:
    ######## open image and get label ########
    img=Image.open(flower_dir[tid])
    #print(flower_dir[tid])
    ######## resize img #######
    img = img.resize((256, 256),Image.ANTIALIAS)
    lable=labels[tid]
    #print(lable)
    
    path=flower_dir[tid]
    #print("path:",path)
    
    base_path=os.path.basename(path)
    #print("base_path:",base_path) 
    ######类别目录路径
    classes="c"+str(lable)
    class_path=os.path.join(des_folder_train,classes)
    
    if not os.path.exists(class_path):
        os.makedirs(class_path) 
    
    #print("class_path:",class_path) 
    despath=os.path.join(class_path,base_path)
    #print("despath:",despath)
    img.save(despath)


#####生成flower data validation的分类数据 #######   
des_folder_validation="I:\\dataSet\\prepare_pic\\validation"

for tid in validation:
    ######## open image and get label ########
    img=Image.open(flower_dir[tid])
    #print(flower_dir[tid])
    img = img.resize((256, 256),Image.ANTIALIAS)
    lable=labels[tid]
    #print(lable)
    path=flower_dir[tid]
    print("path:",path)
    base_path=os.path.basename(path)
    print("base_path:",base_path) 
    classes="c"+str(lable)
    class_path=os.path.join(des_folder_validation,classes)
    # 判断结果
    if not os.path.exists(class_path):

        os.makedirs(class_path) 
    print("class_path:",class_path) 
    despath=os.path.join(class_path,base_path)
    print("despath:",despath)
    img.save(despath)


#####生成flower data test的分类数据 #######     
des_folder_test="I:\\dataSet\\prepare_pic\\test"
for tid in test:
    ######## open image and get label ########
    img=Image.open(flower_dir[tid])
    #print(flower_dir[tid])
    img = img.resize((256, 256),Image.ANTIALIAS)
    lable=labels[tid]
    #print(lable)
    path=flower_dir[tid]
    print("path:",path)
    base_path=os.path.basename(path)
    print("base_path:",base_path) 
    classes="c"+str(lable)
    class_path=os.path.join(des_folder_test,classes)
    # 判断结果
    if not os.path.exists(class_path):
        os.makedirs(class_path) 
    print("class_path:",class_path) 
    despath=os.path.join(class_path,base_path)
    print("despath:",despath)
    img.save(despath)

数据生成之后,共生成三个目录,分别为train,test,validation如下目录格式:


训练集目录

train目录格式示例

文件数量如下所示:

train:
    102类:1020个图片
validation:
    102类:1020幅图片
test:
    102类:6149幅图片

标准图片已经路径的处理工作完成之后,需要使用slim提供的脚本将图片转换为tfrecord格式,该格式作为tensorflow高速读取的二进制文件,数据的高速传输提供了接口,具体使用的教程可以参考该博主.

在实验过程中,我们使用预先编译好的脚本文件data_convert.py对图片进行转换,进入到该文件所在目录,使用如下命令:

    python data_convert.py -t I:\\prepare_data\\prepare_pic #生成图片根目录路径
    --train-shards 5\ #切成5两个tfrecord train文件
    --validation-shards 5\ #切成5两个tfrecord train文件
    --num-threads 5\  #启动五个线程运算
    --dataset-name flower102 #文件名头

运行完成后生成以下文件:


tfrecord格式

3.模型选择

4.模型微调

4.1 拷贝文件到数据集目录

  • 首先将生成的tfrecord文件以及label.txt拷贝到slim模型中,具体路径为slim/flower102/data

4.2定义新的datasets文件

对模型有一定的了解之后,我们进入到模型微调阶段,要将slim/datasets文件中的flowers.py做一些修改,并且另存flowers102.py具体修改以及解释如下:

#将tfrecord文件的文件头改为flower102,对应生成tfrecord文件过程中的--dataset-name flower102命令
_FILE_PATTERN = 'flower102_%s_*.tfrecord'
# 设置训练集与验证集的图片个数,都是1020
SPLITS_TO_SIZES = {'train': 1020, 'validation': 1020}
#设置类别个数:102
_NUM_CLASSES = 102
#将图片格式改为"jpg"
keys_to_features = {
      'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
      'image/format': tf.FixedLenFeature((), tf.string, default_value='jpg'),
      'image/class/label': tf.FixedLenFeature(
          [], tf.int64, default_value=tf.zeros([], dtype=tf.int64)),
  }

修改完flowers102.py后,还需要对同目录下的dataset_factory.py进行修改,具体修改内容如下:

from datasets import flower102
datasets_map = {

    'flower102':flower102,
}

具体就是把刚才新建的flower102添加到包中.

5.训练模型

5.1 准备训练文件夹:

在slim文件中建立以下目录结构:

slim/
    flower102/
        data/
        pretrained/
        train_dir/
  • data中存放tfrecord数据,已经在4.1步完成
  • pretrained中放置已经训练好的InceptionV3的模型,可以在网上下载,源文件中也已经包含.
  • train_dir是用来保存训练过程中存储的模型的文件夹.

5.2 开始训练模型

在slim文件夹中,使用train_image_classifier.py文件对模型进行训练,具体命令行以及解释如下:

python train_image_classifier.py \
#模型保存路径
--train_dir=flower102/train_dir \
#数据集名称
--dataset_name=flower102 \
#数据集切分后的第二名称(train)
--dataset_split_name=train \
#数据集所在目录
--dataset_dir=flower102/data \
#使用的模型名称
--model_name=inception_v3 \
#使用的模型的地址
--checkpoint_path=flower102/pretrained/inception_v3.ckpt \
#微调层(在恢复训练模型时,不恢复这两层,这两层对V3模型的末端层,原模型对应1000类,而新模型只对应102类)
--checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \
--trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \
#最大迭代次数
--max_number_of_steps=100 \
#batch_size
--batch_size=32 
#学习率
--learning_rate=0.001 \
#学习率是否自动下降 此处为固定值
--learning_rate_decay_type=fixed \
#间隔多久保存一次模型
--save_interval_secs=50 \
#间隔多久写入日志以供tensorborad查看
--save_summaries_secs=2 \
#间隔迭代次数打印
--log_every_n_steps=10 \
#选定优化器
--optimizer=rmsprop \
#选定模型中2次正则化超参数
--weight_decay=0.00004 \

使用该命令对模型进行训练,训练过程部分截图如下:


训练过程.PNG

使用tensorboard工具可以查看到损失函数下降的过程:

tensorboard --logdir flower102/train_dir
损失函数.PNG

6.验证模型

验证过程与训练过程所使用的命令类似,如下:

python eval_image_classifier.py \
--checkpoint_path=/tmp/tfmodel/model.ckpt-10000 \
--eval_dir=flower102/eval_dir \
--dataset_dir=flower102/data \
--dataset_name=flower102 \
--dataset_split_name=validation \
--model_name=inception_v3

验证结果如下:


验证.PNG

可以看出,准确率有83%,而top2的召回率有90%左右的成绩.

也可以使用tensorboard查看验证过程:


结果数值.PNG

网络.PNG

7.测试模型

7.1导出模型

tensorflow_slim提供了导出模型框架的脚本export_inference_graph.py,可以将模型框架导出,在通过使用freeze_graph.py将训练好的参数值导入到模型中去.

step 1

输出框架

python export_inference_graph.py \
--alsologtosterr \
--model_name=inception_v3 \
--output_file=flower102/inception_v3_inf_graph.pb \
--dataset_name flower102

step 2

注入参数数据
进入freeze_graph.py所在文件目录,输入:

python freeze_graph.py \
--input_graph slim/flower102/inception_v3_inf_graph.pb \
--input_checkpoint flower102\train_dir/model.ckpt-100000 \
--input_binary true \
--output_node_names InceptionV3/Predictions/Reshape_1 \
--output_graph slim/flower102/frozen_graph.pb
生成测试模型.PNG

经过这两步之后,带有参数值的模型就构造好了,接下来就可以使用这个模型进行测试工作:
运行根目录下的classify_image_incepetion_v3.py,并对以下输入参数进行修改,更正为自己所使用的测试图片与模型名称:

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--model_path',#模型的路径,使用填充数据的模型框架
      default='slim/flower102/frozen_graph.pb',
      type=str,
  )
  parser.add_argument(
      '--label_path',#label地址,在生成tfrecord文件过程中自动生成了label.txt,制定为其地址.
      default='slim/flower102/data/label.txt',
      type=str,
  )
  parser.add_argument(
      '--image_file',#测试图片的地址,这里使用了相对地址
      type=str,
      default='image_07111.jpg',
      help='Absolute path to image file.'
  )
  parser.add_argument(
      '--num_top_predictions',#给出top n的可能结果
      type=int,
      default=5,
      help='Display this many predictions.'
  )

以下为验证的结果截图:
测试image_07111.jpg这张图片,结果如下:


测试.PNG

可以看出C9的概率最高,对比该图片与C9类,可见结果正确.


验证结果.PNG
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352