wider face data 在 faster rcnn 上的实践记录(caffe)

按照githup上playerkk的工程进行实践,地址为:https://github.com/playerkk/face-py-faster-rcnn/blob/master/README.md

1.搭建faster rcnn

这个没什么好说的,参考rbg大神的官网即可,附上地址:https://github.com/rbgirshick/py-faster-rcnn

需要注意的是对于显卡是1080的,因为faster rcnn是基于老版本的cudnn,所以编译的时候会出现许多关于cudnn的报错问题。解决方案推荐的是用caffe中相关的文件替换掉faster rcnn中的相关文件。可参考地址:http://blog.csdn.NET/u010733679/article/details/52221404。

2.克隆工程及下载预训练参数文件

git clone --recursive https://github.com/playerkk/face-py-faster-rcnn.git
在工程的根目录下执行:

cd face-py-faster-rcnn

./data/scripts/fetch_faster_rcnn_models.sh


会在data下出现 faster rcnn models.tgz。

3.下载wider face data数据

网站下载地址为:http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/


下载三个数据文件到一个目录中,我选择的是ubuntu的home目录下:


如图所示进行分布。

图中的最后一个文本文件从该网址下载:https://people.cs.umass.edu/~hzjiang//files/wider_face_train_annot.txt 。按照的是FDDB的格式。



在如图所示的data目录下建立symlinks:


会在工程的data目录下出现链接,如上图所示。

4.下载预训练的Imagenet模型


在工程目录下执行上图所示命令。


接下来就是开始执行训练的过程:

在工程的根目录下执行命令:



++++++++++++++++++++++++2017.0224++++++++++++++++++++更新+++++++++++++++++++++++++++

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

更新工程后我的train_net.py文件内容为:

[python] view plain copy
  1. #!/usr/bin/env python  
  2.   
  3. # --------------------------------------------------------  
  4. # Fast R-CNN  
  5. # Copyright (c) 2015 Microsoft  
  6. # Licensed under The MIT License [see LICENSE for details]  
  7. # Written by Ross Girshick  
  8. # --------------------------------------------------------  
  9.   
  10. """Train a Fast R-CNN network on a region of interest database."""  
  11. # import matplotlib   
  12. # matplotlib.use('Agg')   
  13.   
  14. import _init_paths  
  15. from fast_rcnn.train import get_training_roidb, train_net  
  16. from fast_rcnn.config import cfg, cfg_from_file, cfg_from_list, get_output_dir  
  17. from datasets.factory import get_imdb  
  18. import datasets.imdb  
  19. import caffe  
  20. import argparse  
  21. import pprint  
  22. import numpy as np  
  23. import sys  
  24.   
  25. def parse_args():  
  26.     """ 
  27.     Parse input arguments 
  28.     """  
  29.     parser = argparse.ArgumentParser(description='Train a Fast R-CNN network')  
  30.     parser.add_argument('--gpu', dest='gpu_id',  
  31.                         help='GPU device id to use [0]',  
  32.                         default=0, type=int)  
  33.     parser.add_argument('--solver', dest='solver',  
  34.                         help='solver prototxt',  
  35.                         default=None, type=str)  
  36.     parser.add_argument('--iters', dest='max_iters',  
  37.                         help='number of iterations to train',  
  38.                         default=40000, type=int)  
  39.     parser.add_argument('--weights', dest='pretrained_model',  
  40.                         help='initialize with pretrained model weights',  
  41.                         default=None, type=str)  
  42.     parser.add_argument('--cfg', dest='cfg_file',  
  43.                         help='optional config file',  
  44.                         default=None, type=str)  
  45.     parser.add_argument('--imdb', dest='imdb_name',  
  46.                         help='dataset to train on',  
  47.                         default='voc_2007_trainval', type=str)  
  48.     parser.add_argument('--rand', dest='randomize',  
  49.                         help='randomize (do not use a fixed seed)',  
  50.                         action='store_true')  
  51.     parser.add_argument('--set', dest='set_cfgs',  
  52.                         help='set config keys', default=None,  
  53.                         nargs=argparse.REMAINDER)  
  54.   
  55.     if len(sys.argv) == 1:  
  56.         parser.print_help()  
  57.         sys.exit(1)  
  58.   
  59.     args = parser.parse_args()  
  60.     return args  
  61.   
  62. def combined_roidb(imdb_names):  
  63.     def get_roidb(imdb_name):  
  64.         imdb = get_imdb(imdb_name)  
  65.         print 'Loaded dataset `{:s}` for training'.format(imdb.name)  
  66.         imdb.set_proposal_method(cfg.TRAIN.PROPOSAL_METHOD)  
  67.         print 'Set proposal method: {:s}'.format(cfg.TRAIN.PROPOSAL_METHOD)  
  68.         roidb = get_training_roidb(imdb)  
  69.         return roidb  
  70.   
  71.     roidbs = [get_roidb(s) for s in imdb_names.split('+')]  
  72.     roidb = roidbs[0]  
  73.     if len(roidbs) > 1:  
  74.         for r in roidbs[1:]:  
  75.             roidb.extend(r)  
  76.         imdb = datasets.imdb.imdb(imdb_names)  
  77.     else:  
  78.         imdb = get_imdb(imdb_names)  
  79.     return imdb, roidb  
  80.   
  81. if __name__ == '__main__':  
  82.     args = parse_args()  
  83.   
  84.     print('Called with args:')  
  85.     print(args)  
  86.   
  87.     if args.cfg_file is not None:  
  88.         cfg_from_file(args.cfg_file)  
  89.     if args.set_cfgs is not None:  
  90.         cfg_from_list(args.set_cfgs)  
  91.   
  92.     cfg.GPU_ID = args.gpu_id  
  93.   
  94.     print('Using config:')  
  95.     pprint.pprint(cfg)  
  96.   
  97.     if not args.randomize:  
  98.         # fix the random seeds (numpy and caffe) for reproducibility  
  99.         np.random.seed(cfg.RNG_SEED)  
  100.         caffe.set_random_seed(cfg.RNG_SEED)  
  101.   
  102.     # set up caffe  
  103.     caffe.set_mode_gpu()  
  104.     caffe.set_device(args.gpu_id)  
  105.   
  106.     imdb, roidb = combined_roidb(args.imdb_name)  
  107.     print '{:d} roidb entries'.format(len(roidb))  
  108.   
  109.     output_dir = get_output_dir(imdb)  
  110.     print 'Output will be saved to `{:s}`'.format(output_dir)  
  111.   
  112.     train_net(args.solver, roidb, output_dir,  
  113.               pretrained_model=args.pretrained_model,  
  114.               max_iters=args.max_iters)  
face.py:

[python] view plain copy
  1. # --------------------------------------------------------  
  2. # Fast R-CNN  
  3. # Copyright (c) 2015 Microsoft  
  4. # Licensed under The MIT License [see LICENSE for details]  
  5. # Written by Ross Girshick  
  6. # --------------------------------------------------------  
  7.   
  8. # import datasets.face  
  9. # import os  
  10. # import datasets.imdb as imdb  
  11. # import xml.dom.minidom as minidom  
  12. # import numpy as np  
  13. # import scipy.sparse  
  14. # import scipy.io as sio  
  15. # import utils.cython_bbox  
  16. # import cPickle  
  17. # import subprocess  
  18.   
  19. import os  
  20. from datasets.imdb import imdb  
  21. import datasets.ds_utils as ds_utils  
  22. import xml.etree.ElementTree as ET  
  23. import numpy as np  
  24. import scipy.sparse  
  25. import scipy.io as sio  
  26. import utils.cython_bbox  
  27. import cPickle  
  28. import subprocess  
  29. import uuid  
  30. from voc_eval import voc_eval  
  31. from fast_rcnn.config import cfg  
  32. import cv2  
  33. import PIL  
  34.   
  35. class face(imdb):  
  36.     def __init__(self, image_set, split, devkit_path):  
  37.         imdb.__init__(self'wider')  
  38.         self._image_set = image_set         # {'train', 'test'}  
  39.         self._split = split                 # {1, 2, ..., 10}  
  40.         self._devkit_path = devkit_path     # /data2/hzjiang/Data/CS2  
  41.         # self._data_path = os.path.join(self._devkit_path, 'data')  
  42.         self._data_path = self._devkit_path;  
  43.         self._classes = ('__background__'# always index 0  
  44.                          'face')  
  45.         self._class_to_ind = dict(zip(self.classes, xrange(self.num_classes)))  
  46.         self._image_ext = ['.png']  
  47.         self._image_index, self._gt_roidb = self._load_image_set_index()  
  48.         # Default to roidb handler  
  49.         self._roidb_handler = self.selective_search_roidb  
  50.   
  51.         # Specific config options  
  52.         self.config = {'cleanup'  : True,  
  53.                        'use_salt' : True,  
  54.                        'top_k'    : 2000}  
  55.   
  56.         assert os.path.exists(self._devkit_path), \  
  57.                 'Devkit path does not exist: {}'.format(self._devkit_path)  
  58.         assert os.path.exists(self._data_path), \  
  59.                 'Path does not exist: {}'.format(self._data_path)  
  60.   
  61.     def image_path_at(self, i):  
  62.         """ 
  63.         Return the absolute path to image i in the image sequence. 
  64.         """  
  65.         return self.image_path_from_index(self._image_index[i])  
  66.   
  67.     def image_path_from_index(self, index):  
  68.         """ 
  69.         Construct an image path from the image's "index" identifier. 
  70.         """  
  71.         for ext in self._image_ext:  
  72.             image_path = os.path.join(self._data_path, index)  
  73.             if os.path.exists(image_path):  
  74.                 break  
  75.         assert os.path.exists(image_path), \  
  76.                 'Path does not exist: {}'.format(image_path)  
  77.   
  78.         return image_path  
  79.   
  80.     def _load_image_set_index(self):  
  81.         """ 
  82.         Load the indexes listed in this dataset's image set file. 
  83.         """  
  84.         # # Example path to image set file:  
  85.         # # self._data_path + /ImageSets/val.txt  
  86.         # # read from file  
  87.         # image_set_file = 'split%d/%s_%d_annot.txt' % (self._fold, self._image_set, self._fold)  
  88.         # # image_set_file = os.path.join(self._devkit_path, image_set_file)  
  89.         # image_set_file = os.path.join('/home/hzjiang/Code/py-faster-rcnn/CS3-splits', image_set_file)  
  90.         image_set_file = self._name + '_face_' + self._image_set + '_annot.txt'  
  91.         image_set_file = os.path.join(self._devkit_path, image_set_file)  
  92.   
  93.         # image_set_file = 'cs3_rand_train_annot.txt'  
  94.         # image_set_file = 'wider_dets_annot_from_cs3_model.txt'  
  95.         # image_set_file = 'wider_manual_annot.txt'  
  96.   
  97.         assert os.path.exists(image_set_file), \  
  98.                 'Path does not exist: {}'.format(image_set_file)  
  99.   
  100.         image_index = []  
  101.         gt_roidb = []  
  102.           
  103.         with open(image_set_file) as f:  
  104.             # print len(f.lines())  
  105.             lines = f.readlines()  
  106.   
  107.             idx = 0  
  108.             while idx < len(lines):  
  109.                 image_name = lines[idx].split('\n')[0]  
  110.                 image_name = os.path.join('WIDER_%s/images' % self._image_set, image_name)  
  111.                 # print image_name  
  112.                 image_ext = os.path.splitext(image_name)[1].lower()  
  113.                 # print image_ext  
  114.                 assert(image_ext == '.png' or image_ext == '.jpg' or image_ext == '.jpeg')  
  115.   
  116.                 image = PIL.Image.open(os.path.join(self._data_path, image_name))  
  117.                 imw = image.size[0]  
  118.                 imh = image.size[1]  
  119.   
  120.                 idx += 1  
  121.                 num_boxes = int(lines[idx])  
  122.                 # print num_boxes  
  123.   
  124.                 boxes = np.zeros((num_boxes, 4), dtype=np.uint16)  
  125.                 gt_classes = np.zeros((num_boxes), dtype=np.int32)  
  126.                 overlaps = np.zeros((num_boxes, self.num_classes), dtype=np.float32)  
  127.   
  128.                 for i in xrange(num_boxes):  
  129.                     idx += 1  
  130.                     coor = map(float, lines[idx].split())  
  131.   
  132.                     x1 = min(max(coor[0], 0), imw - 1)  
  133.                     y1 = min(max(coor[1], 0), imh - 1)  
  134.                     x2 = min(max(x1 + coor[2] - 10), imw - 1)  
  135.                     y2 = min(max(y1 + coor[3] - 10), imh - 1)  
  136.   
  137.                     if np.isnan(x1):  
  138.                         x1 = -1  
  139.   
  140.                     if np.isnan(y1):  
  141.                         y1 = -1  
  142.   
  143.                     if np.isnan(x2):  
  144.                         x2 = -1  
  145.   
  146.                     if np.isnan(y2):  
  147.                         y2 = -1  
  148.                           
  149.                     cls = self._class_to_ind['face']  
  150.                     boxes[i, :] = [x1, y1, x2, y2]  
  151.                     gt_classes[i] = cls  
  152.                     overlaps[i, cls] = 1.0  
  153.   
  154.                 widths = boxes[:, 2] - boxes[:, 0] + 1  
  155.                 heights = boxes[:, 3] - boxes[:, 1] + 1  
  156.                 keep_idx = np.where(np.bitwise_and(widths > 5, heights > 5))  
  157.   
  158.                 if len(keep_idx[0]) <= 0:  
  159.                     idx += 1  
  160.                     continue  
  161.   
  162.                 boxes = boxes[keep_idx]  
  163.                 gt_classes = gt_classes[keep_idx[0]]  
  164.                 overlaps = overlaps[keep_idx[0], :]  
  165.   
  166.   
  167.   
  168.                 if not (boxes[:, 2] >= boxes[:, 0]).all():  
  169.                     print boxes  
  170.                     print image_name  
  171.   
  172.                 # print boxes  
  173.                 assert (boxes[:, 2] >= boxes[:, 0]).all()  
  174.                 assert (boxes[:, 3] >= boxes[:, 1]).all()  
  175.   
  176.                 overlaps = scipy.sparse.csr_matrix(overlaps)  
  177.                 gt_roidb.append({'boxes' : boxes,  
  178.                                 'gt_classes': gt_classes,  
  179.                                 'gt_overlaps' : overlaps,  
  180.                                 'flipped' : False,  
  181.                                 'image_name': image_name})  
  182.                 image_index.append(image_name)  
  183.   
  184.                 idx += 1          
  185.   
  186.             assert(idx == len(lines))  
  187.   
  188.         return image_index, gt_roidb  
  189.   
  190.     def gt_roidb(self):  
  191.         """ 
  192.         Return the database of ground-truth regions of interest. 
  193.  
  194.         This function loads/saves from/to a cache file to speed up future calls. 
  195.         """  
  196.         cache_file = os.path.join(self.cache_path, self.name + '_gt_roidb.pkl')  
  197.         if os.path.exists(cache_file):  
  198.             with open(cache_file, 'rb') as fid:  
  199.                 roidb = cPickle.load(fid)  
  200.             print '{} gt roidb loaded from {}'.format(self.name, cache_file)  
  201.             return roidb  
  202.   
  203.         with open(cache_file, 'wb') as fid:  
  204.             cPickle.dump(self._gt_roidb, fid, cPickle.HIGHEST_PROTOCOL)  
  205.         print 'wrote gt roidb to {}'.format(cache_file)  
  206.   
  207.         return self._gt_roidb  
  208.   
  209.     def selective_search_roidb(self):  
  210.         """ 
  211.         Return the database of selective search regions of interest. 
  212.         Ground-truth ROIs are also included. 
  213.  
  214.         This function loads/saves from/to a cache file to speed up future calls. 
  215.         """  
  216.         cache_file = os.path.join(self.cache_path,  
  217.                                   self.name + '_selective_search_roidb.pkl')  
  218.   
  219.         if os.path.exists(cache_file):  
  220.             with open(cache_file, 'rb') as fid:  
  221.                 roidb = cPickle.load(fid)  
  222.             print '{} ss roidb loaded from {}'.format(self.name, cache_file)  
  223.             return roidb  
  224.   
  225.         if self._image_set != 'test':  
  226.             gt_roidb = self.gt_roidb()  
  227.             ss_roidb = self._load_selective_search_roidb(gt_roidb)  
  228.             roidb = datasets.imdb.merge_roidbs(gt_roidb, ss_roidb)  
  229.         else:  
  230.             roidb = self._load_selective_search_roidb(None)  
  231.             print len(roidb)  
  232.   
  233.         with open(cache_file, 'wb') as fid:  
  234.             cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL)  
  235.         print 'wrote ss roidb to {}'.format(cache_file)  
  236.   
  237.         return roidb  
  238.   
  239.     def _load_selective_search_roidb(self, gt_roidb):  
  240.         filename = os.path.abspath(os.path.join(self._devkit_path,  
  241.                                                 self.name + '.mat'))  
  242.         assert os.path.exists(filename), \  
  243.                'Selective search data not found at: {}'.format(filename)  
  244.   
  245.         raw_data = sio.loadmat(filename)['all_boxes'].ravel()  
  246.   
  247.         box_list = []  
  248.         for i in xrange(raw_data.shape[0]):  
  249.             boxes = raw_data[i][:, (1032)] - 1  
  250.             assert (boxes[:, 2] >= boxes[:, 0]).all()  
  251.             box_list.append(boxes)  
  252.   
  253.         return self.create_roidb_from_box_list(box_list, gt_roidb)  
  254.   
  255.     def selective_search_IJCV_roidb(self):  
  256.         """ 
  257.         Return the database of selective search regions of interest. 
  258.         Ground-truth ROIs are also included. 
  259.  
  260.         This function loads/saves from/to a cache file to speed up future calls. 
  261.         """  
  262.         cache_file = os.path.join(self.cache_path,  
  263.                 '{:s}_selective_search_IJCV_top_{:d}_roidb.pkl'.  
  264.                 format(self.name, self.config['top_k']))  
  265.   
  266.         if os.path.exists(cache_file):  
  267.             with open(cache_file, 'rb') as fid:  
  268.                 roidb = cPickle.load(fid)  
  269.             print '{} ss roidb loaded from {}'.format(self.name, cache_file)  
  270.             return roidb  
  271.   
  272.         gt_roidb = self.gt_roidb()  
  273.         ss_roidb = self._load_selective_search_IJCV_roidb(gt_roidb)  
  274.         roidb = datasets.imdb.merge_roidbs(gt_roidb, ss_roidb)  
  275.         with open(cache_file, 'wb') as fid:  
  276.             cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL)  
  277.         print 'wrote ss roidb to {}'.format(cache_file)  
  278.   
  279.         return roidb  
  280.   
  281.     def _load_selective_search_IJCV_roidb(self, gt_roidb):  
  282.         IJCV_path = os.path.abspath(os.path.join(self.cache_path, '..',  
  283.                                                  'selective_search_IJCV_data',  
  284.                                                  self.name))  
  285.         assert os.path.exists(IJCV_path), \  
  286.                'Selective search IJCV data not found at: {}'.format(IJCV_path)  
  287.   
  288.         top_k = self.config['top_k']  
  289.         box_list = []  
  290.         for i in xrange(self.num_images):  
  291.             filename = os.path.join(IJCV_path, self.image_index[i] + '.mat')  
  292.             raw_data = sio.loadmat(filename)  
  293.             box_list.append((raw_data['boxes'][:top_k, :]-1).astype(np.uint16))  
  294.   
  295.         return self.create_roidb_from_box_list(box_list, gt_roidb)  
  296.   
  297.     def _load_face_annotation(self, index):  
  298.         """ 
  299.         Load image and bounding boxes info from txt files of face. 
  300.         """  
  301.         filename = os.path.join(self._data_path, 'Annotations', index + '.mat')  
  302.   
  303.         data = sio.loadmat(filename)  
  304.   
  305.         num_objs = data['gt'].shape[0]  
  306.   
  307.         boxes = np.zeros((num_objs, 4), dtype=np.uint16)  
  308.         gt_classes = np.zeros((num_objs), dtype=np.int32)  
  309.         overlaps = np.zeros((num_objs, self.num_classes), dtype=np.float32)  
  310.   
  311.         # Load object bounding boxes into a data frame.  
  312.         for ix in xrange(num_objs):  
  313.             # Make pixel indexes 0-based  
  314.             coor = data['gt'][ix, :]  
  315.             x1 = float(coor[0]) - 1  
  316.             y1 = float(coor[1]) - 1  
  317.             x2 = float(coor[2]) - 1  
  318.             y2 = float(coor[3]) - 1  
  319.             cls = self._class_to_ind['face']  
  320.             boxes[ix, :] = [x1, y1, x2, y2]  
  321.             gt_classes[ix] = cls  
  322.             overlaps[ix, cls] = 1.0  
  323.   
  324.         overlaps = scipy.sparse.csr_matrix(overlaps)  
  325.   
  326.         if not (boxes[:, 2] >= boxes[:, 0]).all():  
  327.             print boxes  
  328.             print filename  
  329.   
  330.         assert (boxes[:, 2] >= boxes[:, 0]).all()  
  331.   
  332.         return {'boxes' : boxes,  
  333.                 'gt_classes': gt_classes,  
  334.                 'gt_overlaps' : overlaps,  
  335.                 'flipped' : False}  
  336.   
  337.     def _write_inria_results_file(self, all_boxes):  
  338.         use_salt = self.config['use_salt']  
  339.         comp_id = 'comp4'  
  340.         if use_salt:  
  341.             comp_id += '-{}'.format(os.getpid())  
  342.   
  343.         # VOCdevkit/results/comp4-44503_det_test_aeroplane.txt  
  344.         path = os.path.join(self._devkit_path, 'results'self.name, comp_id + '_')  
  345.         for cls_ind, cls in enumerate(self.classes):  
  346.             if cls == '__background__':  
  347.                 continue  
  348.             print 'Writing {} results file'.format(cls)  
  349.             filename = path + 'det_' + self._image_set + '_' + cls + '.txt'  
  350.             with open(filename, 'wt') as f:  
  351.                 for im_ind, index in enumerate(self.image_index):  
  352.                     dets = all_boxes[cls_ind][im_ind]  
  353.                     if dets == []:  
  354.                         continue  
  355.                     # the VOCdevkit expects 1-based indices  
  356.                     for k in xrange(dets.shape[0]):  
  357.                         f.write('{:s} {:.3f} {:.1f} {:.1f} {:.1f} {:.1f}\n'.  
  358.                                 format(index, dets[k, -1],  
  359.                                        dets[k, 0] + 1, dets[k, 1] + 1,  
  360.                                        dets[k, 2] + 1, dets[k, 3] + 1))  
  361.         return comp_id  
  362.   
  363.     def _do_matlab_eval(self, comp_id, output_dir='output'):  
  364.         rm_results = self.config['cleanup']  
  365.   
  366.         path = os.path.join(os.path.dirname(__file__),  
  367.                             'VOCdevkit-matlab-wrapper')  
  368.         cmd = 'cd {} && '.format(path)  
  369.         cmd += '{:s} -nodisplay -nodesktop '.format(datasets.MATLAB)  
  370.         cmd += '-r "dbstop if error; '  
  371.         cmd += 'setenv(\'LC_ALL\',\'C\'); voc_eval(\'{:s}\',\'{:s}\',\'{:s}\',\'{:s}\',{:d}); quit;"' \  
  372.                .format(self._devkit_path, comp_id,  
  373.                        self._image_set, output_dir, int(rm_results))  
  374.         print('Running:\n{}'.format(cmd))  
  375.         status = subprocess.call(cmd, shell=True)  
  376.   
  377.     def evaluate_detections(self, all_boxes, output_dir):  
  378.         comp_id = self._write_inria_results_file(all_boxes)  
  379.         self._do_matlab_eval(comp_id, output_dir)  
  380.   
  381.     def competition_mode(self, on):  
  382.         if on:  
  383.             self.config['use_salt'] = False  
  384.             self.config['cleanup'] = False  
  385.         else:  
  386.             self.config['use_salt'] = True  
  387.             self.config['cleanup'] = True  
  388.   
  389. if __name__ == '__main__':  
  390.     d = datasets.inria('train''')  
  391.     res = d.roidb  
  392.     from IPython import embed; embed()  

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

之后在命令行中输入:

voole@zhx:~/face-py-faster-rcnn$ ./experiments/scripts/faster_rcnn_end2end.sh 0 VGG16 wider


输出:





问题已经得到解决了:原因是因为我安装的easydict的版本是1.4,即使我配置了faster_rcnn_end2end.yml,但是easydict并没有将参数传给train_net.py,所以才会出现上述问题,解决方案就是升级你的easydict。

你可能感兴趣的:(深度学习,#,Caffe框架,深度学习目标检测)