转载请注明:
参考:
GPU坑:
GPU:
1.Environment
创建环境
Centos7
CUDA:0.9
CUDNN:7.3.1
TeslaP100:sm_60
conda create --name tensorflow-gpu python=3.6
conda install matplotlib yaml pyyaml numpy
pip in stall cython opencv-python easydict
先安装Scipy再安装tensorflow()
conda install scipy1.1.0
conda install tensorflow-gpu1.8.0
安装时注意细节更新
2.下载github项目代码和数据
git clone https://github.com/endernewton/tf-faster-rcnn.git
3.修改GPU配置
修改lib/setup.py
cd tf-faster-rcnn/lib
Change the GPU architecture (-arch) if necessary
vim setup.py
Tesla P100 :sm_60
GPU计算能力查询:https://developer.nvidia.com/cuda-gpus4.链接cython模块
在lib目录下打开终端,输入
make clean
make
cd ..
此时终端回到主目录tf-faster-rcnn
5.安装 Python COCO API,这是为了使用COCO数据库
cd data
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
cd ../../..
此时终端的目录是主目录tf-faster-rcnn
6.数据下载:Beyond the demo: installation for training and testing models
1)下载训练,验证和测试数据集VOCdevkit
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
2)数据集解压 named VOCdevkit
$VOCdevkit/ # development kit
$VOCdevkit/VOCcode/ # VOC utility code
$VOCdevkit/VOC2007 # image sets, annotations, etc.
# ... and several other directories ...
解压后应该是具有如下数据存储结构:
tar xvf VOCtrainval_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar
tar xvf VOCdevkit_08-Jun-2007.tar
3)建立数据集PASCAL VOC软连接
cd $FRCN_ROOT/data
ln -s $VOCdevkit VOCdevkit2007
其中 $FRCN_ROOT/data 应该是存放数据集VOCdevkit的路径(eg:/tf-faster-rcnn/data/)
4)MS COCO官网数据集(百度云)下载,COCO API、MASK API和Annotation format介绍(来自官网):
7.运行Demo 和测试预训练模型
1)下载预训练好的模型 voc_0712_80k-110k.tgz
下载地址:https://drive.google.com/open?id=0ByuDEGFYmWsbNVF5eExySUtMZmM 或 https://www.dropbox.com/s/po2kzdhdgl4ix55/VGG_imagenet.npy?dl=0 (百度云:https://pan.baidu.com/s/1kWkF3fT),放到 data文件夹中。使用命令解压得到voc_2007_trainval+voc_2012_trainval文件夹
tar xvf voc_0712_80k-110k.tgz
2)建立预训练模型的软连接
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 ../../..
3)GPU下直接运行demo
# at repository root
GPU_ID=0
CUDA_VISIBLE_DEVICES=${GPU_ID} ./tools/demo.py
4)对预训练模型进行测试
GPU_ID=0
./experiments/scripts/test_faster_rcnn.sh $GPU_ID pascal_voc_0712 res101
8.训练自己的模型
1)下载预训练模型和权重
for VGG16 :
mkdir -p data/imagenet_weights
cd data/imagenet_weights
wget -v http://download.tensorflow.org/models/vgg_16_2016_08_28.tar.gz
tar -xzvf vgg_16_2016_08_28.tar.gz
mv vgg_16.ckpt vgg16.ckpt
cd ../..
for Resnet101 :
mkdir -p data/imagenet_weights
cd data/imagenet_weights
wget -v http://download.tensorflow.org/models/resnet_v1_101_2016_08_28.tar.gz
tar -xzvf resnet_v1_101_2016_08_28.tar.gz
mv resnet_v1_101.ckpt res101.ckpt
cd ../..
2)训练(验证、测试)
由于是在GPU下运行,./experiments/scripts/train_faster_rcnn.sh
训练
./experiments/scripts/train_faster_rcnn.sh [GPU_ID] [DATASET] [NET]
# GPU_ID is the GPU you want to test on
# NET in {vgg16, res50, res101, res152} is the network arch to use
# DATASET {pascal_voc, pascal_voc_0712, coco} is defined in train_faster_rcnn.sh
# Examples:
./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc vgg16
./experiments/scripts/train_faster_rcnn.sh 1 coco res101
测试
./experiments/scripts/test_faster_rcnn.sh [GPU_ID] [DATASET] [NET]
# GPU_ID is the GPU you want to test on
# NET in {vgg16, res50, res101, res152} is the network arch to use
# DATASET {pascal_voc, pascal_voc_0712, coco} is defined in test_faster_rcnn.sh
# Examples:
./experiments/scripts/test_faster_rcnn.sh 0 pascal_voc vgg16
./experiments/scripts/test_faster_rcnn.sh 1 coco res101
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
二 、训练自己数据集
1.数据格式
此处训练需要将数据整理成VOC2007的格式以作为基本的数据集来使用。该数据集由主要三个文件夹以及其中的内容组成:
1)Annotations文件夹
该文件下存放的是xml格式的标签文件,一张图片对应于一个xml文件,xml文件记录了目标区域的坐标和大小,目标类别等相关信息。
在训练时需要将xml文件格式转换成ASCII
2)JPEGImages文件夹
该文件夹下存放的是数据集图片,包括训练集和测试集的图片。
3)ImageSets文件夹
该文件夹下存放了三个文件夹,分别是Layout、Main、Segmentation。目标检测只要使用其中的存放图像数据的Main文件夹。在Main中存储着test.txt, train.txt, trainval.txt, val.txt四个txt文件,文件中记载着训练集测试集等等数据。
在训练时需要将txt文件格式转换成ASCII
2.制作VOC数据集:Annotation标注工具
https://github.com/hzylmf/od-annotation 参考:
1)根据requirements.txt安装环境依赖
$ cd od-annotation
$ pip3 install -r requirements.txt
2)重命名标注样本,采用前导0方式编号,共6位(000001-0000xx),注意保持样本编号连续。
编辑annotation/label_config.txt文件,根据格式配置标签
# 标签名称:标签描述
dog:狗
3)编辑config.py,根据样本实际情况修改:
SAMPLE_FILE_TYPE = 'jpg' # 样本图片格式
SAMPLE_FILE_PATH = 'your samples directory path' # 样本图片存放目录
4)启动/停止/重启标注工具:
$ cd od-annotation
$ python3 app.py --start|stop|restart # 前台进程方式运行
$ python3 app.py --start|restart --daemon # 以后台进程方式(重新)启动
5)访问http://localhost:5000开始标注。
先选定待标注类别,然后按住鼠标左键并拖拽鼠标在目标区域绘制矩形框进行标注,松开鼠标完成标注。可拖动矩形框以修正坐标,右击某矩形框可取消该标注。每次新绘制矩形框、拖动已有矩形框或右击取消矩形框时,会在下方的当前样本标注状态文本框中同步更新该样本的标注结果。点击左右方向按钮或通过键盘方向键切换标注样本。切换时自动提交标注结果,同时在所有样本标注状态文本框中更新当前样本的标注结果。或手动点击保存按钮提交标注结果。
6)所有样本标注完成后,若需要转换成VOC2007格式,执行:
$ cd od-annotation
$ python3 app.py --convert2voc
查看annotation/VOC2007目录下相关文件夹是否生成对应文件
注:linux 直接在anocade下创建python3 环境进行实现; windows:直接python3 实现
访问http://localhost:5000开始标注
注意:图片最大读取1024*600的图片,对分辨率大的图片很不友好,需要先降低分辨率
7)完成VOC2007的数据集制作后,将其整个文件夹的命名修改为VOC2007,并放在data/VOCdevkit2007/目录下,即在最后的项目数据的路径为tf-faster-rcnn/data/VOCdevkit2007/VOC2007/, 在此目录下,为三个文件夹,即Annotations,JPEGImages,ImageSets
8)其中ImagesSets文件夹中Main中包含4个文件(test.txt、train.txt、trainval.txt、val.txt)
test.txt:测试集
train.txt:训练集
val.txt:验证集
trainval.txt:训练和验证集
在原始VOC2007数据集中,80%作为trainval,20%作为test,train大约是trainval的60%,val大约为trainval的40%
import os
import random
trainval_percent = 0.8
train_percent = 0.6
xmlfilepath = r'/data/tf-faster-rcnn-master/data/VOCdevkit2007/VOC2007/Annotations'
txtsavepath = r'/data/tf-faster-rcnn-master/data/VOCdevkit2007/VOC2007/ImageSets/Main'
total_xml = os.listdir(xmlfilepath)
num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)
ftrainval = open(txtsavepath+'/trainval.txt', 'w')
ftest = open(txtsavepath+'/test.txt', 'w')
ftrain = open(txtsavepath+'/train.txt', 'w')
fval = open(txtsavepath+'/val.txt', 'w')
for i in list:
name=total_xml[i][:-4]+'\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
目标检测制作PASCAL VOC2007格式的数据集:https://blog.csdn.net/hitzijiyingcai/article/details/816364553.代码修改:
1)修改lib/datasets/pascal_voc.py
修改成自己的类,保留’background’类
2)lib/datasets/imdb.py
将num_classes改为自己的类别数加1,上面只是一个类,因此是2
3)修改tools/demo.py
a.类型修改同(1)
b.在(1)处更改训练好的模型名称
c.修改默认的数据集DATASETS和NETS,即default=‘pascal_voc’ , default=‘res101’
d.更改类型数目(num_classes),
e.在tf-faster-rcnn/data/demo/文件夹中放入需要检测的数据图片,将tool/demo.py中im_names对应改成需要检测图片的编号,否则会出现AttributeError: ‘NoneType’ object has no attribute ‘astype’
【图片保密,模糊处理】
4)!!!标注信息越界问题!!!:
越界有6种形式:x1<0; x2>width; x2<x1; y1<0; y2>height; y2<y1
源码中是针对pascal_voc数据写的,没有考虑数据标错的可能性
a.首先自己的数据都是从0开始的因此要修改lib/datasets/pascal_voc.py中_load_pascal_annotation函数,该函数是读取pascal_voc格式标注文件的,下面几句中的-1全部去掉(pascal_voc标注是1-based,所以需要-1转化成0-based,如果我们的数据标注是0-based,再-1就可能溢出,所以要去掉)。如果只是0-based的问题(而没有标注为负数或超出图像边界的坐标)
b.为了检测数据的越界形式并改进,修改lib/datasets/imdb.py,append_flipped_images函数,加入对对六种形式的检查
#源代码中没有获取图像高度信息的函数,补充上
def _get_heights(self):
return [PIL.Image.open(self.image_path_at(i)).size[1]
for i in range(self.num_images)]
def append_flipped_images(self):
num_images = self.num_images
widths = self._get_widths()
heights = self._get_heights()#add to get image height
for i in range(num_images):
boxes = self.roidb[i]['boxes'].copy()
oldx1 = boxes[:, 0].copy()
oldx2 = boxes[:, 2].copy()
print (self.image_index[i])#print image name
assert (boxes[:,1]<=boxes[:,3]).all()#assert that ymin<=ymax
assert (boxes[:,1]>=0).all()#assert ymin>=0,for 0-based
assert (boxes[:,3]<heights[i]).all()#assert ymax<height[i],for 0-based
assert (oldx2<widths[i]).all()#assert xmax<withd[i],for 0-based
assert (oldx1>=0).all()#assert xmin>=0, for 0-based
assert (oldx2 >= oldx1).all()#assert xmax>=xmin, for 0-based
boxes[:, 0] = widths[i] - oldx2 - 1
boxes[:, 2] = widths[i] - oldx1 - 1
#print ("num_image:%d"%(i))
assert (boxes[:, 2] >= boxes[:, 0]).all()
entry = {'boxes' : boxes,
'gt_overlaps' : self.roidb[i]['gt_overlaps'],
'gt_classes' : self.roidb[i]['gt_classes'],
'flipped' : True}
self.roidb.append(entry)
self._image_index = self._image_index * 2
然后运行,遇到y有标注错误的地方就会报AssertError,然后看日志上最后一个打印的图像名,到对应的Annotation上查看错误标记,改过来后不要忘记删除data/cache缓存,然后就是重复再重复…
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
开始排坑啦
1.AssertionError: Path does not exist: /home/dl-box/wei/py-faster-rcnn/data/VOCdevkit2007/VOC2007/JPEGImages/000001.jpg
很奇怪的错误,文件明明在但是就是读取不成功,后来发现是编码问题,将tf-faster-rcnn/data/VOCdevkit2007/VOC2007/ImageSets和Annotations中的txt文件和xml均转成ASCII编码
2.KeyError:’\ufeffdropper’
更改为ASCII编码后还是出现了问题,不明白呀奇怪!!!
修改/data/tf-faster-rcnn-master/lib/datasets/pascal_voc.py
度娘说这么改,可能还是编码的问题吧吧吧
终于开始跑了鸭,冲鸭!
3. 在调用append_flipped_images函数时出现: assert (boxes[:, 2] >= boxes[:, 0]).all()
出现这个问题主要是自己的数据集标注出错。由于我们使用自己的数据集,可能出现x坐标为0的情况,而pascal_voc数据标注都是从1开始计数的,所以faster rcnn代码里会转化成0-based形式,对Xmin,Xmax,Ymin,Ymax进行-1操作,从而会出现溢出,如果x=0,减1后溢出为65535。更有甚者,标记坐标为负数或者超出图像范围。主要解决方法有:
(1)修改lib/datasets/imdb.py,在boxes[:, 2] = widths[i] - oldx1 - 1后插入:
for b in range(len(boxes)):
if boxes[b][2]< boxes[b][0]:
boxes[b][0] = 0
(2)注释掉1(见3>4)>a)
4.loss_bbox = nan,result: Mean AP=0.000
还是自己的数据集标注越界的问题!!(见3>4))
Faster-RCNN训练自己数据集遇到的问题集锦:
5. AttributeError: ‘NoneType’ object has no attribute 'astype’
运行demo时报错,是因为demo中图片名字的问题,仔细检查路径和文件名,查看demo.py里路径相关的文件
切记每次更改训练时删除data/cache和output/res101/,否则会报错