环境:linux+python3.5+tensorflow1.10+cuda9.0
源码:https://github.com/DetectionTeamUCAS/Faster-RCNN_Tensorflow
数据集制作
数据集格式:
与pascal voc格式一样,
分为Annotations和JPEGImages
xml文件有这些内容就可以了
<annotation>
<folder>VOC2007</folder>
<filename>001.jpg</filename>
<size>
<width>958</width>
<height>808</height>
<depth>3</depth>
</size>
<object>
<name>airplane</name>
<pose>unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>563</xmin>
<ymin>478</ymin>
<xmax>630</xmax>
<ymax>573</ymax>
</bndbox>
</object>
</annotation>
跑自己的数据集修改的内容:
1 上传数据至Faster-RCNN_Tensorflow/data/io/data,data文件夹是我自己新建的
2 修改convert_data_to_tfrecord.py文件,把路径修改至你自己的数据路径就可以了。tf.app.flags.DEFINE_string(‘dataset’, ‘nwpu’, ‘dataset’)这里选择要使用的数据集。
3.进入Faster-RCNN_Tensorflow/libs/label_name_dict打开label_dict.py文件,新增自己的数据集,'back_ground':0
是默认的
4.修改Faster-RCNN_Tensorflow/libs/configs/cfgs.py,DATASET_NAME = 'nwpu'
数据集选择自己的数据集,CLASS_NUM = 10
改成自己数据集的类数
5.修改Faster-RCNN_Tensorflow/data/io/read_tfrecord.py,next_batch函数中添加自己的数据集
if dataset_name not in ['ship', 'spacenet', 'pascal', 'coco']:
raise ValueError('dataSet name must be in pascal, coco spacenet and ship')
6 convert_data_to_tfrecord.py文件的def convert_pascal_to_tfrecord():函数中'img_name': _bytes_feature(img_name)
修改为'img_name': _bytes_feature(img_name.encode()),
如果没有报错就不用改了。
至此就算修改完了,运行convert_data_to_tfrecord.py文件,生成训练和测试的tfrecord文件
如果运行时出现类似这种错误,是因为数据集中出现了没有的类名,好好检查下数据集。
Traceback (most recent call last):
File "convert_data_to_tfrecord.py", line 122, in <module>
convert_pascal_to_tfrecord()
File "convert_data_to_tfrecord.py", line 93, in convert_pascal_to_tfrecord
img_height, img_width, gtbox_label = read_xml_gtbox_and_label(xml)
File "convert_data_to_tfrecord.py", line 59, in read_xml_gtbox_and_label
label = NAME_LABEL_MAP[child_item.text]
KeyError: '10'
编译:
进入/libs/box_utils/cython_utils删除里边的bbox.c和nms.c文件以及.so文件
python setup.py build_ext --inplace
编译通过后应该会有这些文件
bbox.c __init__.py nms.pyx
bbox.pyx __init__.pyc __pycache__
cython_bbox.cpython-35m-x86_64-linux-gnu.so Makefile setup.py
cython_nms.cpython-35m-x86_64-linux-gnu.so nms.c
训练:
1.上传预训练的模型至Faster-RCNN_Tensorflow/data/pretrained_weights,默认的是resnet_v1_101
2.报错:
Traceback (most recent call last):
File "train.py", line 14, in <module>
from libs.networks import build_whole_network
File "../libs/networks/build_whole_network.py", line 20, in <module>
from libs.detection_oprations.anchor_target_layer_without_boxweight import anchor_target_layer
File "../libs/detection_oprations/anchor_target_layer_without_boxweight.py", line 15, in <module>
from libs.box_utils.cython_utils.cython_bbox import bbox_overlaps
ImportError: ../libs/box_utils/cython_utils/cython_bbox.so: undefined symbol: _Py_ZeroStruct
原因是python版本的问题,我电脑里装了python2和python3,但是tensorflow是python3的,我用python2编译就会出问题。
3.进入到tools,运行python train.py就可以开始训练了
期间遇到的问题:
PaddingFIFOQueue '_2_get_batch/batch/padding_fifo_queue' is closed and has insufficient elements (requested 1, current size 0)
我是因为tfrecord放的位置不对,程序没有找到,默认的位置是Faster-RCNN_Tensorflow/data/tfrecord下
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/script_ops.py", line 206, in __call__
ret = func(*args)
File "../libs/box_utils/draw_box_in_img.py", line 124, in draw_boxes_with_label_and_scores
draw_label_with_scores(draw_obj, box, a_label, a_score, color='White')
File "../libs/box_utils/draw_box_in_img.py", line 91, in draw_label_with_scores
print(LABEL_NAME_MAP[label])
KeyError: 15
我因为开始忘了修改类的数目,所以总是生成一些超过类目数的label,这个问题困了我好久,果然是马虎不得。
评估:
评估准确率时config.py文件中这个参数要改为0
推断结果在图上画框时这个参数要改为0.5
SHOW_SCORE_THRSHOLD = 0 # only show in tensorboardeval.py文件中
错误:
File "eval.py", line 173, in <module>
showbox=args.showbox)
File "eval.py", line 128, in eval
draw_imgs=showbox)
File "eval.py", line 108, in eval_with_plac
pickle.dump(all_boxes, fw1)
TypeError: write() argument must be str, not bytes
修改108行fw1 = open(os.path.join(save_dir, ‘detections.pkl’), ‘wb’)
pickle.dump(all_boxes, fw1)
错误:
File "eval.py", line 173, in <module>
showbox=args.showbox)
File "eval.py", line 134, in eval
all_boxes = pickle.load(f)
File "/usr/lib/python3.5/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
修改133行with open(os.path.join(save_dir, ‘detections.pkl’),‘rb’) as f:
all_boxes = pickle.load(f)
错误:
Traceback (most recent call last):
File "eval.py", line 173, in <module>
showbox=args.showbox)
File "eval.py", line 140, in eval
test_imgid_list=real_test_imgname_list)
File "../libs/val_libs/voc_eval.py", line 253, in voc_evaluate_detections
do_python_eval(test_imgid_list, test_annotation_path=test_annotation_path)
File "../libs/val_libs/voc_eval.py", line 221, in do_python_eval
color_list = colors.cnames.keys()[::6]
TypeError: 'dict_keys' object is not subscriptable
voc_eval.py文件中do_python_eval修改成
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.colors as colors
color_list=list(colors.cnames.keys())
color_list=color_list[::6]