在 Object Detection API 的示例代码中包含了一个训练识别宠物的 Demo,包括数据集和相应的一些代码。虽然本课程中我们会自己准备数据和脚本来进行训练,但是在这之前还需要安装一些库、配置一下环境。在配置完成之后,运行一下这个训练宠物的 Demo,以便检查环境配置是否 OK,同时对训练过程先有个整体的了解,然后再准备自己的数据和训练脚本。
请确保已经安装好了 Python 2.7。
首先下载 Object Detection API 的代码:
git clone https://github.com/tensorflow/models.git
然后安装 TensorFlow(本课程使用 tensorflow 1.3.0):
sudo pip install tensorflow==1.3.0
接着是一些依赖库:
sudo pip install pillow
sudo pip install lxml
sudo pip install jupyter
sudo pip install matplotlib
Object Detection API 中的模型和训练参数是使用 protobuf 来序列化和反序列化的,所以在运行之前需要将相应的 protobuf 文件编译出来。
#进入 tensorflow/models/research/protoc object_detection/protos/*.proto --python_out=.
成功编译以后可以在 object_detection/protos/
下找到生成 .py 和 .pyc 文件。
接下来将 Object Detection API 的库加入到 PYTHONPATH 中:
#进入 tensorflow/models/research/export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
运行 Object Detection API 的脚本,以及之后自己写的脚本都会用到这些库,如果不想每次运行前都敲这个命令的话,可以把这条命令加入到 ~/.bashrc 中(需要将 pwd 展开为实际路径)。
最后运行一下测试脚本来检测安装是否正确:
#进入 tensorflow/models/research/python object_detection/builders/model_builder_test.py
如果看到下面的输出,那么 Object Detection API 的安装就完成了。
数据集由图片和相应的标注文件组成:
wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz
wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz
tar -xvf annotations.tar.gz
tar -xvf images.tar.gz
完成以后目录应该看起来是这样的:
images:
annotations:
在 images 目录就是一些宠物的照片,而在 annotations 文件夹里面是对相应照片的标注,在 annotations 文件夹中的和 images 文件夹中照片文件名一致的 xml 文件就是标注文件,这些标注文件为 PASCAL VOC 格式,可以打开 Abyssinian_1.xml
看一下:
标注内容主要为图片的源信息,如高和宽、物体的名称及所在位置:(xmin、ymin、xmax、ymax)所标识的矩形框。
还记得需要一个物体类别的数字编号和物体类别实际名称的对应关系的文件吗?可以在这里找到:
object_detection/data/pet_label_map.pbtxt
文件内容看起来是这样的:
注意:所有物体类别的数字编号都是从 1 开始的,因为 0 是一个在数学计算中很特殊的值。
Object Detection API 的训练框架使用 TFRecord 格式的文件作为输入。所以这里需要将图片和标注转换为 TFRecord 格式的文件。
TFRecord 数据文件是一种将图像数据和标签统一存储的二进制文件,能更好的利用内存,在 TensorFlow 中快速的复制、移动、读取、存储等。
Demo 里面包含了生成对应 TFRecord 格式文件的脚本,运行:
# 进入 tensorflow/models/research/
python object_detection/create_pet_tf_record.py \--label_map_path=object_detection/data/pet_label_map.pbtxt \--data_dir=DATA_DIR \--output_dir=DATA_DIR
这里需要将 DATA_DIR
替换为 images 和 annotations 所在的文件夹(父文件夹),不出意外的话,生成的文件应该看起像这样:
pet_train.record
为训练集,pet_val.record
为测试集。
还需要一个 Pre-trained 模型来进行转移学习,尽量的缩短学习的时间,在这里仍然选择上一节课中使用的 ssd_mobilenet_v1_coco
。
下载以后解压备用:
在转移学习中要用的文件是 model.ckpt.* 这三个文件。
还需要一个配置文件来对训练的流程进行配置,如使用什么算法,选用什么优化器等。在 object_detection/samples/configs/
可以找到很多配置模板,在这里使用 object_detection/samples/configs/ssd_mobilenet_v1_pets.config
作为起始的配置文件,需要在这个模板上面稍作修改。
这个配置文件是一个 JSON 格式的文件,里面有很多配置项,先挑一些必须修改的或者重要的项目:
train_input_reader: {
tf_record_input_reader {
input_path: "PATH_OF_TRAIN_TFRECORD"
}
label_map_path: "PATH_OF_LABEL_MAP"
}
需要将PATH_OF_TRAIN_TFRECORD
替换为pet_train.record
的绝对路径,将PATH_OF_LABEL_MAP
替换为pet_label_map.pbtxt
的绝对路径:
eval_input_reader: {
tf_record_input_reader {
input_path: "PATH_OF_VAL_TFRECORD"
}
label_map_path: "PATH_OF_LABEL_MAP"
}
需要将PATH_OF_VAL_TFRECORD
替换为pet_val.record
的绝对路径,将PATH_OF_LABEL_MAP
替换为pet_label_map.pbtxt
的绝对路径:
train_config: { fine_tune_checkpoint: "CHECK_POINT_PATH"
from_detection_checkpoint: true
num_steps: 200000
}
如果将from_detection_checkpoint
设为true
的话,代表将从一个事先训练好的模型开始继续训练(转移学习),此时需要将CHECK_POINT_PATH
替换为 model.ckpt 的绝对路径(注意之前有三个文件,model.ckpt.index、model.ckpt.meta、model.ckpt.data-xxx
在配置时不需要加model.ckpt
之后的后缀),如:fine_tune_checkpoint: "/root/ssd_mobilenet_v1_coco_11_06_2017/model.ckpt"
num_steps 为训练迭代的步数,这里暂时不修改。
将改好以后的配置文件重命名为 pipeline.config
。
准备好训练数据和配置文件以后,就可以开始进行训练了。通常会把训练会用到的文件放到一起(训练目录),这里建议把训练目录设置为这样:
注意:需要按照这个目录结构修改 pipeline.config 中的相应项。
然后执行训练脚本:
# 进入 tensorflow/models/research/
python object_detection/train.py \
--logtostderr \
--pipeline_config_path=${TRAIN_DIR}/model/pipeline.config} \
--train_dir=${TRAIN_DIR}/model/train
TRAIN_DIR
需要替换为训练目录的绝对路径。
如果不出意外的话,会听到 CPU 的风扇声开始响起来,电脑变得有点卡,同时可以在终端上看到以下输出:
每一行输出为:训练迭代步数/当前损失值/每步训练所花时间。
基本上可以看出,随着训练的进行,每一步的损失值是下降的,那是不是可以喝咖啡等待训练结束了呢?
不过,每一步执行的时间大概在 10 秒左右,那么按照我们的配置 200000 步需要 200000 X 10 秒 = 23 天左右,这显然是不能接受的。
看来用笔记本的 CPU 进行训练可能不是一个好主意,需要更强的计算力:GPU。
配置好了训练环境,也把一个训练 Demo 运行了起来,但是笔记本的 CPU 运算能力显然不足应付这个任务,那么接下来让我们在 GPU 上面运行训练。