用TensorFlow训练一个目标检测器(手把手教学版)

用TensorFlow训练一个目标检测器(手把手教学版)

向AI转型的程序员都关注了这个号????????????

大数据挖掘DT机器学习  公众号: datayx

TensorFlow内包含了一个强大的物体检测API,我们可以利用这API来训练自己的数据集实现特殊的目标检测。

用TensorFlow训练一个目标检测器(手把手教学版)

国外一位程序员分享了自己实现可爱的浣熊检测器的经历

原文地址(需要翻越那道墙):https://towardsdatascience.com/how-to-train-your-own-object-detector-with-tensorflows-object-detector-api-bec72ecfe1d9

原文作者的github:(作者的数据集可以在这里下载)

关注微信公众号 datayx  然后回复 目标检测  即可获取。

在文章中作者把检测器的训练流程进行了简要介绍,但过于粗略,初学者难以跟着实现。为了方便初学者,我把详细的步骤整理了一下,下面我们一起来学习一下吧!

这篇文章主要还是学习训练目标检测,本文以检测浣熊为例,其实也可以用自己的数据集,检测其他的目标,比如 检测海上船只,检测天空的飞机,检测小猫小狗等等。

用TensorFlow训练一个目标检测器(手把手教学版)

为什么要做这件事?

方便面君不仅可爱,在国外很普遍的与人们平静地生活在一起。处于对它的喜爱和与浣熊为邻的情况,作者选择了它作为检测器的检测对象。完成后可以将摄像安装在房子周围,检测是否有浣熊闯入了你家,你就能及时知道是否来了不速之客了。看来浣熊还真多啊!

用TensorFlow训练一个目标检测器(手把手教学版)


一、创建数据集

机器学习需要数据作为原料,那么我们首先需要做的就是建立起一个可供训练的数据集,同时我们需要利用符合Tensorflow的数据格式来保存这些数据及其标签。

1.在准备输入数据之前你需要考虑两件事情:其一,你需要一些浣熊的彩色图片;其二,你需要在图中浣熊的位置框坐标(xmin,ymin,xmax,ymax)来定位浣熊的位置并进行分类。对于只检测一种物体来说我们的任务十分简单,只需要定义一类就可以了;

2.哪里去找数据呢?互联网是最大的资源啦。包括各大搜索引擎的图片搜索和图像网站,寻找一些不同尺度、位姿、光照下的图片。作者找了大概两百张的浣熊图片来训练自己的检测器(数据量有点小,但是来练手还是可以的,其实imagenet上有浣熊的数据集的,有心的朋友可以去下载,注册imagenet是需要翻越高墙的,否则看不到验证码);

用TensorFlow训练一个目标检测器(手把手教学版)

3.有了数据以后我们需要给他们打标签。分类很简单,都是浣熊,但是我们需要手动在每一张图中框出浣熊的位置。一个比较好的打标工具是LabelImg, 

https://github.com/tzutalin/labelImg

关于图片打标注,请参考另一篇文章《手把手教你图片打标注

http://blog.****.net/chenmaolin88/article/details/79357502

4、到目前为止,我们有了一些浣熊的图片以及这些图片的标注文件(annotation)(如果你比较懒,可以从原文作者的GITHUB里下载这些图片和标注文件, 这里我就直接下载原文作者的标注文件和图片

用TensorFlow训练一个目标检测器(手把手教学版)

5、我们把下载好的ZIP包解压,如下,annotations目录就是标注文件,images目录就是图像文件,标注文件raccoon-1.xml里的filename节点就是它对应的图片文件的文件名,需要特别说明的是,raccoon这个数据集里面的标注文件xml里的filename是png后缀,而实际我们下载到的图片是是jpg格式的,估计是原作者转换了格式,因此,在后文中,我们需要对这个filename做一点小处理。解压出来的其他文件我们都不需要,全部删掉,后面我们会一步步自己写出那些文件的。

用TensorFlow训练一个目标检测器(手把手教学版)

6.最后,将图片及图像的标签转换为TFRecord格式,并将起分为训练集和验证集就可以开始下一步的工作了!用LabelImg标注的文件是PASCAL VOC格式的,tensorflow提供了一个脚本将PASCAL VOC格式的标注文件和相应的图片转换为TFRecord,不过,要用这个脚本,我们需要先搭建TensorFlow环境以及安装TensorFlow object detection api ,关于这两个部分,请参阅我的系列文章《Ubuntu 16.04下搭建TensorFlow运行环境(用Anaconda)》

http://blog.****.net/chenmaolin88/article/details/79370258

《Ubuntu 16.04下安装TensorFlow Object Detection API(对象检测API)》

http://blog.****.net/chenmaolin88/article/details/79371891

后文假设你已经按照这两篇文章搭建好了环境。


二、将图片和标注转换为TFRecord格式

2.1 在~/tensorflow/models/research/object_detection/dataset_tools目录下(~表示当前用户主目录,下同)找到create_pascal_tf_record.py 文件,这个就是tensorflow提供的将pascal voc格式转换为TFRecord格式的脚本,执行如下脚本,将其复制一份,只不过这个脚本是针对pascal voc数据集的目录结构编写的,所以我们需要编辑修改一下它:

(root) [email protected]:~/tensorflow/models/research$ cp object_detection/dataset_tools/create_pascal_tf_record.py   

object_detection/dataset_tools/create_pascal_tf_record4raccoon.py

(root) [email protected]:~/tensorflow/models/research$ gedit object_detection/dataset_tools/create_pascal_tf_record4raccoon.py

https://blog.****.net/chenmaolin88/article/details/79357263

2.2 框架需要我们定义好我们的类别ID与类别名称的关系,通常用pbtxt格式文件保存,我们在~/dataset/raccoon_dataset-master/目录下新建一个名为raccoon_label_map.pbtxt的文本文件,内容如下:

item {

  id: 1

  name: 'raccoon'

}

因为我们只有一个类别,所以这里就只需要定义1个item,若你有多个类别,就需要多个item,注意,id从1开始,name的值要和标注文件里的类别name相同,即你在图像打标的时候标记的是raccoon,这里就要写raccoon,不能写"浣熊".

2.3 我们需要用两个文本文件,来告诉转换脚本,哪些图片文件用来做训练集,哪些图片文件用来做验证集。在~/dataset/raccoon_dataset-master/目录下新建一个名为train.txt的文本文件,内容(这个清单是我用python脚本生成的,人工取前160张作为训练集,后40张作为验证集)如下:

用TensorFlow训练一个目标检测器(手把手教学版)

在~/dataset/raccoon_dataset-master/目录下新建一个名为val.txt的文本文件,内容如下:

用TensorFlow训练一个目标检测器(手把手教学版)

这个list可以用如下python脚本生成:

用TensorFlow训练一个目标检测器(手把手教学版)

2.4 运行我们编写的脚本,生成TFRecord文件

#from ~/tensorflow/models/research

python object_detection/dataset_tools/create_pascal_tf_record4raccoon.py \

--data_dir=/home/forest/dataset/raccoon_dataset-master/images \

--set=/home/forest/dataset/raccoon_dataset-master/train.txt \

--output_path=/home/forest/dataset/raccoon_dataset-master/train.record \

--label_map_path=/home/forest/dataset/raccoon_dataset-master/raccoon_label_map.pbtxt \

--annotations_dir=/home/forest/dataset/raccoon_dataset-master/annotations

用TensorFlow训练一个目标检测器(手把手教学版)

如果输出 if not xml,说明执行成功,~/dataset/raccoon_dataset-master/train.record 就是我们需要训练集文件

接着执行如下脚本,生成验证集TFRecord文件:

python object_detection/dataset_tools/create_pascal_tf_record4raccoon.py \

--data_dir=/home/forest/dataset/raccoon_dataset-master/images \

--set=/home/forest/dataset/raccoon_dataset-master/val.txt \

--output_path=/home/forest/dataset/raccoon_dataset-master/val.record \

--label_map_path=/home/forest/dataset/raccoon_dataset-master/raccoon_label_map.pbtxt \

--annotations_dir=/home/forest/dataset/raccoon_dataset-master/annotations

用TensorFlow训练一个目标检测器(手把手教学版)

如果输出 if not xml,说明执行成功,~/dataset/raccoon_dataset-master/val.record 就是我们需要验证集文件

三、下载预训练模型

  本例中,我们将使用ssd_mobilenet_v1 网络,并且我们需要使用迁移学习的加速我们的训练过程,我们将使用ssd_mobilenet_v1_coco作为预训练模型来进行finetune训练,下载地址 ssd_mobilenet_v1_coco ,

http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz

若你在《Ubuntu 16.04下安装TensorFlow Object Detection API(对象检测API)》

http://blog.****.net/chenmaolin88/article/details/79371891

的搭建的最后一步跑demo时,已经下载了该模型,则确认目录结构如下之后,跳过本步骤即可。

用TensorFlow训练一个目标检测器(手把手教学版)

四、修改训练配置文件

4.1 复制object_detection/samples/configs下的ssd_mobilenet_v1_coco.config 到 ~/dataset/raccoon_dataset-master/下,重命名为ssd_mobilenet_v1_raccoon.config,并做如下修改:

https://blog.****.net/chenmaolin88/article/details/79357263

4.2在~/dataset/raccoon_dataset-master/目录下新建一个train目录,用于保存训练的检查点文件。

五、开始训练

在object_detection路径下,执行下面的命令,开始训练,:

从 ~/tensorflow/models/research/object_detection 目录下运行如下命令

python train.py --logtostderr \--pipeline_config_path=/home/forest/dataset/raccoon_dataset-master/ssd_mobilenet_v1_raccoon.config \--train_dir=/home/forest/dataset/raccoon_dataset-master/train

用TensorFlow训练一个目标检测器(手把手教学版)

若是GPU,则需要在train.py文件的第55行,加入下面这句:

#GPU需要加上下面这句,0表示第1块GPU设备

os.environ['CUDA_VISIBLE_DEVICES'] = "0"

用TensorFlow训练一个目标检测器(手把手教学版)

你可以随时在终端里按ctrl+c,终止训练,那么我们什么时候结束训练呢?请看下面。

六、用验证集评估训练效果(可选)

在~/dataset/raccoon_dataset-master/目录下新建一个eval目录,用于保存eval的文件。另开终端,执行如下命令

(root) [email protected]:~/tensorflow/models/research/object_detection$ python eval.py \

--logtostderr \

--pipeline_config_path=/home/forest/dataset/raccoon_dataset-master/ssd_mobilenet_v1_raccoon.config \

--checkpoint_dir=/home/forest/dataset/raccoon_dataset-master/train \

--eval_dir=/home/forest/dataset/raccoon_dataset-master/eval

保持这个终端一直运行,在训练结束时,再CTRL+C结束eval

七、用TensorBoard查看训练进程

为了更方便 TensorFlow 程序的理解、调试与优化,谷歌发布了一套叫做 TensorBoard 的可视化工具。你可以用 TensorBoard 来展现你的 TensorFlow 图像,绘制图像生成的定量指标图以及附加数据。TensorBoard 通过读取 TensorFlow 的事件文件来运行。TensorFlow 的事件文件包括了你会在 TensorFlow 运行中涉及到的主要数据。

新打开一个终端,运行如下指令:

(root) [email protected]:~$ source activate root

(root) [email protected]:~$ tensorboard --logdir=/home/forest/dataset/raccoon_dataset-master/

用TensorFlow训练一个目标检测器(手把手教学版)

在浏览器中打开上图中出来的http地址,即可看到TensorBoard的主界面,可以看出来,在20k step之前,loss下降很快,之后就波动很小了,经过一夜的训练,目前接近80k step了, mAP平均精确率为67%(由于我是训练完之后再做的eval,所以这里是一条直线,在train时就一直开着eval的话,这里就应该是一条曲线了),我们几乎可以停止训练了。在训练的那个终端里按CTRL+C停止训练吧。

用TensorFlow训练一个目标检测器(手把手教学版)

用TensorFlow训练一个目标检测器(手把手教学版)

若你在train后,就开始跑了eval的话,你还可以像下面一样拖动滑动条来查看随着时间推移,识别效果的直观变化。

用TensorFlow训练一个目标检测器(手把手教学版)

八、将检查点文件导出为冻结的模型文件

 TensorFlow网络中含有大量的需要训练的变量,当训练结束时,这些变量的值就确定了,我们可以用下面的方法将训练的检查点文件里的变量替换为常量,导出成用于推断的模型文件。注意75895 部分根据你自己的最后一个检查点的编号来调整。

(root) [email protected]:~/tensorflow/models-master/research/object_detection$ python export_inference_graph.py \

--pipeline_config_path=/home/forest/dataset/raccoon_dataset-master/ssd_mobilenet_v1_raccoon.config \

--trained_checkpoint_prefix=/home/forest/dataset/raccoon_dataset-master/train/model.ckpt-75895 \

--output_directory=/home/forest/dataset/raccoon_dataset-master/train


/home/forest/dataset/raccoon_dataset-master/train下的frozen_inference_graph.pb 文件就是我们宝贵的,最终要的模型文件。

九、用模型进行浣熊的识别

打开《Ubuntu 16.04下安装TensorFlow Object Detection API(对象检测API)》

http://blog.****.net/chenmaolin88/article/details/79371891

里最后一步提到的DEMO,做如下修改:

用TensorFlow训练一个目标检测器(手把手教学版)

.....

用TensorFlow训练一个目标检测器(手把手教学版)

单步运行每一行

最终结果如下

用TensorFlow训练一个目标检测器(手把手教学版)

https://blog.****.net/chenmaolin88/article/details/79357263

不断更新资源

深度学习、机器学习、数据分析、python

 搜索公众号添加: datayx  

用TensorFlow训练一个目标检测器(手把手教学版)

长按图片,识别二维码,点关注