window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)

Table of Contents

一、PASCAL VOC 2007/2012格式数据集制作 

二、训练自己的数据集

三、end2end训练

四、测试


环境:

系统:windows10 64bit

GPU: NNIFIA GTX1080Ti

框架:caffe

语言:python

Faster RCNN源码:https://github.com/rbgirshick/py-faster-rcnn

一、PASCAL VOC 2007/2012格式数据集制作 

PASCAL VOC 2007/2012数据集的制作:VOC2007格式数据集制作
window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第1张图片
将制作的数据集放在py-faster-rcnn-master\data下。最后完整的路径是py-faster-rcnn-master\data\VOCdevkit2007

二、训练自己的数据集

Faster RCNN默认有三种网络模型 ZF(小)、VGG_CNN_M_1024(中)、VGG16 (大)

每一个Faster RCNN模型都有两种训练方式:

  • 一种是交替优化方法(alternating optimization),即训练两个网络,一个是rpn,一个是fast rcnn,总计两个stage,每个stage各训练一次rpn和fast rcnn。
  • 另外一种训练方式为近似联合训练(approximate joint training),也称end to end的训练方式,训练过程中只训练一个权重网络,训练速度有可观的提升,而训练精度不变。

此处以VGG_CNN_M_1024的end2ent(也叫近似联合训练)为例。

  1. 修改模型配置文件
    以vgg_cnn_m_1024为例,用end2end的方式训练。
    (1) 打开py-faster-rcnn-master\models\pascal_voc\VGG_CNN_M_1024\faster_rcnn_end2end\train.prototxt修改4处
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第2张图片
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第3张图片
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第4张图片
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第5张图片

    (2)打开py-faster-rcnn-master\models\pascal_voc\VGG_CNN_M_1024\faster_rcnn_end2end\ test.prototxt修改2处。
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第6张图片window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第7张图片

     

  2. 修改py-faster-rcnn-master\lib\datasets下的imdb.py文件
    在使用自己的数据进行训练时,基本上都会报错:assert(boxes[:,2] >= boxes[:,0]).all() ,主要是因为自己的图片数据没有统一整理过而导致的,将该文件加入几行修改如下:
    找到append_flipped_images这个函数
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第8张图片
  3. 修改py-faster-rcnn-master\lib\rpn如图所示2个文件和py-faster-rcnn-master\lib\roi_data_layer 下的layer.py文件,将其中的param_str_全部改为param_str。
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第9张图片
    修改后的的anchor_target_layer.py和proposal_target_layer.py分别如下:
    anchor_target_layer.py
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第10张图片
    proposal_target_layer.py
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第11张图片
    layer.py
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第12张图片

    注:有些博客说修改rpn文件夹如下的5个文件,将文件中param_str_全部改为param_str,其实只有2个文件中包含有 
           param_str_

    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第13张图片
  4. 修改py-faster-rcnn-master\lib\fast_rcnn文件夹下的config.py

    将训练和测试的proposals方法改为gt
    # Train using these proposals
    # __C.TRAIN.PROPOSAL_METHOD = 'selective_search'
    __C.TRAIN.PROPOSAL_METHOD = 'gt'
    # Test using these proposals
    # __C.TEST.PROPOSAL_METHOD = 'selective_search'
    __C.TEST.PROPOSAL_METHOD = 'gt'
  5. 修改py-faster-rcnn-master\lib\datasets下的pascal_voc.py
    在self.classes里,'__background__'是我们的背景类,不要动他。下面的改为你自己标签的内容。如下图:
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第14张图片

    为避免路径出错问题,如下图:
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第15张图片

    解决方案一:
    检查py-faster-rcnn-master\data\VOCdevkit2007目录下是否存在results\VOC2007\Main\,如果不存在,需要手动创建。形成py-faster-rcnn-master\data\VOCdevkit2007\results\VOC2007\Main\

    解决方案二:
    如下修改的同时,需要在py-faster-rcnn-master\data\VOCdevkit2007\VOC2007目录下创建一个Main文件夹window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第16张图片

    将写入方式修改为w+,如下图:
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第17张图片

  6. 为避免以下类似问题
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第18张图片

    解决方案:打开py-faster-rcnn-master\lib\datasets下的pascal_voc.py,

    # 找到_do_python_eval函数,将以下源码
        def _do_python_eval(self, output_dir = 'output'):
            annopath = os.path.join(
                self._devkit_path,
                'VOC' + self._year,
                'Annotations',
                '{:s}.xml')
    # 改成如下
        def _do_python_eval(self, output_dir = 'output'):
            annopath = os.path.join(
                self._devkit_path,
                'VOC' + self._year,
                'Annotations',
                '{}.xml')

    为何要这样修改:主要是在windows下,执行annopath = os.path.join('path1','path2','{:s}.xml'),得到的结果是{:s}.xml,而不是path1\path2\{:s}.xml(这个结果是我们想要的),如下所示:
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第19张图片
    而在linux环境下,执行annopath = os.path.join('path1','path2','{:s}.xml'),得到的结果是path1\path2\{:s}.xml,如下:
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第20张图片
    所以源码在linux环境下能跑通,在windows环境下会出现找不到路径的错误,如上图中No such file or directory:'000016.xml'的错误。

三、end2end训练

  1. 删除缓存文件

    (1) py-faster-rcnn-master\output文件夹删除,

    (2)删除py-faster-rcnn-master\data\cache中的文件

    (3)删除py-faster-rcnn-master\data\VOCdevkit2007\annotations_cache中的文件

  2. 开始训练
    打开打开git bash输入,去到py-faster-rcnn-master根目录下,运行以下的语句

    ./experiments/scripts/faster_rcnn_end2end.sh 0 VGG_CNN_M_1024 pascal_voc

    当然你可以去experiments\scripts\faster_rcnn_end2end.sh中调自己的训练的一些参数,也可以用VGG16、ZF模型去训练。我这里就用默认给的参数说明。
    出现以下这种界面,那就是训练成功了。
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第21张图片

  3. 训练中可测碰到的错误
    错误一:

    I1116 20:28:35.41Loading pretrained model weights from data/imagenet_models/VGG_CNN_M_1024.v2.caffemodel

    *** Check failure stack trace: ***
    这是因为没有找到预训练的model
    解决办法:下载imagenet_models.rar解压至py-faster-rcnn-master\data目录下
    下载地址:https://dl.dropbox.com/s/gstw7122padlf0l/imagenet_models.tgz?dl=0

    错误二:
    TypeError: slice indices must be integers or None or have an __index__ method
    解决办法:
    在文件夹py-faster-rcnn-master\lib\roi_data_layer中找到minibatch.py第172行和proposal_target_layer.py第123行,修改代码。

    # 将_get_bbox_regression_labels函数和_get_bbox_regression_labels函数中的以下代码   
        for ind in inds:
            cls = clss[ind]
            start = 4 * cls
            end = start + 4
            bbox_targets[ind, start:end] = bbox_target_data[ind, 1:]
            bbox_inside_weights[ind, start:end] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS
    # 修改为以下的代码
        for ind in inds:
            ind = int(ind)
            cls = clss[ind]
            start = int(4 * cls)
            end = int(start + 4)
            bbox_targets[ind, start:end] = bbox_target_data[ind, 1:]
            bbox_inside_weights[ind, start:end] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS

    错误三:
    No module named cython_bbox
    解决:把自己编译后的py-faster-rcnn-master\lib\build\lib.win-amd64-2.7\下面有三个文件夹nms,pycocotools,utils,拷贝到py-faster-rcnn\lib目录下即可,其实就是编译生成的pyd文件放到指定的位置

四、测试

  1. 创建自己的demo.py
     

    如果想方便的话,直接把已经有的demo.py复制一份,并把它的标签改为自己的标签,把模型改为自己的模型。这是我的demo,类别和模型部分,供参考

    CLASSES = ('__background__',             
               'knife')                         # 第一个背景类不需要修改,其它修改为自己识别的类
     
    NETS = {'vgg16': ('VGG16',
                      'VGG16_faster_rcnn_final.caffemodel'),
    	'vgg1024':('VGG_CNN_M_1024',                            # 在这里添加自己的训练出来的模型
    		 'vgg_cnn_m_1024_faster_rcnn_iter_70000.caffemodel'),
            'zf': ('ZF',
                      'ZF_faster_rcnn_final.caffemodel')}
    
    def parse_args():
        """Parse input arguments."""
        parser = argparse.ArgumentParser(description='Faster R-CNN demo')
        parser.add_argument('--gpu', dest='gpu_id', help='GPU device id to use [0]',
                            default=0, type=int)
        parser.add_argument('--cpu', dest='cpu_mode',
                            help='Use CPU mode (overrides --gpu)',
                            action='store_true')
        parser.add_argument('--net', dest='demo_net', help='Network to use [vgg16]',
                            choices=NETS.keys(), default='vgg1024')   # 将这里的默认改为vgg1024,因为我们使用的是vgg1024
    
        args = parser.parse_args()
    
        return args

    在这个部分,将你要测试的图片写在im_names里,并把图片放在data\demo这个文件夹下。 

    if __name__ == '__main__':
        cfg.TEST.HAS_RPN = True  # Use RPN for proposals
     
        args = parse_args()
     
        prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
                                'faster_rcnn_end2end', 'test.prototxt')  # 这里修改为自己的测试prototxt
        caffemodel = os.path.join(cfg.DATA_DIR, 'faster_rcnn_models',
                                  NETS[args.demo_net][1])
     
        if not os.path.isfile(caffemodel):
            raise IOError(('{:s} not found.\nDid you run ./data/script/'
                           'fetch_faster_rcnn_models.sh?').format(caffemodel))
     
        if args.cpu_mode:
            caffe.set_mode_cpu()
        else:
            caffe.set_mode_gpu()
            caffe.set_device(args.gpu_id)
            cfg.GPU_ID = args.gpu_id
        net = caffe.Net(prototxt, caffemodel, caffe.TEST)
     
        print '\n\nLoaded network {:s}'.format(caffemodel)
     
        # Warmup on a dummy image
        im = 128 * np.ones((300, 500, 3), dtype=np.uint8)
        for i in xrange(2):
            _, _= im_detect(net, im)
     
        im_names = ['000016.jpg','000024.jpg']  # 这里修改为自己需要识别的图片,并将其放入data/demo目录下
        for im_name in im_names:
            print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
            print 'Demo for data/demo/{}'.format(im_name)
            demo(net, im_name)
     
        plt.show()
    

     

  2. 输出的模型
    训练好的模型在py-faster-rcnn-master\output\目录下
    将output\里你刚刚训练好的caffemodel复制到data\faster_rcnn_models

  3. 结果
    在cmd中,py-faster-rcnn-master\tools目录下执行以下命令

    python demo.py

    即可得到结果
    window10 + GPU + caffe + python + py-faster-rcnn下Faster-RCNN训练自己的数据集(end2end训练)_第22张图片

你可能感兴趣的:(py-faster-rcnn,caffe)