前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TensorFlow学习笔记--自定义图像识别

TensorFlow学习笔记--自定义图像识别

作者头像
喵叔
发布2020-09-08 16:04:35
7070
发布2020-09-08 16:04:35
举报
文章被收录于专栏:喵叔's 专栏喵叔's 专栏
零、学习目标

本篇文章主要讲解自己的图像数据如何在TnesorFlow上训练,主要从数据准备、训练模型、验证准确率和导出模型并对图片分类。重点如下:

  1. 微调
  2. 导出模型并对图片分类
一、微调
  1. 原理 对于新手来说,在自己的数据集上训练一个模型时,最简单的方法是在ImageNet的模型上进行微调。什么是微调呢?以VGG16为例,它的结构为5部分卷积层共13层(conv1 ~ conv5)和3层的全连接层(fc6 ~ fc8),一共16层,因此被称为VGG16。 如果将VGG16的结构用于一个新的数据集,就要去掉最后一层的全连接层,因为最后一层全连接层的输入是前一层的特征,输出的是1000类的概率,正好对应了ImageNet中的1000个类别,但是在这里,我们的类别只有6种,所以要去掉最后一层全连接层,采用一个更符合数据类别的全连接层。 这时,网络参数的初始化值就不是随机生成的了,而是利用VGG16在ImageNet上已经训练好的参数作为训练的初始值。因为ImageNet训练集上的VGG16已经包含了大量有用的卷积过滤器,使用已存在的参数不久节约时间,也有助于提高分类器的性能。
  2. 训练范围 在载入参数后,我们可以指定训练层数范围,训练层数可选范围如下:
  3. 只训练fc8这一层,保持其他层的参数不变,将VGG16作为一个特征提取器,用fc7层提起的特征做Softmax分类,这样做有利提高训练速度,但是性能不是最佳的;
  4. 训练所有参数,对网络中的所有参数都进行训练,性能得以提高,深度模型得以充分发挥,但是速度太慢;
  5. 训练部分参数,固定浅层参数不变,训练深层参数。

以上这三种方法就是神经网络的微调,通过微调可以将神经网络通过以有模型应用到自己的数据集上。

  1. 数据处理 我们首先将数据分为训练集和验证集,之后将图片转化为tfrecord格式【注1】。将文件夹 data_preoare 复制到项目的根部录下。这个文件夹中由所需的数据集和代码。data_preoare/pic/train 目录是训练文件所在的目录,data_preoare/pic/validation 目录是验证文件所在的目录。两个目录下又以不同分类划分了6种类别,分别为:农田、冰川、城市地区、森林、水域和岩石,每个文件夹中存放的图片为jpg格式的图片。 由于神经网络无法识别jpg格式的数据,所以需要将图片数据转为tfrecord格式的数据。 切换到 data_preoare 文件夹下,在命令行输入如下命令进行格式转换:
代码语言:javascript
复制
python data_convert.py -t pic/ --train-shards 2 --validation-shards 2 --num-threads 2 --dataset-name satellite

解释一下上面参数的含义:

参数

含义

-t pic/

指定要转换的数据所在的文件夹,这个文件夹下必须有一个训练目录和一个验证目录,并且每个目录按类别存放图片数据

–train-shards 2

将训练数据集分为两块,也就是说转换完格式后训练数据集将会是两个tfrecord格式的文件【注2】

–validation-shards 2

将验证数据集分为两块

–num-threads 2

采用两个线程生产数据【注3】

–dataset-name:satellite

给转换后的数据集起一个名字

运行命令后,pic文件夹下会出现五个新的数据文件,以 satellite_train_ 开头的训练据文件和以 satellite_validation_ 开头的验证数据文件,并且还包含一个label.txt文件,表示图片的标签数字到真实类别字符串的映射顺序。例如tfrecod中图片标签为0,就代表类别为label.txt中的第一行类别。

注1: 文件下载地址:下载文件

注2: 如果训练数据集较大,则可以将训练数据集划分为多个数据块

注3: 线程数量必须能整除train-shars和validation-shards,这样才能抱枕每个线程中数据块的数量相等

  1. 下载TensorFlow Slim 源代码 下载TensorFlow Slim 是Google提供的图像分类工具。里面提供了图像分类的接口、常用的网络结构和预训练模型。 利用git下载Slim源码:git clone ht仁ps://github.corn/tensorflow/models.git,我所提供的下载地址中也有Slim源码。将 Slim 文件夹复制到根目录下即可。代码结构如下:

文件名/文件夹名

说明

datasets/

训练时需要用到的数据库,训练自己的数据时必须在这里进行定义自己的数据库

nets/

常用的网络结构

preprocessing/

针对不同网络定义了不同的预处理数据的方法

scripts/

训练示例脚本

train_image_classificer.py

训练模型入口

eval_image_classificer.py

验证模型性能入口

download_and_convert_data.py

下载并转换数据及各式入口

  1. 定义dataset 在 slim/datasets 目录下创建 satellite.py 文件,将 flowers.py 文件中的内容复制进去。修改部分代码:
  2. _FILE_PATTERN、SPLITS_TO_SIZE、_NUM_CLASSES
代码语言:javascript
复制
# 数据的文件名
_FILE_PATTERN = 'satellite_%s_*.tfrecord'
# 训练集和验证集的数量
SPLITS_TO_SIZE = {'train':4800,'validation':1200}
# 数据集中图片的类别数目
_NUM_CLASSES = 6
  1. image/format
代码语言:javascript
复制
# 设定图片格式
'image/format' : tf.FixedLenFeature((),tf.string,default_value = 'jpg')
  1. 修改dataset_factory.py
代码语言:javascript
复制
from datasets import cifar10
from datasets import flowers
from datasets import imagenet
from datasets import mnist
# 将satellite模块添加进来
from datasets import satellite

# satellite 数据库加入进来
datasets_map = {
  'cifar10':cifar10,
  'flowers':flowers,
  'imagenet':imagenet,
  'mnist':mnist,
  'satellite':satellite
}
  1. 准备训练文件夹 在slim文件夹下新建 satellite 目录、satellite/data(训练和验证数据文件夹)、satellite/train_dir(保存训练日志和模型文件夹)、satellite/pretrained。创建完目录后需要完成以下工作:
  2. 将转换好格式的数据(包括label.txt)复制 satellite/data 文件夹
  3. 下载Inception V3模型,下载地址是:下载地址,解压后,将inception_v3.ckpt文件复制到 satellite/pretrained
  4. 训练程序 在slim文件夹下启动命令行,输入如下命令开始训练(代码需要在TensorFlow GPU版本上运行):
代码语言:javascript
复制
python train_image_classifier.py --train_dir=satellite/train_dir --dataset_name=satellite --dataset_split_name=train --dataset_dir=satellite/data --model_name=inception_v3 --checkpoint_path=satellite/pretrained/inception_v3.ckpt --checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits --trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits --max_number_of_steps=100000 --batch_size=32 --learning_rate=0.001 --learning_rate_decay_type=fixed --save_interval_secs=300 --save_summaries_secs=2 --log_every_n_steps=10 --optimizer=rmsprop --weight_decay=0.00004

解释一下上面参数的含义:

参数

说明

–trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits

指定模型微调变量的范围。这里指设定表示只对 InceptionV3/Logits 和 InceptionV3/AuxLogits 两个变量微调,也就是对fc8进行微调,如果不设置此参数,将会对所有参数进行训练。

–train_dir=satellite/train_dir

在 satellite/train_dir 目录下保存日志和模型文件(heckpoint)

–dataset_name=satellite、–datasets_split_name=train

指定训练数据集

–dataset_dir=satellite/data

训练数据集保存的位置

–model_name=inception_v3

使用的模型名称

–checkpoint_path=satellite/pretrained/inception_v3.ckpt

预训练模型保存的位置

–checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits

恢复预训练模型时不回复这两层,因为这两层模型对应着ImageNet数据集的1000类,与当前数据集不符,所以不要恢复他

–max_number_of_steps 100000

最大执行步数

–batch_size=32

每步的batch数量

–learning_rate=0.001

学习率

–learning_rate_decay_type=fixed

学习率是否下降,此处固定学习率

–save_interval_secs=300

每隔300秒保存一次模型,保存到train_dir目录下

–save_summaries_secs=2

每隔2秒保存一次日志

–log_every_n_steps=10

每隔10步在屏幕上打印出训练信息

–optimizer=rmsprop

指定优化器

–weight_decay=0.00004

设定weight_decay,即模型中所有参数的二次正则化超参数

注4: 开始训练时,如果训练文件夹(satellite/train_dir)里没有保存的模型,就会自动加载 checkpoint_path 中的预训练模型,然后程序会把初始模型保存在train_dir中,命名为 model.ckpt-0,0表示第0步。之后每隔300秒就会保存一次模型,由于模型较大,所以只会保留最新的5个模型。如果中断程序运行后再次运行,会首先检查train_dir文件夹中是否存在模型,如果存在则接着存在的模型开始训练。

  1. 验证模型 要查看模型的准确率,可以使用 eval_image_classifier.py 来验证,在命令行输入如下命令:
代码语言:javascript
复制
python eval_image_classifier.py --checkpoint_path=satellite/train_dir --eval_dir=statellite/eval_dir --dataset_name=satellite --dataset_split_name=validation --dataset_dir=satellite/data --model_name=inception_v3

下面来解释一下参数

参数

说明

–checkpoint_path=satellite/train_dir

参数可以接收目录路径或者文件路径。如果是一个目录路径,则会查找这个目录下最新的模型

–eval_dir=satellite/eval_dir

执行结果日志的保存目录

–dataset_dir=satellite/data

验证数据集保存位置

–model_name=inception_v3

使用的模型

执行后会打印出如下内容:

代码语言:javascript
复制
eval/Accuracy[0.51]
eval/Recall_5[0.973333336]

Accuracy表示模型的分类准确率,Recall_5表示前5次的准确率

  1. TensorBoard 可视化与超参数选择 使用TnesorBoard 有助于设定训练模型的方式以及超参数,命令行输入如下参数:
代码语言:javascript
复制
tensorboard --logdir satellite/train_dir

在TensorBoard中可以查看损失变化曲线,损失变化曲线有助于调整参数。如果损失曲线比动较大,无法收敛,就有可能时学习率过大,适当减小学习率就行了。 现在做如下操作:

  1. train_dir 中建立两个文件夹,分别存放只微调fc8和微调整个网络的模型。通过调整 train_dir 参数将这两种模型分别存入新建的文件夹中,之后使用命令:
代码语言:javascript
复制
tensorboard --logdir satellite/train_dir

浏览器打开TensorBoard就可以看到狂歌模型的损失曲线,上方的为只训练末端的损失数,下方为训练所有层的损失函数。看损失函数可以看出训练所有层比只训练末端要好。

二、到处模型并分类图片

模型训练完之后,将会进行部署。这里提供了两个文件 freeze_graph.pyclassify_image_inception_v3.py 前者用于导出识别模型,后者用于识别单张图片。在slim文件夹下执行如下命令:

代码语言:javascript
复制
python export_inference_graph.py --alsologtostderr --model_name=inception_v3 --output_file=satellite/inception_v3_inf_graph.pb --dataset_name satellite

命令执行后,会在satellite文件夹下生成一个 inception_v3_inf_graph.pb 文件,但是这个文件不包含训练获得的模型参数,需要将cheeckpoint中的模型参数保存进来,方法是使用freeze_graph.py:

代码语言:javascript
复制
python freeze_graph.py --input_graph slim/satellite/inception_v3export_inference_graph.pb --input_checkpoint slim/satellite/train_dir/model.ckpt-5271 --input_binary true --output_node_names InceptionV3/Predictions/Reshape_1 --output_graph slim/satellite/frozen_graph.pb

这里讲解一下参数:

参数

说明

–input_graph slim/satellite/inception_v3_inf_graph.pb

使用的网络结构文件(前一步已经导出)

–input_checkpoint slim/satellite/train_dir/model.ckpt-5271

指定载入到网络结构中的checkpoint参数

–input_binary true

使用网络结构文件是二进制还是文本形式

–output_node_names InceptionV3/Predictions/Reshape_1

是Inception V3最后的输出层

–output_graph slim/satellite/frozen_graph.pb

导出模型的文件

下面开始对图片进行识别。命令行执行脚本 classify_image_inception_v3.py ,运行如下命令:

代码语言:javascript
复制
python classify_image_inception_v3.py --model_path slim/statellite/frozen_graph.pb --label_path data_preoare/pic/label.txt --image_file test_image.jpg

讲解参数:

参数

说明

–model_path slim/statellite/frozen_graph.pb

导入训练好的模型

–label_path data_preoare/pic/label.txt

将–model_path输出的结果转换为对应的名称

–image_file test_image.jpg

要识别的图片

执行完参数后,将输出每种类别的概率。

三、总结

首先简要介绍了微调神经网络的基本原理,接着详细介绍了如何使用 TensorFlow Slim 微调预训练模型,包括数据准备、定义新的 datasets 文件、训练、 验证 、 导出模型井测试单张图片等。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 零、学习目标
  • 一、微调
  • 二、到处模型并分类图片
  • 三、总结
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档