本实验借鉴https://blog.csdn.net/ctwy291314/article/details/80999645, 该实验是将目标检测迁移到人脸检测上.
这里使用WIDER FACE数据集作为训练集合验证集. 为了简单, 快速实现在目标检测任务中采用迁移学习. 只下载WIDER Face Validation Images作为训练集, 必要的时候也可以作为验证集.
将WIDER_val和wider_face_split文件夹放在./datasets下.
这里采用Tensorflow在COCO数据集上训练好的模型, 下载地址https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md. 这里下载faster_rcnn_inception_v2_coco.
原文中使用代码001_down_data.py进行数据集和训练好模型的下载, 这里暂时不需要!
数据预处理工作包括:
将WIDERFace转换为Pascal XML. 将使用scripts/data-to-pascal-xml.py转换WIDERFace数据并且将数据复制到一个不同的子文件夹中. 并修改scripts/data-to-pascal-xml.py中的一些路径.
运行scripts/data-to-pascal-xml.py, 将会在datasets下生成tf_wider_train和tf_wider_val文件夹, 里面包含xmls文件夹, images文件夹和txt文件. 这是训练集和验证集的源数据.
创建Pascal XML到Tensorflow CSV的索引. 详见scripts/xml-to-csv.py, 并简单修改一些路径. 这样tf_wider_train和tf_wider_val文件夹下面的txt文件, 就会变成csv文件.
创建TFRecord文件. 训练和验证数据将被转换成二进制文件. 详见scripts/generate_tfrecord.py, 并简单修改一些路径. 运行方式如下:
# creates train.record
python generate_tfrecord.py --images_path=../datasets/tf_wider_train/images --csv_input=../datasets/tf_wider_train/train.csv --output_path=../datasets/train.record
# Create test/validation data:
python generate_tfrecord.py --images_path=../datasets/tf_wider_val/images --csv_input=../datasets/tf_wider_val/val.csv --output_path=../datasets/val.record
代码对图像没有进行resize, 因此batch size只能是1. 将图像进行resize, 这样可以提高运行效率.
在运行以上两个程序之前, 确保python已经安装了object_detection. object_detection是Tensorflow做目标检测所需的包, 可见https://github.com/tensorflow/models/tree/master/research/object_detection.
1> 直接pip install object_detection时, Tensorflow的版本要求是最高的. 这样, 又会涉及到CUDA版本和CUDNN版本的问题. 所以, 直接将https://github.com/tensorflow/models clone下来, 然后指定PYTHONPATH环境变量即可. 如将models/research/加到PYTHONPATH环境变量中即可.
2> Protobuf Compilation. 首先安装protobuf. https://github.com/protocolbuffers/protobuf源码编译安装.
3> cd /home/ly/downloads/models/research/
From tensorflow/models/research/
protoc object_detection/protos/*.proto --python_out=.
4> 将models/research/和models/research/slim都加进PYTHONPATH环境变量.
cd ./face_faster_rcnn
python export_inference_graph.py --input_type image_tensor --pipeline_config_path faster_rcnn_inception_v2_coco.config --trained_checkpoint_prefix model_output/model.ckpt-100000 --output_directory face_faster_rcnn_model/
tar zcvf face_faster_rcnn_model.tar.gz face_faster_rcnn_model
python transfer_learning_object_detection.py
第二种: 将人脸检测加入到目标检测中, 即在实现原有目标检测的同时, 加入新的目标检测.
第二种实现方式有两种: 1) 先对图像做目标检测, 再对图像做人脸检测, 将结果进行融合即可. 2) 实现端到端的, 即将新的目标检测加入到原来的目标检测中去, 而不是分开!
对于第二种实现方法, 目前这一处理:
object_face_detection_faster_rcnn目录下.
1> 还是仅采用WIDER FACE数据集作为训练集, 将num_classes改成91.
2> 修改object_face_label.pbtxt, 将91类的目标name都写上. 原始的*.pbtxt在/home/ly/downloads/models/research/object_detection/data下. 如80类的COCO数据集, 采用的是mscoco_label_map.pbtxt.
3> python train.py --logtostderr --train_dir=…/datasets/ --pipeline_config_path=faster_rcnn_inception_v2_coco.config --train_dir=model_output
4> python export_inference_graph.py --input_type image_tensor --pipeline_config_path faster_rcnn_inception_v2_coco.config --trained_checkpoint_prefix model_output/model.ckpt-100000 --output_directory object_face_detection_faster_rcnn_model/
需要修改/home/ly/downloads/models/research/object_detection/meta_architectures/faster_rcnn_meta_arch.py, 因为tf 1.10没有tf.batch_gather(), 可以将这个操作自行添加. 借助tf 1.13版本即可.
5> tar zcvf object_face_detection_faster_rcnn_model.tar.gz object_face_detection_faster_rcnn_model
python transfer_learning_object_detection.py
对7.的部分进行实验, 发现实验结果并不好. 还是只有人脸检测部分. 直接将new class加入到old class中(即分类层的结点数增多), 并且训练集只有new class的数据集. 开始retain, 这里的问题是: 1) 只采用新数据集进行训练, 分类层结点个数是(old class + new class数目), 网络前N-1层freeze, 这样新数据集可能并不能很好的适应网络. 因为我们只有new class的数据集. 2) 只采用新数据集进行训练, 分类层结点个数是(old class + new class数目), 网络前N-1层不freeze, 这样新数据集可能并不能很好的适应网络, 并且可能会破坏原有class的识别精度. 因为我们只有new class的数据集.
因此, 将new class加入到old class的迁移学习, 并不是很容易做. 目前的迁移学习还是集中在将原始任务迁移到一个新任务上, 减少训练量和训练难度.
first stage: 做图像做目标检测, 得到检测结果1, 这里采用的是已经训练好的通用目标检测框架; second stage: 对图像做目标检测, 得到检测结果2, 这里采用的是将迁移学习应用到目前检测中, 将原始检测任务迁移到新的目标检测任务中. 最后, 将检测结果1和检测结果2进行融合, 进行展示或将检测结果进行格式化输出.
具体代码可见: ./object_face_detection_faster_rcnn/transfer_learning_object_face_detection.py.
Faster RCNN多小目标检测效果较差, 这是由于Faster RCNN scale的问题, faster rcnn只在con5_3进行roi pooling; fpn和mask-rcnn则正好解决了这个缺陷, 在多级特征上进行roi pooling.