其他分享
首页 > 其他分享> > 打造自己的图像识别模型

打造自己的图像识别模型

作者:互联网

1.目标

本篇文章介绍的重点是如何使用TensorFlow在自己的图像数据上训练深度学习模型,主要涉及的方法是对已经预训练好的ImageNet模型进行微调(Fine-tune)。使用谷歌的Colaboratory(python3 环境)实现。

2.微调原理

什么是微调?这里以VGG16为例进行讲解。

如图下图所示,VGG16的结构为卷积+全连接层。卷积层分为5个部分共13层,即图中的conv1~conv5。还有3层是全连接层,即图中的fc6、fe7、fc8。卷积层加上全连接层合起来一共为16层,因此它被称为VGG16。如果要将VGG16的结构用于一个新的数据集,首先要去掉fc8这一层。原因是fc8层的输入是fc7层的特征,输出是1000类的概率,这1000类正好对应了ImageNet 模型中的1000个类别。在自己的数据中,类别数一般不是1000类,因此fc8层的结构在此时是不适用的,必须将fc8层去掉,重新采用符合数据集类别数的全连接层,作为新的fe8。比如数据集为5类,那么新的fc8的输出也应当是5类。

此外,在训练的时候,网络的参数的初始值并不是随机化生成的,而是采用VGG16在ImageNet 上已经训练好的参数作为训练的初始值。这样做的原因在于,在ImageNet数据集上训练过的VGG16中的参数已经包含了大量有用的卷积过滤器,与其从零开始初始化VGG16的所有参数,不如使用已经训练好的参数当作训练的起点。这样做不仅可以节约大量训练时间,而且有助于分类器性能的提高。

载入VGG16的参数后,就可以开始训练了。此时需要指定训练层数的范围。一般来说,可以选择以下几种范围进行训练:

这种训练方法就是所谓的对神经网络模型做微调。借助微调,可以从预训练模型出发,将神经网络应用到自己的数据集上。下面介绍如何在TensorFlow中进行微调。

3.TensorFlow Slim 微调

TensorFlow Slim 是Google公司公布的一个图像分类工具包,它不仅定义了一些方便的接口,还提供了很多ImageNet数据集上常用的网络结构和预训练模型。截至2017年7月,Slim提供包括VGG16、VGG19、Inception V1~V4、ResNet 50、ResNet 101、MobileNet在内大多数常用模型的结构以及预训练模型,更多的模型还会被持续添加进来。

3.1 数据准备

首先要将自己的数据集切分为训练集和验证集,训练集用于训练模型,验证集用来验证模型的准确率。本次使用的是卫星图片分类数据集,这个数据集一共有6个类别,见下表所示:

类别名 含义
Wetland 农田
Glacier 冰川
Urban 城市区域
Rock 岩石
water 水域
Wood 森林

在data_prepare目录中,用一个pic文件夹保存原始的图像文件,图像文件保存的结构如下:

data prepare/
    pic/
        train/
            wood/
            water/
            rock/
            wetland/
            glacier/
            urban/
        validation/
            wood/
            water/
            rock/
            wetland/
            glacier/
            urban/

将图片分为trainvalidation两个目录,分别表示训练使用的图片和验证使用的图片。在每个目录中,分别以类别名为文件夹名保存所有图像。在每个类别文件夹下,存放的就是原始的图像(如jpg格式的图像文件)。下面,在data_prepare文件夹下,使用预先编制好的脚本data_convert.py,将图片转换为为tfrecord格式:

!python data_ convert.py -t pic/ \
    --train-shards 2 \
    --validation-shards 2 \
    --num-threads 2 \
    --dataset-name satellite

解释这里参数的含义:

运行上述命令后,就可以在pic文件夹中找到5个新生成的文件,分别是训练数据 satellite_train_00000-of-00002.tfrecord、satellite_train_00001-of-00002.tfrecord,以及验证数据 satellite validation_00000-of-00002.tfrecord、satellite validation_00001-of-00002.tfrecord。另外,还有一个文本文件label.txt,它表示图片的内部标签(数字)到真实类别(字符串)之间的映射顺序。如图片在tfrecord中的标签为0,那么就对应label.txt 第一行的类别,在tfrecord的标签为1,就对应label.txt中第二行的类别,依此类推。

3.2 下载TensorFlow Slim

如果需要使用Slim微调模型,首先要下载Slim的源代码。Slim的源代码保存在tensorflow/models项目中,可以使用下面的git命令下载tensorflow/models:

git clone https://github.com/tensorflow/models. git

找到models/research/目录中的slim文件夹,这就是要用到的TensorFlow Slim的源代码。这里简单介绍TensorFlow Slim的代码结构,见下表。

文件夹或文件名 用途
datasets/ 定义一些训练时使用的数据集。如果需要训练自己的数据,必须同样在datasets文件夹中进行定义,会在下面对此进行介绍
nets/ 定义了一些常用的网络结构,如AlexNet、VGGl6、VGG19、Inception 系列、ResNet、MobileNet等
preprocessing/ 在模型读入图片前,常常需要对图像做预处理和数据增强。这个文件夹针对不同的网络,分别定义了它们的预处理方法
scripts 包含了一些训练的示例脚本
train_ image_classifier.py 训练模型的入口代码
eval_image_classifier.py 验证模型性能的入口代码
download_and _convert data.py 下载并转换数据集格式的入口代码

上表只列出了TensorFlow Slim中最重要的几个文件以及文件夹的作用。其他还有少量文件和文件夹,如果读者对它们的作用感兴趣,可以自行参阅其文档。

3.3 定义新的datasets文件

在slim/datasets中,定义了所有可以使用的数据库,为了使用在第3.1节中创建的tfrecord数据进行训练,必须要在datasets中定义新的数据库。

首先,在datasets/目录下新建一个文件satellite.py,并将flowers.py文件中的内容复制到satellite.py中。接下来,需要修改以下几处内容。

第一处是_FILE_PATTERNSPLITS_TO_SIZES_NUM_CLASSES,将其进行以下修改:

_FILE_PATTERN='satellite _%s*. tfrecord'
SPLTTS_TO_SIZES={' train:4800,' validation':1200}
_NUM_CLASSES=6

_FILE_PATTERN 变量定义了数据的文件名的格式和训练集、验证集的数量。

_NUM_CLASSES 变量定义了数据集中图片的类别数目。

第二处修改为image/format部分,将之修改为:

'image/format': tf. FixedLenFeature((), tf. string, default_value ='jpg'),

此处定义了图片的默认格式。收集的卫星图片的格式为jpg图片,因此修改为jpg。最后,读者也可以对文件中的注释内容进行合适的修改。修改完satellite.py后,还需要在同目录的dataset_factory.py文件中注册satellite数据库。如下:

datasets_map={
'cifar10':cifarl0,
'flowers':flowers,
'imagenet':imagenet,
'satellite':satellite,}

3.4 准备训练文件夹

定义完数据集后,在slim文件夹下再新建一个satellite目录,在这个目录中,完成最后的几项准备工作:

3.5 开始训练

在slim文件夹下,运行以下命令就可以开始训练了:

!python train_image_classifier. py \
--train_dir=satellite/train_dir \
--dataset_name=satellite \
--dataset_split_name=train \
--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

这里的参数比较多,下面一一进行介绍:

以上命令是只训练未端层InceptionV3/Logits,InceptionV3/AuxLogits,还可以对所有层进行训练:与只训练末端层的命令相比,只有一处发生了变化,即去掉了--trainable_scopes参数。

3.6 验证模型准确率

在slim文件下执行下列命令:

!python eval_image_classifier.py  \
--checkpoint_path=satellite/train_dir  \
-eval_dir=satellite/eval_dir  \
--dataset_name=satellite  \
--dataset_split_name=validation  \
--dataset_dir=satellite/data  \
--model_name=inception_v3

这里参数的含义为:

执行后,应该会出现类似下面的结果:

eval/Accuracy[0.51]
eval/Recal1_5[0.97333336]

Accuracy 表示模型的分类准确率,而Recall_5表示Top5的准确率,如果不需要top5 。而需要top2或者top3准确率,只要在eval_image_classifier.py中修改下面的部分就可以了:

names_to_values, names_to_updates=slim. metrics. aggregate_metric map({
'Accuracy': slim. metrics. streaming_accuracy (predictions,labels),
'Recall_5': slim. metrics. streaming_recall_at_k(1ogits,labels,5),
})

4 代码及数据集

百度网盘 提取码:8qqt

标签:satellite,图像识别,训练,模型,train,打造,数据,dir
来源: https://www.cnblogs.com/Terrypython/p/10858803.html