零,学习目标
本文主要讲解如何训练自己的图像数据,主要从数据准备、训练模型、验证准确性、导出模型和图像分类。要点如下:
微调导出的模型并对图像进行分类一、微调
原则
对于初学者来说,在自己的数据集上训练模型的最简单方法是在自己的数据集上微调模型。什么是微调?以VGG16为例,其结构一共13层5部分卷积层(conv1~conv5)和3层全连接层(fc6~fc8),共16层)层,所以称为VGG16。
如果VGG16的结构用于一个新的数据集,应该去掉最后一层的全连接层,因为最后一个全连接层的输入是上一层的特征,输出是1000个类别的概率,对应于 中的1000个类别,但是这里,我们只有6个类别,所以我们需要去掉最后一个全连接层,使用更符合数据类别的全连接层。
此时网络参数的初始化值并不是随机生成的,而是将已经在VGG16上训练过的参数作为初始值进行训练。由于训练集上的 VGG16 已经包含了大量有用的卷积滤波器,使用现有的参数将很快节省时间,也有助于提高分类器的性能。
训练范围
加载参数后,我们可以指定训练层数的范围。训练层数可选范围如下:
只训练fc8层,保持其他层的参数不变,使用VGG16作为特征提取器,使用fc7层提出的特征进行分类,有利于提高训练速度,但性能不最好的;
训练所有参数,训练网络中的所有参数,性能提升,可以充分利用深度模型,但速度太慢;
训练一些参数,固定浅层参数不变,训练深层参数。
以上三种方法都是神经网络的微调。通过微调,神经网络可以通过模型应用于自己的数据集。
数据处理
我们首先将数据分为训练集和验证集,然后将图像转换为格式[注1]。将文件夹复制到项目的根目录。此文件夹包含所需的数据集和代码。 /pic/train目录是训练文件所在目录,/pic/目录是验证文件所在目录。两个目录分为6大类,分类不同,分别是:农田、冰川、市区、森林、水域和岩石。每个文件夹中存储的图片都是jpg格式的图片。
由于神经网络无法识别jpg格式的数据,所以需要将图像数据转换为格式的数据。切换到文件夹,在命令行输入如下命令进行格式转换:
python data_convert.py -t pic/ --train-shards 2 --validation-shards 2 --num-threads 2 --dataset-name satellite
解释以上参数的含义:
参数含义
-t 图片/
指定要转换的数据所在的文件夹。该文件夹下必须有训练目录和验证目录,每个目录按类别存储图像数据
–train-2
训练数据集分为两部分,也就是说,训练数据集在格式转换后会是两种格式的文件[注2]
–2
验证数据集分为两部分
–num-2
使用两个线程产生数据[注3]
——名称:
为转换后的数据集命名
运行命令后,pic文件夹中会出现5个新的数据文件,以_开头的训练数据文件和以_开头的验证数据文件,还包括一个label.txt文件,表示标签号图片取决于真实类别字符串的映射顺序。比如图片标签为0,则表示该类别是label.txt中的第一行类别。
注1:
文件下载地址:下载文件
注2:
如果训练数据集很大,可以将训练数据集分成多个数据块
注3:
线程数必须能被train-shars和-整除,使得每个线程中的数据块数相等
下载 Slim 源代码
下载 Slim 是一个提供的图像分类工具。提供图像分类、常用网络结构和预训练模型的接口。
使用git下载Slim源码:git clone htren ps://.corn//.git,Slim源码也在我提供的下载地址。只需将 Slim 文件夹复制到根目录即可。代码结构如下:文件名/文件夹名描述
/
训练需要用到的数据库,训练自己的数据时必须在这里定义自己的数据库
网/
常见的网络结构
/
针对不同的网络定义了不同的数据预处理方法
/
训练示例脚本
cer.py
训练模型入口
er.py
验证模型性能输入
_data.py
下载和转换数据和各种条目
定义
在 slim/ 目录中创建一个 .py 文件,并将 .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')
修改.py
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文件夹下新建目录,/data(训练和验证数据文件夹),/(保存训练日志和模型文件夹),/。创建目录后,需要完成以下任务:
将转换后的数据(包括label.txt)复制到/data文件夹中
下载V3模型,下载地址为:下载地址,解压后将.ckpt文件复制到/
培训计划
在slim文件夹中启动命令行,输入以下命令开始训练(代码需要在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
解释以上参数的含义:
参数说明
–=/,/
指定模型微调变量的范围。这里设置的意思是只微调了/和/变量,也就是fc8微调了。如果没有设置这个参数,所有的参数都会被训练。
–=/
将日志和模型文件保存在/目录()
–=,–=火车
指定训练数据集
–=/数据
训练数据集保存的位置
–=
使用的型号名称
–=//.ckpt
预训练模型的保存位置
–应对=/,/
恢复预训练模型时两层不恢复,因为模型的两层对应数据集的1000个类别,与当前数据集不一致,所以不恢复
p>
–
最大执行步数
–=32
每步的批次数
–=0.001
学习率
–type=固定
学习率是否降低,这里是固定的学习率
–=300
每300秒保存一次模型并保存到目录
–=2
每 2 秒保存一次日志
–=10
每 10 步在屏幕上打印训练信息
–=
指定优化器
–=0.00004
设置,即模型中所有参数的二次正则化超参数
注4:
开始训练时,如果训练文件夹(/)中没有保存的模型,会自动加载预训练好的模型,然后程序将初始模型保存在 中,命名为model.ckpt-0, 0表示 Step 0,之后每隔 300 秒保存一次模型。由于模型较大,所以只保留最新的 5 个模型。如果你中断程序重新运行,它会首先检查该模型是否存在于该文件夹中,如果存在,则现有的模型将开始训练。
验证模型
要检查模型的准确性,可以使用r.py来验证,在命令行输入如下命令:
让我们解释一下参数
参数说明
–=/
参数可以接收目录路径或文件路径。如果是目录路径,则会在该目录中查找最新型号
–=/
保存执行结果日志的目录
–=/数据
验证数据集保存位置
–=
使用的模型
执行后会打印以下内容:
eval/Accuracy[0.51]
eval/Recall_5[0.973333336]
表示模型的分类准确率,表示前5次的准确率
可视化和超参数选择
用于帮助设置模型的训练方式和超参数,在命令行输入以下参数:
tensorboard --logdir satellite/train_dir
您可以在 中查看损失变化曲线,损失变化曲线有助于调整参数。如果损失曲线比较大,不能收敛,可能是学习率过大,可以适当降低学习率。
现在执行以下操作:
在里面创建两个文件夹
存储仅微调 fc8 的模型并微调整个网络。通过调整参数将两个模型保存到新文件夹中,然后使用命令:
tensorboard --logdir satellite/train_dir
打开浏览器可以看到狂歌模型的损失曲线。上半部分是仅训练端的损失数,下半部分是训练所有层的损失函数。看损失函数可以看出,训练所有层比只训练末端要好。
二、到处建模,图片排序
模型训练完成后,将被部署。这里提供了两个文件,.py 和 .py。前者用于导出识别模型,后者用于识别单张图像。在 slim 文件夹中执行以下命令:
python export_inference_graph.py --alsologtostderr --model_name=inception_v3 --output_file=satellite/inception_v3_inf_graph.pb --dataset_name satellite
命令执行后,文件夹中会生成一个ph.pb文件,但该文件不包含训练得到的模型参数,需要使用.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
这里解释参数:
参数说明
–苗条//ph.pb
使用的网络结构文件(上一步导出的)
– slim///model.ckpt-5271
指定加载到网络结构中的参数
–真
网络结构文件是二进制还是文本格式
– //
是V3的最后一个输出层
–苗条//.pb
导出模型文件
开始识别下面的图像。从命令行执行脚本 .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
解释参数:
参数说明
–苗条//.pb
导入训练好的模型
-/pic/label.txt
将–的结果转换成对应的名字
–.jpg
要识别的图像
执行参数后,会输出每个类的概率。
三、总结
首先简要介绍微调神经网络的基本原理,然后详细介绍如何使用 Slim 微调预训练模型,包括数据准备、定义新文件、训练、验证、导出模型和测试单个图像等。
暂无评论内容