TF-Slim(tensorflow.contrib.slim)是TensorFlow的高层API,类似layers,主要可以用来快速的设计、评估模型,有着类似keras般的语法
Tensorflow models包含一个Slim的图像分类库,可以微调、训练、使用预训练模型来对图像进行分类,包含的主要CNN网络有:
- Inception V1/2/3/4
- Inception-ResNet-V2
- ResNet 50/101/152
- VGG 16/19
- MobileNet V1/2
- NASNet/PNASNet
项目地址: https://github.com/tensorflow/models/tree/master/research/slim
很简单,三部曲就可以:
文档已经写的很清楚了,照着做基本是没问题的,以下步骤来自文档教程:
- 安装TensorFlow (>1.0)
- 克隆models(https://github.com/tensorflow/models/)
官方提供四种数据集:
Flowers、CIFAR-10、MNIST、ImageNet-2012
前三个数据集数据量小,直接调用相关脚本自动会完成下载、转换(TFRecord格式)的过程,类似:
DATA_DIR=/tmp/data/flowers
python download_and_convert_data.py \
--dataset_name=flowers \
--dataset_dir="${DATA_DIR}"
其会自动完成Flower数据集的准备工作. 比较特殊的是ImageNet数据集,官方也提供了教程,做下来发现还是有问题,后续提供解决方案
可以从头开始训练(比如使用ImageNet)、加载预训练模型直接分类、网络微调三种. 官方直接提供脚本,很方便:
DATASET_DIR=/tmp/flowers
TRAIN_DIR=/tmp/flowers-models/inception_v3
CHECKPOINT_PATH=/tmp/my_checkpoints/inception_v3.ckpt
python train_image_classifier.py \
--train_dir=${TRAIN_DIR} \
--dataset_dir=${DATASET_DIR} \
--dataset_name=flowers \
--dataset_split_name=train \
--model_name=inception_v3 \
--checkpoint_path=${CHECKPOINT_PATH} \
--checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \
--trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits
以参数形式指定,很清晰
从以上步骤来看,其实自动化程度已经很高了,按照教程指导问题应该不大,也并不是这篇博文的重点. 最近需要在ImageNet上训练一个Inception-ResNet-V2的变形版本,短平快的做法就是使用TF-Slim,在制作ImageNet数据集的时候按照官方指导出了问题,特此给出可行的解决方案,我的环境是Ubuntu 14.04 + CUDA8 + TF 1.0.1 + Python 2.7.
官方原版教程步骤:
- bazel编译相关脚本
- 直接执行download_and_preprocess_imagenet程序
看起来很简单,其实有坑,两点:
1. bazel编译失败(不知是否是环境问题)
2. ImageNet下载超慢(100多个GB的数据)
所以,比较可行的方法是,自己下载ImageNet-2012,然后来进行转换(TFRecord). 看看代码吧,找找问题,发现涉及如下三个脚本:
datasets/preprocess_imagenet_validation_data.py
,处理val的数据datasets/process_bounding_boxes.py
,处理boundingbox数据datasets/build_imagenet_data.py
, 构建数据集主程序
进代码看看,首先是preprocess_imagenet_validation_data.py
:
就是转换下格式,图片归类存放(后续需要)
之后是process_bounding_boxes.py
:
将bounding box的坐标获得写成csv文件(后续需要合并成一个文件)
到主程序build_imagenet_data.py
:
可以看到,训练集和验证集需要按照1000个子目录下包含图片的格式,现在基本就很明确处理步骤了:
再说具体点:
原始的ImageNet-2012下载下来包含三个文件:
- ILSVRC2012_bbox_train_v2.tar.gz
- ILSVRC2012_img_val.tar
- ILSVRC2012_img_train.tar
test的数据不公开,此处不包含test的数据.
bbox就是bounding box数据,另外两个是train 和 val 的数据(全是JPEG图片)
可以使用我的脚本一步完成:
假设数据存放在models/research/slim/ImageNet-ori
目录下,TFRecord文件的输出目录是models/research/slim/ILSVRC2012/output
,当前目录是models/research/slim
# 创建相关目录
mkdir -p ILSVRC2012
mkdir -p ILSVRC2012/raw-data
mkdir -p ILSVRC2012/raw-data/imagenet-data
mkdir -p ILSVRC2012/raw-data/imagenet-data/bounding_boxes
# 做bounding box数据
tar -xvf ImageNet-ori/ILSVRC2012_bbox_train_v2.tar.gz -C ILSVRC2012/raw-data/imagenet-data/bounding_boxes/
python process_bounding_boxes.py ILSVRC2012/raw-data/imagenet-data/bounding_boxes/ imagenet_lsvrc_2015_synsets.txt | sort > ILSVRC2012/raw-data/imagenet_2012_bounding_boxes.csv
# 做验证集(解压时间久)
mkdir -p ILSVRC2012/raw-data/imagenet-data/validation/
tar xf ILSVRC2012_img_val.tar -C ILSVRC2012/raw-data/imagenet-data/validation/
python preprocess_imagenet_validation_data.py ILSVRC2012/raw-data/imagenet-data/validation/ imagenet_2012_validation_synset_labels.txt
# 做训练集(解压时间更久,保持耐心!)
mkdir -p ILSVRC2012/raw-data/imagenet-data/train/
mv ImageNet-ori/ILSVRC2012_img_train.tar ILSVRC2012/raw-data/imagenet-data/train/ && cd ILSVRC2012/raw-data/imagenet-data/train/
tar -xvf ILSVRC2012_img_train.tar && mv ILSVRC2012_img_train.tar ../../../ImageNet-ori/
find . -name "*.tar" | while read NAE ; do mkdir -p "${NAE%.tar}"; tar -xvf "${NAE}" -C "${NAE%.tar}"; rm -f "${NAE}"; done
# 执行准换
python build_imagenet_data.py --train_directory=ILSVRC2012/raw-data/imagenet-data/train --validation_directory=ILSVRC2012/raw-data/imagenet-data/validation --output_directory=ILSVRC2012/output --imagenet_metadata_file=imagenet_metadata.txt --labels_file=imagenet_lsvrc_2015_synsets.txt --bounding_box_file=ILSVRC2012/raw-data/imagenet_2012_bounding_boxes.csv
相关目录都是可改的,注意下路径就行了,我本机测试没问题.
参考博客
用tensorflow训练imagenet数据准备