复现地址:https://github.com/endernewton/tf-faster-rcnn
深度学习环境搭建见文章:https://blog.csdn.net/weixin_43435675/article/details/88359636
fasterrcnn代码解读见文章:https://www.cnblogs.com/darkknightzh/p/10043864.html
coco数据集上如下:
$ conda create -n tf-faster-rcnn python=3.6
$ conda remove -n tf-faster-rcnn --all #若想删除这conda环境
$ source activate tf-faster-rcnn
$ conda env list
$ source deactivate
下载后原始的文件夹如下:
文件夹data
:数据,权重
lib
:网络结构,数据读入
tools
:训练,测试
voc数据集分享
:链接:https://pan.baidu.com/s/1UPRbgR2rMZUDHHGI6roGuA 提取码:jlj8
resnet101(for voc pre-trained on 07+12 set),vgg16预训练模型文件夹分享
:链接:https://pan.baidu.com/s/14kIWwxdOqCCioiyBDNtnlg 提取码:gmta
修改为gpu
:在tf-faster-rcnn/lib/setup.py的第130行修改为自己gpu对应,算力查询:http://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/
修改为cpu
:
1.
编译Cython:虚拟环境中lib路径下make clean
,make
(pip install easydict,pip install Cython),(注意如果运行python3 tool/demo.py就会出现错误提示:ImportError: No module named gpu_nms,把Makefile里面的python改成python3就可以了)。
2.
安装COCO API:在自己建的虚拟环境中make
cd data
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
3.
下载voc数据集或在上文百度云分享:
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
Extract all of these tars into one directory
named VOCdevkit:
tar xvf VOCtrainval_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar
tar xvf VOCdevkit_08-Jun-2007.tar
VOCdevkit文件夹拷贝到tf-fater-rcnn/data路径下并重命名为VOCdevkit2007
,用不到分割可以改为如下:
4.
将下载的Resnet101预训练模型voc_2007_trainval+voc_2012_trainval
(一个文件夹里面只有几个ckpt文件,上文百度云分享的)放在tf-fater-rcnn目录,在tf-faster-rcnn目录创建一个output文件夹
并且在其中存放预训练模型的软链接,output文件夹中会在每次训练后存放训练好的模型:
NET=res101
TRAIN_IMDB=voc_2007_trainval+voc_2012_trainval
mkdir -p output/${
NET}/${
TRAIN_IMDB} # 创建名称的空文件夹
cd output/${
NET}/${
TRAIN_IMDB}
ln -s ../../../voc_2007_trainval+voc_2012_trainval ./default # 建立软连
cd ../../..
GPU_ID=0
CUDA_VISIBLE_DEVICES=${
GPU_ID} ./tools/demo.py
1.
同样采用上面在ImageNet和VOC0712上训练过的Resnet101预训练模型,对其用VOC0712的test测试集进行测试(查阅test_faster_rcnn.sh
会发现,其实所用的就是VOC07的test测试集,test.txt里面有4952行)
把tf-faster-rcnn/lib/datasets/voc_eval.py的第121行的
with open(cachefile,'w') as f
改成:
with open(cachefile,'wb') as f
同时还要把第105行的
cachefile = os.path.join(cachedir, '%s_annots.pkl' % imagesetfile)
改为
cachefile = os.path.join(cachedir, '%s_annots.pkl' % imagesetfile.split("/")[-1].split(".")[0])
2.
faster-rcnn根目录下
GPU_ID=0
./experiments/scripts/test_faster_rcnn.sh $GPU_ID pascal_voc_0712 res101
测试4952张完显示下图
测试完后会自动建立/output/res101/voc_2007_test
/default/res101_faster_rcnn_iter_110000/…pkl
1.
wget -v http://download.tensorflow.org/models/vgg_16_2016_08_28.tar.gz ,或在官网上下载:https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models
./experiments/scripts/train_faster_rcnn.sh [GPU_ID] [DATASET] [NET]
# GPU_ID 是你要使用的GPU编号
# NET 是你采用的网络类型, 可选范围为{vgg16, res50, res101, res152}
# DATASET 是数据集,在train_faster_rcnn.sh中预先定义过{pascal_voc, pascal_voc_0712, coco} ,还可以根据自己需要进行添加
# Examples:
./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc vgg16
./experiments/scripts/train_faster_rcnn.sh 1 coco res101
上面在演示demo时,在output中建立了一个经过VOC0712数据集训练好的Res101模型的软链接,如果有再次使用VOC0712数据集对Res101进行训练的需要,记得删除掉该软链接
2.
下面使用VOC07数据集训练VGG16训练并测试: 为了节省时间并排除错误,我把迭代次数只设置了20次,即在./experiments/scripts/train_faster_rcnn.sh
里的第22行把ITERS=70000改成ITERS=20,同时由于train_faster_rcnn.sh中最后有调用test_faster_rcnn.sh,因此记得把./experiments/scripts/test_faster_rcnn.sh
的ITERS也改成20。
$ ./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc vgg16
有20类AP,21类Result
训练了20轮准确度很差,运行train_faster_rcnn.sh后会自动运行test_faster_rcnn.sh,即训练完自动进行测试。
3.
用Tensorboard可视化:训练完成后,可以使用Tensorboard对训练过程的log
进行可视化。
logdir
用来设置想要把Tensorboard的event文件存放在哪里,port
用来设置通过哪个端口显示Tensorboard界面
$ tensorboard --logdir=tensorboard/vgg16/voc_2007_trainval/ --port=7001 &
,产生下面文件
复制http://…,浏览器打开,只训练了20轮效果差
4.
默认情况下,训练好的网络存放在:output/[NET]/[DATASET_trainval
]/default/
测试的输出结果存放在:output/[NET]/[DATASET_test
]/default/[SNAPSHOT]/
训练和验证的Tensorboard信息存放在:
tensorboard/[NET]/[DATASET]/default/
tensorboard/[NET]/[DATASET]/default_val/
1.
在与PASCAL VOC(VOCdevkit2007)数据集同级目录建立文件夹名为"MSDD",在MSDD文件夹下,建立3个文件夹:annotations_cache,results,VOC2007
。ananotations_cache里存放的是标注缓存数据,如果你对数据集有改动,记得清除缓存数据,否则的话依旧加载的是原始数据。
results文件夹下依次创建如下路径:
2.
VOC2007文件夹下创建如下3个子文件夹:
在Annotations目录下存放所有的xml标签文件,名字格式为000001.xml
在JPEGImages目录下存放所有的jpg图片,名字格式为000001.jpg
3.
在ImageSets文件夹下创建3个子文件夹:
Main文件夹下存放的是记录各个子集所包含样本编号的txt文件
4.
可在data文件夹下建立软链接,也可将数据集直接放在data文件夹下:
修改程序:1.
新建msdd.py:在lib/dataset/目录下复制pascal_voc.py并以自己的数据集命名,该文件会生成该各个子数据集的imdb,如msdd_train、msdd_val等
# pascal_voc.py
class pascal_voc(imdb):
def __init__(self, image_set, year, use_diff=False):
name = 'voc_' + year + '_' + image_set
if use_diff:
name += '_diff'
imdb.__init__(self, name)
self._year = year
self._image_set = image_set
self._devkit_path = self._get_default_path()
self._data_path = os.path.join(self._devkit_path, 'VOC' + self._year)
self._classes = ('__background__', # always index 0
'aeroplane', 'bicycle', 'bird', 'boat',
'bottle', 'bus', 'car', 'cat', 'chair',
'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant',
'sheep', 'sofa', 'train', 'tvmonitor')
self._class_to_ind = dict(list(zip(self.classes, list(range(self.num_classes)))))
self._image_ext = '.jpg'
self._image_index = self._load_image_set_index()
# Default to roidb handler
self._roidb_handler = self.gt_roidb
self._salt = str(uuid.uuid4())
self._comp_id = 'comp4'
# PASCAL specific config options
self.config = {
'cleanup': True,
'use_salt': True,
'use_diff': use_diff,
'matlab_eval': False,
'rpn_file': None}
# msdd.py
class msdd(imdb):
def __init__(self, image_set):
name = 'msdd_' + image_set
imdb.__init__(self, name)
self._year = '2007'
self._image_set = image_set
self._devkit_path = self._get_default_path()
self._data_path = os.path.join(self._devkit_path, 'VOC' + self._year) # 数据位置 data/MSDD/VOC2007
self._classes = ('__background__', # always index 0
'cr', 'ln', 'pa', 'ps', # 改成自己的类别
'rs', 'sc')
self._class_to_ind = dict(list(zip(self.classes, list(range(self.num_classes)))))
self._image_ext = '.jpg' # 建议使用jpg格式
self._image_index = self._load_image_set_index()
# Default to roidb handler
self._roidb_handler = self.gt_roidb
self._salt = str(uuid.uuid4())
self._comp_id = 'comp4'
# PASCAL specific config options
self.config = {
'cleanup': True,
'use_salt': True,
'use_diff': False, # 关闭use_diff
'matlab_eval': False,
'rpn_file': None}
# pascal_voc.py
def _get_default_path(self):
"""
Return the default path where PASCAL VOC is expected to be installed.
"""
return os.path.join(cfg.DATA_DIR, 'VOCdevkit' + self._year)
# msdd.py
def _get_default_path(self):
"""
Return the default path where PASCAL VOC is expected to be installed.
"""
return os.path.join(cfg.DATA_DIR, 'MSDD')
# 开发包位置 data/MSDD
2.
修改factory.py:该文件同样在lib/dataset/目录下,该文件生成由各个子数据集(xxx_train、xxx_test)的imdb格式组成的字典,其中会调用如pascal_voc.py、msdd.py等文件,以按各个数据集的指定格式生成各个子数据集的imdb,仿照其他格式在相应位置插入下面代码
# factory.py
# Set up mssd_
for split in ['train', 'val', 'trainval', 'test']:
# 只能选ImageSets/Main中有的txt文件,可以仅选一部分
name = 'msdd_{}'.format(split)
__sets[name] = (lambda split = split: msdd(split))
3.
修改train_faster_rcnn.sh,仿照其他数据集,添加自己数据集,可选的IMDB都是在factory.py中生成的
# train_faster_rcnn.sh
msdd)
TRAIN_IMDB="msdd_trainval" # 训练所用IMDB
TEST_IMDB="msdd_test" # 测试所用IMDB
STEPSIZE="[50000]"
ITERS=20
ANCHORS="[8,16,32]"
RATIOS="[0.5,1,2]"
;;
4.
与上同理修改test_faster_rcnn.sh
# test_faster_rcnn.sh
msdd)
TRAIN_IMDB="msdd_trainval" # 训练所用IMDB
TEST_IMDB="msdd_test" # 测试所用IMDB
ITERS=20
ANCHORS="[8,16,32]"
RATIOS="[0.5,1,2]"
;;
5.
开始训练测试
$ ./experiments/scripts/train_faster_rcnn.sh 0 msdd vgg16
6.
推理应用
修改tools/demo.py里面的’CLASSES‘、’NETS’以及’DATASETS’变量为和自己的数据集相关,修改main函数里面测试图片名,即可利用训练好的模型对几张图片进行检测应用。