转载请注明:
参考:
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-gpu
1.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=0ByuDEGFYmWsbNVF5eExySUtMZmMhttps://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 参考:

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_faster rcnn 


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

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_GPU_02


修改成自己的类,保留’background’类

2)lib/datasets/imdb.py

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_faster rcnn _03


将num_classes改为自己的类别数加1,上面只是一个类,因此是2

3)修改tools/demo.py

a.类型修改同(1)

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_数据_04


b.在(1)处更改训练好的模型名称

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_数据集_05


c.修改默认的数据集DATASETS和NETS,即default=‘pascal_voc’ , default=‘res101’

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_数据_06


d.更改类型数目(num_classes),

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_tensoflow _07


e.在tf-faster-rcnn/data/demo/文件夹中放入需要检测的数据图片,将tool/demo.py中im_names对应改成需要检测图片的编号,否则会出现AttributeError: ‘NoneType’ object has no attribute ‘astype’

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_tensoflow _08


【图片保密,模糊处理】

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的问题(而没有标注为负数或超出图像边界的坐标)

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_tensoflow _09


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

如何设置在cpu上训练tensorflow 模型 tensorflow怎么用gpu训练_faster rcnn _10


度娘说这么改,可能还是编码的问题吧吧吧

终于开始跑了鸭,冲鸭!

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/,否则会报错