用TensorFlow训练一个目标检测器(手把手教学版)
向AI转型的程序员都关注了这个号????????????
大数据挖掘DT机器学习 公众号: datayx
TensorFlow内包含了一个强大的物体检测API,我们可以利用这API来训练自己的数据集实现特殊的目标检测。
国外一位程序员分享了自己实现可爱的浣熊检测器的经历
原文地址(需要翻越那道墙):https://towardsdatascience.com/how-to-train-your-own-object-detector-with-tensorflows-object-detector-api-bec72ecfe1d9
原文作者的github:(作者的数据集可以在这里下载)
关注微信公众号 datayx 然后回复 目标检测 即可获取。
在文章中作者把检测器的训练流程进行了简要介绍,但过于粗略,初学者难以跟着实现。为了方便初学者,我把详细的步骤整理了一下,下面我们一起来学习一下吧!
这篇文章主要还是学习训练目标检测,本文以检测浣熊为例,其实也可以用自己的数据集,检测其他的目标,比如 检测海上船只,检测天空的飞机,检测小猫小狗等等。
为什么要做这件事?
方便面君不仅可爱,在国外很普遍的与人们平静地生活在一起。处于对它的喜爱和与浣熊为邻的情况,作者选择了它作为检测器的检测对象。完成后可以将摄像安装在房子周围,检测是否有浣熊闯入了你家,你就能及时知道是否来了不速之客了。看来浣熊还真多啊!
一、创建数据集
机器学习需要数据作为原料,那么我们首先需要做的就是建立起一个可供训练的数据集,同时我们需要利用符合Tensorflow的数据格式来保存这些数据及其标签。
1.在准备输入数据之前你需要考虑两件事情:其一,你需要一些浣熊的彩色图片;其二,你需要在图中浣熊的位置框坐标(xmin,ymin,xmax,ymax)来定位浣熊的位置并进行分类。对于只检测一种物体来说我们的任务十分简单,只需要定义一类就可以了;
2.哪里去找数据呢?互联网是最大的资源啦。包括各大搜索引擎的图片搜索和图像网站,寻找一些不同尺度、位姿、光照下的图片。作者找了大概两百张的浣熊图片来训练自己的检测器(数据量有点小,但是来练手还是可以的,其实imagenet上有浣熊的数据集的,有心的朋友可以去下载,注册imagenet是需要翻越高墙的,否则看不到验证码);
3.有了数据以后我们需要给他们打标签。分类很简单,都是浣熊,但是我们需要手动在每一张图中框出浣熊的位置。一个比较好的打标工具是LabelImg,
https://github.com/tzutalin/labelImg
关于图片打标注,请参考另一篇文章《手把手教你图片打标注》
http://blog.****.net/chenmaolin88/article/details/79357502
4、到目前为止,我们有了一些浣熊的图片以及这些图片的标注文件(annotation)(如果你比较懒,可以从原文作者的GITHUB里下载这些图片和标注文件, 这里我就直接下载原文作者的标注文件和图片)
5、我们把下载好的ZIP包解压,如下,annotations目录就是标注文件,images目录就是图像文件,标注文件raccoon-1.xml里的filename节点就是它对应的图片文件的文件名,需要特别说明的是,raccoon这个数据集里面的标注文件xml里的filename是png后缀,而实际我们下载到的图片是是jpg格式的,估计是原作者转换了格式,因此,在后文中,我们需要对这个filename做一点小处理。解压出来的其他文件我们都不需要,全部删掉,后面我们会一步步自己写出那些文件的。
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张作为验证集)如下:
在~/dataset/raccoon_dataset-master/目录下新建一个名为val.txt的文本文件,内容如下:
这个list可以用如下python脚本生成:
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
如果输出 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
如果输出 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时,已经下载了该模型,则确认目录结构如下之后,跳过本步骤即可。
四、修改训练配置文件
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
若是GPU,则需要在train.py文件的第55行,加入下面这句:
#GPU需要加上下面这句,0表示第1块GPU设备
os.environ['CUDA_VISIBLE_DEVICES'] = "0"
你可以随时在终端里按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/
在浏览器中打开上图中出来的http地址,即可看到TensorBoard的主界面,可以看出来,在20k step之前,loss下降很快,之后就波动很小了,经过一夜的训练,目前接近80k step了, mAP平均精确率为67%(由于我是训练完之后再做的eval,所以这里是一条直线,在train时就一直开着eval的话,这里就应该是一条曲线了),我们几乎可以停止训练了。在训练的那个终端里按CTRL+C停止训练吧。
若你在train后,就开始跑了eval的话,你还可以像下面一样拖动滑动条来查看随着时间推移,识别效果的直观变化。
八、将检查点文件导出为冻结的模型文件
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,做如下修改:
.....
单步运行每一行
最终结果如下
https://blog.****.net/chenmaolin88/article/details/79357263
不断更新资源
深度学习、机器学习、数据分析、python
搜索公众号添加: datayx
长按图片,识别二维码,点关注