本篇文章主要讲解本身的图像数据如何在TnesorFlow上训练,主要从数据准备、训练模型、验证准确率和导出模型并对图片分类。重点以下:node
原理
对于新手来讲,在本身的数据集上训练一个模型时,最简单的方法是在ImageNet的模型上进行微调。什么是微调呢?以VGG16为例,它的结构为5部分卷积层共13层(conv1 ~ conv5)和3层的全链接层(fc6 ~ fc8),一共16层,所以被称为VGG16。
若是将VGG16的结构用于一个新的数据集,就要去掉最后一层的全链接层,由于最后一层全链接层的输入是前一层的特征,输出的是1000类的几率,正好对应了ImageNet中的1000个类别,可是在这里,咱们的类别只有6种,因此要去掉最后一层全链接层,采用一个更符合数据类别的全链接层。
这时,网络参数的初始化值就不是随机生成的了,而是利用VGG16在ImageNet上已经训练好的参数做为训练的初始值。由于ImageNet训练集上的VGG16已经包含了大量有用的卷积过滤器,使用已存在的参数不久节约时间,也有助于提升分类器的性能。python
训练范围
在载入参数后,咱们能够指定训练层数范围,训练层数可选范围以下:git
只训练fc8这一层,保持其余层的参数不变,将VGG16做为一个特征提取器,用fc7层提起的特征作Softmax分类,这样作有利提升训练速度,可是性能不是最佳的;github
训练全部参数,对网络中的全部参数都进行训练,性能得以提升,深度模型得以充分发挥,可是速度太慢;web
训练部分参数,固定浅层参数不变,训练深层参数。shell
以上这三种方法就是神经网络的微调,经过微调能够将神经网络经过以有模型应用到本身的数据集上。数据库
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:
文件下载地址:下载文件svg
注2:
若是训练数据集较大,则能够将训练数据集划分为多个数据块
注3:
线程数量必须能整除train-shars和validation-shards,这样才能抱枕每一个线程中数据块的数量相等
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 | 下载并转换数据及各式入口 |
# 数据的文件名 _FILE_PATTERN = 'satellite_%s_*.tfrecord' # 训练集和验证集的数量 SPLITS_TO_SIZE = {'train':4800,'validation':1200} # 数据集中图片的类别数目 _NUM_CLASSES = 6
# 设定图片格式 'image/format' : tf.FixedLenFeature((),tf.string,default_value = 'jpg')
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 }
准备训练文件夹
在slim文件夹下新建 satellite 目录、satellite/data(训练和验证数据文件夹)、satellite/train_dir(保存训练日志和模型文件夹)、satellite/pretrained。建立完目录后须要完成如下工做:
将转换好格式的数据(包括label.txt)复制 satellite/data 文件夹
下载Inception V3模型,下载地址是:下载地址,解压后,将inception_v3.ckpt文件复制到 satellite/pretrained
训练程序
在slim文件夹下启动命令行,输入以下命令开始训练(代码须要在TensorFlow GPU版本上运行):
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文件夹中是否存在模型,若是存在则接着存在的模型开始训练。
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 | 使用的模型 |
执行后会打印出以下内容:
eval/Accuracy[0.51] eval/Recall_5[0.973333336]
Accuracy表示模型的分类准确率,Recall_5表示前5次的准确率
tensorboard --logdir satellite/train_dir
在TensorBoard中能够查看损失变化曲线,损失变化曲线有助于调整参数。若是损失曲线比动较大,没法收敛,就有可能时学习率过大,适当减少学习率就好了。
如今作以下操做:
tensorboard --logdir satellite/train_dir
浏览器打开TensorBoard就能够看到狂歌模型的损失曲线,上方的为只训练末端的损失数,下方为训练全部层的损失函数。看损失函数能够看出训练全部层比只训练末端要好。
模型训练完以后,将会进行部署。这里提供了两个文件 freeze_graph.py 和 classify_image_inception_v3.py 前者用于导出识别模型,后者用于识别单张图片。在slim文件夹下执行以下命令:
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:
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 ,运行以下命令:
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 文件、训练、 验证 、 导出模型井测试单张图片等。