def multi_gpu_generate_rpn_on_dataset( weights_file, dataset_name, _proposal_file_ignored, num_images, output_dir ): """Multi-gpu inference on a dataset.""" # Retrieve the test_net binary path binary_dir = envu.get_runtime_dir() binary_ext = envu.get_py_bin_ext() binary = os.path.join(binary_dir, 'test_net' + binary_ext) assert os.path.exists(binary), 'Binary \'{}\' not found'.format(binary) # Pass the target dataset via the command line opts = ['TEST.DATASETS', '("{}",)'.format(dataset_name)] opts += ['TEST.WEIGHTS', weights_file] # Run inference in parallel in subprocesses outputs = subprocess_utils.process_in_parallel( 'rpn_proposals', num_images, binary, output_dir, opts ) # Collate the results from each subprocess boxes, scores, ids = [], [], [] for rpn_data in outputs: boxes += rpn_data['boxes'] scores += rpn_data['scores'] ids += rpn_data['ids'] rpn_file = os.path.join(output_dir, 'rpn_proposals.pkl') cfg_yaml = yaml.dump(cfg) save_object( dict(boxes=boxes, scores=scores, ids=ids, cfg=cfg_yaml), rpn_file ) logger.info('Wrote RPN proposals to {}'.format(os.path.abspath(rpn_file))) return boxes, scores, ids, rpn_file
def save_model_to_weights_file(weights_file, model): """Stash model weights in a dictionary and pickle them to a file. We map GPU device scoped names to unscoped names (e.g., 'gpu_0/conv1_w' -> 'conv1_w'). """ logger.info('Saving parameters and momentum to {}'.format( os.path.abspath(weights_file))) blobs = {} # Save all parameters for param in model.params: scoped_name = str(param) unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s}'.format(scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save momentum for param in model.TrainableParams(): scoped_name = str(param) + '_momentum' unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s}'.format(scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save preserved blobs for scoped_name in workspace.Blobs(): if scoped_name.startswith('__preserve__/'): unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s} (preserved)'.format( scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) cfg_yaml = yaml.dump(cfg) save_object(dict(blobs=blobs, cfg=cfg_yaml), weights_file)
def save_model_to_weights_file(weights_file, model): """Stash model weights in a dictionary and pickle them to a file. We map GPU device scoped names to unscoped names (e.g., 'gpu_0/conv1_w' -> 'conv1_w'). """ logger.info( 'Saving parameters and momentum to {}'.format( os.path.abspath(weights_file))) blobs = {} # Save all parameters for param in model.params: scoped_name = str(param) unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s}'.format(scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save momentum for param in model.TrainableParams(): scoped_name = str(param) + '_momentum' unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s}'.format(scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save preserved blobs for scoped_name in workspace.Blobs(): if scoped_name.startswith('__preserve__/'): unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug( ' {:s} -> {:s} (preserved)'.format( scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) cfg_yaml = yaml.dump(cfg) save_object(dict(blobs=blobs, cfg=cfg_yaml), weights_file)
def multi_gpu_generate_rpn_on_dataset(weights_file, dataset_name, _proposal_file_ignored, num_images, output_dir): """Multi-gpu inference on a dataset.""" # Retrieve the test_net binary path binary_dir = envu.get_runtime_dir() binary_ext = envu.get_py_bin_ext() binary = os.path.join(binary_dir, 'test_net' + binary_ext) assert os.path.exists(binary), 'Binary \'{}\' not found'.format(binary) # Pass the target dataset via the command line opts = ['TEST.DATASETS', '("{}",)'.format(dataset_name)] opts += ['TEST.WEIGHTS', weights_file] # Run inference in parallel in subprocesses outputs = subprocess_utils.process_in_parallel('rpn_proposals', num_images, binary, output_dir, opts) # Collate the results from each subprocess boxes, scores, ids = [], [], [] for rpn_data in outputs: boxes += rpn_data['boxes'] scores += rpn_data['scores'] ids += rpn_data['ids'] rpn_file = os.path.join(output_dir, 'rpn_proposals.pkl') cfg_yaml = envu.yaml_dump(cfg) save_object(dict(boxes=boxes, scores=scores, ids=ids, cfg=cfg_yaml), rpn_file) logger.info('Wrote RPN proposals to {}'.format(os.path.abspath(rpn_file))) return boxes, scores, ids, rpn_file
def main(args): merge_cfg_from_file(args.cfg) cfg.NUM_GPUS = 1 for i, weights_file in enumerate(args.weights_list): args.weights_list[i] = cache_url(weights_file, cfg.DOWNLOAD_CACHE) assert_and_infer_cfg(cache_urls=False) preffix_list = args.preffix_list if len(args.preffix_list) \ else [""] * len(args.weights_list) model = model_builder.create(cfg.MODEL.TYPE, train=False) # Initialize GPU from weights files for i, weights_file in enumerate(args.weights_list): nu.initialize_gpu_from_weights_file(model, weights_file, gpu_id=0, preffix=preffix_list[i]) nu.broadcast_parameters(model) blobs = {} # Save all parameters for param in model.params: scoped_name = str(param) unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: if workspace.HasBlob(scoped_name): blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save merged weights file save_object(dict(blobs=blobs), args.output_wts)
def pickle_weights(out_file_name, weights): blobs = { normalize_resnet_name(blob.name): utils.Caffe2TensorToNumpyArray(blob) for blob in weights.protos } save_object(blobs, out_file_name) print('Wrote blobs:') print(sorted(blobs.keys()))
def evaluate_proposal_file(dataset, proposal_file, output_dir): """Evaluate box proposal average recall.""" roidb = dataset.get_roidb(gt=True, proposal_file=proposal_file) results = task_evaluation.evaluate_box_proposals(dataset, roidb) task_evaluation.log_box_proposal_results(results) recall_file = os.path.join(output_dir, 'rpn_proposal_recall.pkl') save_object(results, recall_file) return results
def pickle_weights(out_file_name, weights): blobs = { normalize_resnet_name(blob.name): utils.Caffe2TensorToNumpyArray(blob) for blob in weights.protos } save_object(blobs, out_file_name) print('Wrote blobs:') print(sorted(blobs.keys()))
def evaluate_proposal_file(dataset, proposal_file, output_dir): """Evaluate box proposal average recall.""" roidb = dataset.get_roidb(gt=True, proposal_file=proposal_file) results = task_evaluation.evaluate_box_proposals(dataset, roidb) task_evaluation.log_box_proposal_results(results) recall_file = os.path.join(output_dir, 'rpn_proposal_recall.pkl') save_object(results, recall_file) return results
def _do_detection_eval(json_dataset, res_file, output_dir): coco_dt = json_dataset.COCO.loadRes(str(res_file)) coco_eval = COCOeval(json_dataset.COCO, coco_dt, 'bbox') coco_eval.evaluate() coco_eval.accumulate() _log_detection_eval_metrics(json_dataset, coco_eval) eval_file = os.path.join(output_dir, 'detection_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote json eval results to: {}'.format(eval_file)) return coco_eval
def _do_detection_eval(json_dataset, res_file, output_dir): coco_dt = json_dataset.COCO.loadRes(str(res_file)) coco_eval = COCOeval(json_dataset.COCO, coco_dt, 'bbox') coco_eval.evaluate() coco_eval.accumulate() _log_detection_eval_metrics(json_dataset, coco_eval) eval_file = os.path.join(output_dir, 'detection_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote json eval results to: {}'.format(eval_file)) return coco_eval
def multi_gpu_test_net_on_dataset( weights_file, dataset_name, proposal_file, num_images, output_dir ): """Multi-gpu inference on a dataset.""" binary_dir = envu.get_runtime_dir() binary_ext = envu.get_py_bin_ext() binary = os.path.join(binary_dir, 'test_net' + binary_ext) assert os.path.exists(binary), 'Binary \'{}\' not found'.format(binary) # Pass the target dataset and proposal file (if any) via the command line opts = ['TEST.DATASETS', '("{}",)'.format(dataset_name)] opts += ['TEST.WEIGHTS', weights_file] if proposal_file: opts += ['TEST.PROPOSAL_FILES', '("{}",)'.format(proposal_file)] # Run inference in parallel in subprocesses # Outputs will be a list of outputs from each subprocess, where the output # of each subprocess is the dictionary saved by test_net(). if os.path.exists(os.path.join(output_dir, 'detections.pkl')): out_result = cPickle.load(open(os.path.join(output_dir, 'detections.pkl'))) return out_result['all_boxes'], out_result['all_segms'], out_result['all_keyps'], out_result['all_bodys'] outputs = subprocess_utils.process_in_parallel( 'detection', num_images, binary, output_dir, opts ) # Collate the results from each subprocess all_boxes = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] all_segms = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] all_keyps = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] all_bodys = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] for det_data in outputs: all_boxes_batch = det_data['all_boxes'] all_segms_batch = det_data['all_segms'] all_keyps_batch = det_data['all_keyps'] all_bodys_batch = det_data['all_bodys'] for cls_idx in range(1, cfg.MODEL.NUM_CLASSES): all_boxes[cls_idx] += all_boxes_batch[cls_idx] all_segms[cls_idx] += all_segms_batch[cls_idx] all_keyps[cls_idx] += all_keyps_batch[cls_idx] all_bodys[cls_idx] += all_bodys_batch[cls_idx] det_file = os.path.join(output_dir, 'detections.pkl') cfg_yaml = yaml.dump(cfg) save_object( dict( all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, all_bodys=all_bodys, cfg=cfg_yaml ), det_file ) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps, all_bodys
def _do_personmask_eval(json_dataset, res_file, output_dir): coco_dt = json_dataset.COCO.loadRes(str(res_file)) coco_eval = denseposeCOCOeval(json_dataset.COCO, coco_dt, 'uvpm') coco_eval.evaluate() coco_eval.accumulate() #_log_detection_eval_metrics(json_dataset, coco_eval) eval_file = os.path.join(output_dir, 'personmask_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote json eval results to: {}'.format(eval_file)) coco_eval.summarize() return coco_eval
def _do_python_eval(json_dataset, salt, output_dir='output', subset_pointer=None): info = voc_info(json_dataset) year = info['year'] anno_path = info['anno_path'] image_set_path = info['image_set_path'] devkit_path = info['devkit_path'] cachedir = os.path.join(devkit_path, 'annotations_cache') aps = [] nposs = [] # The PASCAL VOC metric changed in 2010 use_07_metric = True if int(year) < 2010 else False logger.info('VOC07 metric? ' + ('Yes' if use_07_metric else 'No')) if not os.path.isdir(output_dir): os.mkdir(output_dir) for _, cls in enumerate(json_dataset.classes): if cls == '__background__': continue filename = _get_voc_results_file_template(json_dataset, salt).format(cls) rec, prec, ap, npos = voc_eval(filename, anno_path, image_set_path, cls, cachedir, ovthresh=0.5, use_07_metric=use_07_metric, subset_pointer=subset_pointer) aps += [ap] nposs.append(npos) logger.info('AP for {} {} = {:.4f}'.format(npos, cls, ap)) res_file = os.path.join(output_dir, cls + '_pr.pkl') save_object({'rec': rec, 'prec': prec, 'ap': ap}, res_file) logger.info('Mean AP = {:.4f}'.format(np.mean(aps))) nposs = np.array(nposs, dtype=float) nposs /= nposs.sum() logger.info('Weighted Mean AP = {:.4f}'.format( (np.array(aps) * nposs).sum())) logger.info('~~~~~~~~') logger.info('Results:') for ap in aps: logger.info('{:.3f}'.format(ap)) logger.info('{:.3f}'.format(np.mean(aps))) logger.info('~~~~~~~~') logger.info('') logger.info('----------------------------------------------------------') logger.info('Results computed with the **unofficial** Python eval code.') logger.info('Results should be very close to the official MATLAB code.') logger.info('Use `./tools/reval.py --matlab ...` for your paper.') logger.info('-- Thanks, The Management') logger.info('----------------------------------------------------------')
def multi_gpu_test_net_on_dataset( weights_file, dataset_name, proposal_file, num_images, output_dir ): """Multi-gpu inference on a dataset.""" binary_dir = envu.get_runtime_dir() binary_ext = envu.get_py_bin_ext() binary = os.path.join(binary_dir, 'test_net' + binary_ext) assert os.path.exists(binary), 'Binary \'{}\' not found'.format(binary) # Pass the target dataset and proposal file (if any) via the command line opts = ['TEST.DATASETS', '("{}",)'.format(dataset_name)] opts += ['TEST.WEIGHTS', weights_file] if proposal_file: opts += ['TEST.PROPOSAL_FILES', '("{}",)'.format(proposal_file)] # Run inference in parallel in subprocesses # Outputs will be a list of outputs from each subprocess, where the output # of each subprocess is the dictionary saved by test_net(). outputs = subprocess_utils.process_in_parallel( 'detection', num_images, binary, output_dir, opts ) # Collate the results from each subprocess all_boxes = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] all_segms = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] all_keyps = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] all_bodys = [[] for _ in range(cfg.MODEL.NUM_CLASSES)] for det_data in outputs: all_boxes_batch = det_data['all_boxes'] all_segms_batch = det_data['all_segms'] all_keyps_batch = det_data['all_keyps'] all_bodys_batch = det_data['all_bodys'] for cls_idx in range(1, cfg.MODEL.NUM_CLASSES): all_boxes[cls_idx] += all_boxes_batch[cls_idx] all_segms[cls_idx] += all_segms_batch[cls_idx] all_keyps[cls_idx] += all_keyps_batch[cls_idx] all_bodys[cls_idx] += all_bodys_batch[cls_idx] det_file = os.path.join(output_dir, 'detections.pkl') cfg_yaml = yaml.dump(cfg) save_object( dict( all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, all_bodys=all_bodys, cfg=cfg_yaml ), det_file ) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps, all_bodys
def _do_keypoint_eval(json_dataset, res_file, output_dir): ann_type = 'keypoints' imgIds = json_dataset.COCO.getImgIds() imgIds.sort() coco_dt = json_dataset.COCO.loadRes(res_file) coco_eval = COCOeval(json_dataset.COCO, coco_dt, ann_type) coco_eval.params.imgIds = imgIds coco_eval.evaluate() coco_eval.accumulate() eval_file = os.path.join(output_dir, 'keypoint_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote json eval results to: {}'.format(eval_file)) coco_eval.summarize() return coco_eval
def _do_keypoint_eval(json_dataset, res_file, output_dir): ann_type = 'keypoints' imgIds = json_dataset.COCO.getImgIds() imgIds.sort() coco_dt = json_dataset.COCO.loadRes(res_file) coco_eval = COCOeval(json_dataset.COCO, coco_dt, ann_type) coco_eval.params.imgIds = imgIds coco_eval.evaluate() coco_eval.accumulate() eval_file = os.path.join(output_dir, 'keypoint_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote json eval results to: {}'.format(eval_file)) coco_eval.summarize() return coco_eval
def _do_python_eval_corloc(json_dataset, salt, output_dir='output'): info = voc_info(json_dataset) year = info['year'] anno_path = info['anno_path'] image_set_path = info['image_set_path'] devkit_path = info['devkit_path'] cachedir = os.path.join(devkit_path, 'annotations_cache') corlocs = [] too_min_rates = [] # The PASCAL VOC metric changed in 2010 use_07_metric = True if int(year) < 2010 else False logger.info('VOC07 metric? ' + ('Yes' if use_07_metric else 'No')) if not os.path.isdir(output_dir): os.mkdir(output_dir) for _, cls in enumerate(json_dataset.classes): if cls == '__background__': continue filename = _get_voc_results_file_template( json_dataset, salt).format(cls) corloc, too_min_rate = voc_eval_corloc( filename, anno_path, image_set_path, cls, cachedir, ovthresh=0.5, use_07_metric=use_07_metric) corlocs += [corloc] too_min_rates += [too_min_rate] logger.info('CorLoc for {} = {:.4f}'.format(cls, corloc)) logger.info('too_min_rate for {} = {:.4f}'.format(cls, too_min_rate)) res_file = os.path.join(output_dir, cls + '_corloc.pkl') save_object({'corloc': corloc}, res_file) logger.info('Mean CorLoc = {:.4f}'.format(np.mean(corlocs))) logger.info('Mean too_min_rate = {:.4f}'.format(np.mean(too_min_rates))) logger.info('~~~~~~~~') logger.info('Results:') for corloc in corlocs: logger.info('{:.3f}'.format(corloc)) logger.info('{:.3f}'.format(np.mean(corlocs))) logger.info('~~~~~~~~') logger.info('') logger.info('----------------------------------------------------------') logger.info('Results computed with the **unofficial** Python eval code.') logger.info('Results should be very close to the official MATLAB code.') logger.info('Use `./tools/reval.py --matlab ...` for your paper.') logger.info('-- Thanks, The Management') logger.info('----------------------------------------------------------') print('Results:') for corloc in corlocs: print('{:.2f}&'.format(corloc * 100.0), end = '') print('{:.2f}'.format(np.mean(corlocs) * 100.0))
def generate_rpn_on_range( weights_file, dataset_name, _proposal_file_ignored, output_dir, ind_range=None, gpu_id=0 ): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert cfg.MODEL.RPN_ONLY or cfg.MODEL.FASTER_RCNN roidb, start_ind, end_ind, total_num_images = get_roidb( dataset_name, ind_range ) logger.info( 'Output will be saved to: {:s}'.format(os.path.abspath(output_dir)) ) model = model_builder.create(cfg.MODEL.TYPE, train=False, gpu_id=gpu_id) nu.initialize_gpu_from_weights_file( model, weights_file, gpu_id=gpu_id, ) model_builder.add_inference_inputs(model) workspace.CreateNet(model.net) boxes, scores, ids = generate_proposals_on_roidb( model, roidb, start_ind=start_ind, end_ind=end_ind, total_num_images=total_num_images, gpu_id=gpu_id, ) cfg_yaml = yaml.dump(cfg) if ind_range is not None: rpn_name = 'rpn_proposals_range_%s_%s.pkl' % tuple(ind_range) else: rpn_name = 'rpn_proposals.pkl' rpn_file = os.path.join(output_dir, rpn_name) save_object( dict(boxes=boxes, scores=scores, ids=ids, cfg=cfg_yaml), rpn_file ) logger.info('Wrote RPN proposals to {}'.format(os.path.abspath(rpn_file))) return boxes, scores, ids, rpn_file
def generate_rpn_on_range( weights_file, dataset_name, _proposal_file_ignored, output_dir, ind_range=None, gpu_id=0 ): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert cfg.MODEL.RPN_ONLY or cfg.MODEL.FASTER_RCNN roidb, start_ind, end_ind, total_num_images = get_roidb( dataset_name, ind_range ) logger.info( 'Output will be saved to: {:s}'.format(os.path.abspath(output_dir)) ) model = model_builder.create(cfg.MODEL.TYPE, train=False, gpu_id=gpu_id) nu.initialize_gpu_from_weights_file( model, weights_file, gpu_id=gpu_id, ) model_builder.add_inference_inputs(model) workspace.CreateNet(model.net) boxes, scores, ids = generate_proposals_on_roidb( model, roidb, start_ind=start_ind, end_ind=end_ind, total_num_images=total_num_images, gpu_id=gpu_id, ) cfg_yaml = envu.yaml_dump(cfg) if ind_range is not None: rpn_name = 'rpn_proposals_range_%s_%s.pkl' % tuple(ind_range) else: rpn_name = 'rpn_proposals.pkl' rpn_file = os.path.join(output_dir, rpn_name) save_object( dict(boxes=boxes, scores=scores, ids=ids, cfg=cfg_yaml), rpn_file ) logger.info('Wrote RPN proposals to {}'.format(os.path.abspath(rpn_file))) return boxes, scores, ids, rpn_file
def precompute_maskrcnn_backbone_features(config, dataset, split): feat_type = config['feat_type'] # assert that the dimensions are ok otherwise break s, nI, nT = min( len(dataset), config['it']), config['n_input_frames'], config['n_target_frames'] # Automatically get feature dimensions sample_input, _, _ = dataset.next() sample_features = sample_input[feat_type] assert sample_features.dim() == 4, "Batch mode is expected" sz = sample_features.size() assert (sz[0] == 1, 'This function assumes batch mode, but a single example per batch') c, h, w = sz[1] / nI, sz[2], sz[3] assert c == config['nb_features'] dataset.reset() # Check that the dataset to compute will be under 100GB - floating point takes 4B - check assert s * (nI+nT) * c * h * w * 4 <= 1e11, \ 'The dataset to compute will take over 100 GB - aborting' # Initialize tensors seq_features = np.empty((s, (nI + nT), c, h, w), dtype=np.float32) seq_ids = ['' for _ in range(s)] for i, data in enumerate(dataset): inputs, targets, _ = data correspondingSample = dataset.data_source[i] # insert in the dataset inp_feat = inputs[feat_type].view( (nI, c, h, w)).numpy().astype(np.float32) tar_feat = targets[feat_type].view( (nT, c, h, w)).numpy().astype(np.float32) seq_features[i] = np.concatenate((inp_feat, tar_feat), 0) seq_ids[i] = correspondingSample[u'annID'][0] if i >= (config['it'] - 1): break # save the precomputed features fr = config['frame_ss'] filename = os.path.join( opt['save'], '__'.join( (split, feat_type, 'nSeq%d' % (nI + nT), 'fr%d' % fr))) logger.info('Precomputed features saved to : %s' % filename) save_object(dict(sequence_ids=seq_ids), filename + '__ids.pkl') np.save(filename + '__features.npy', seq_features)
def save_model_to_weights_file(weights_file, model, cur_iter=None): """Stash model weights in a dictionary and pickle them to a file. We map GPU device scoped names to unscoped names (e.g., 'gpu_0/conv1_w' -> 'conv1_w'). """ logger.info('Saving parameters and momentum to {}'.format( os.path.abspath(weights_file))) blobs = {} # Save all parameters for param in model.params: scoped_name = str(param) unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s}'.format(scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save momentum for param in model.TrainableParams(): scoped_name = str(param) + '_momentum' unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s}'.format(scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save preserved blobs for scoped_name in workspace.Blobs(): if scoped_name.startswith('__preserve__/'): unscoped_name = c2_utils.UnscopeName(scoped_name) if unscoped_name not in blobs: logger.debug(' {:s} -> {:s} (preserved)'.format( scoped_name, unscoped_name)) blobs[unscoped_name] = workspace.FetchBlob(scoped_name) # Save roidb shuffling: if 'roidb_state' not in blobs and type(cur_iter) != type(None): blobs['roidb_state'] = model.roi_data_loader.get_perm_state( cur_iter + 1) # give iters_done. else: logger.info("roidb state not stored") if cfg.TRAIN.PADA: if 'weight_db' not in blobs: blobs['weight_db'] = model.class_weight_db.get_state() cfg_yaml = envu.yaml_dump(cfg) save_object(dict(blobs=blobs, cfg=cfg_yaml), weights_file)
def _do_body_uv_eval(json_dataset, res_file, output_dir): ann_type = 'uv' imgIds = json_dataset.COCO.getImgIds() imgIds.sort() res = load_object(res_file) coco_dt = json_dataset.COCO.loadRes(res) # Non-standard params used by the modified COCO API version # from the DensePose fork # global normalization factor used in per-instance evaluation test_sigma = 0.255 coco_eval = denseposeCOCOeval(json_dataset.COCO, coco_dt, ann_type, test_sigma) coco_eval.params.imgIds = imgIds coco_eval.evaluate() coco_eval.accumulate() eval_file = os.path.join(output_dir, 'body_uv_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote pickle eval results to: {}'.format(eval_file)) coco_eval.summarize() return coco_eval
def _write_coco_body_uv_results_file(json_dataset, all_boxes, all_bodys, res_file): results = [] for cls_ind, cls in enumerate(json_dataset.classes): if cls == '__background__': continue if cls_ind >= len(all_bodys): break logger.info('Collecting {} results ({:d}/{:d})'.format( cls, cls_ind, len(all_bodys) - 1)) cat_id = json_dataset.category_to_id_map[cls] results.extend( _coco_body_uv_results_one_category(json_dataset, all_boxes[cls_ind], all_bodys[cls_ind], cat_id)) # Body UV results are stored in 3xHxW ndarray format, # which is not json serializable logger.info('Writing body uv results pkl to: {}'.format( os.path.abspath(res_file))) save_object(results, res_file)
def evaluate_proposal_file(dataset, proposal_file, output_dir): """Evaluate box proposal average recall.""" roidb = dataset.get_roidb(gt=True, proposal_file=proposal_file) results = task_evaluation.evaluate_box_proposals(dataset, roidb) task_evaluation.log_box_proposal_results(results) recall_file = os.path.join(output_dir, 'rpn_proposal_recall.pkl') save_object(results, recall_file) all_boxes = np.array([[], smd.prep_proposal_file(proposal_file, output_dir, top_k=100)]) """Plot Precision Recall curve for proposal file""" smd.evaluate_boxes(dataset, all_boxes, output_dir) smd.draw_histos(filepath=output_dir) """Plot recall-proposals curve""" boxes = np.array(all_boxes[1:][0]) scores = boxes[:, :, -1] boxes = boxes[:, :, :-1] smd.plot_rec_prop_curve(boxes, scores, dataset, output_dir, n=40) return results
def _do_python_eval(json_dataset, salt, output_dir='output'): info = voc_info(json_dataset) year = info['year'] anno_path = info['anno_path'] image_set_path = info['image_set_path'] devkit_path = info['devkit_path'] cachedir = os.path.join(devkit_path, 'annotations_cache') aps = [] # The PASCAL VOC metric changed in 2010 use_07_metric = True if int(year) < 2010 else False logger.info('VOC07 metric? ' + ('Yes' if use_07_metric else 'No')) if not os.path.isdir(output_dir): os.mkdir(output_dir) for _, cls in enumerate(json_dataset.classes): if cls == '__background__': continue filename = _get_voc_results_file_template( json_dataset, salt).format(cls) rec, prec, ap = voc_eval( filename, anno_path, image_set_path, cls, cachedir, ovthresh=0.5, use_07_metric=use_07_metric) aps += [ap] logger.info('AP for {} = {:.4f}'.format(cls, ap)) res_file = os.path.join(output_dir, cls + '_pr.pkl') save_object({'rec': rec, 'prec': prec, 'ap': ap}, res_file) logger.info('Mean AP = {:.4f}'.format(np.mean(aps))) logger.info('~~~~~~~~') logger.info('Results:') for ap in aps: logger.info('{:.3f}'.format(ap)) logger.info('{:.3f}'.format(np.mean(aps))) logger.info('~~~~~~~~') logger.info('') logger.info('----------------------------------------------------------') logger.info('Results computed with the **unofficial** Python eval code.') logger.info('Results should be very close to the official MATLAB code.') logger.info('Use `./tools/reval.py --matlab ...` for your paper.') logger.info('-- Thanks, The Management') logger.info('----------------------------------------------------------')
def save_annotated_frame_results(self, config, output_dir='./quantitative_eval/', st=None, en=None): det_filename = 'detections' det_filename += '_%d' % st if not st is None else '' det_filename += '_%d' % en if not en is None else '' det_filename += '.pkl' det_file = os.path.join(output_dir, det_filename) cfg_yaml = yaml.dump(cfg) save_object( dict(all_boxes=self.all_boxes_ann_frame, all_segms=self.all_segms_ann_frame, cfg=cfg_yaml, all_ids=self.id_sequences, config=config), det_file) self.all_boxes_ann_frame, self.all_segms_ann_frame, _ = empty_results( self.num_classes, self.num_images) self.id_sequences = [] logger.info('Wrote detections to: {}'.format( os.path.abspath(det_file)))
def _do_detection_eval(json_dataset, res_file, output_dir): coco_dt = json_dataset.COCO.loadRes(str(res_file)) coco_eval = COCOeval(json_dataset.COCO, coco_dt, 'bbox') print("==============Evaluating localization metrics=============") # TT: Evaluate localization P/R coco_eval.params.useCats = 0 coco_eval.evaluate() coco_eval.accumulate() coco_eval.summarize() _log_pr_curve_for_aml(coco_eval, "Localization PR curve") coco_eval = COCOeval(json_dataset.COCO, coco_dt, 'bbox') print("==============Evaluating overall metrics=============") coco_eval.params.useCats = 1 coco_eval.evaluate() coco_eval.accumulate() _log_detection_eval_metrics(json_dataset, coco_eval) _log_pr_curve_for_aml(coco_eval, "Final PR curve") eval_file = os.path.join(output_dir, 'detection_results.pkl') save_object(coco_eval, eval_file) logger.info('Wrote json eval results to: {}'.format(eval_file)) return coco_eval
def test_net(weights_file, dataset_name, proposal_file, output_dir, ind_range=None, gpu_id=0): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert not cfg.MODEL.RPN_ONLY, \ 'Use rpn_generate to generate proposals from RPN-only models' roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, ind_range) model = initialize_model_from_cfg(weights_file, gpu_id=gpu_id) num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES all_boxes, all_segms, all_keyps, all_personmasks, all_parss, all_bodys = \ empty_results(num_classes, num_images) timers = defaultdict(Timer) txt_all = [] parsing_i_png = None for i, entry in enumerate(roidb): if 'has_no_densepose' in entry.keys(): pass else: if cfg.TEST.PRECOMPUTED_PROPOSALS: # The roidb may contain ground-truth rois (for example, if the roidb # comes from the training or val split). We only want to evaluate # detection on the *non*-ground-truth rois. We select only the rois # that have the gt_classes field set to 0, which means there's no # ground truth. box_proposals = entry['boxes'][entry['gt_classes'] == 0] if len(box_proposals) == 0: continue else: # Faster R-CNN type models generate proposals on-the-fly with an # in-network RPN; 1-stage models don't require proposals. box_proposals = None im = cv2.imread(entry['image']) with c2_utils.NamedCudaScope(gpu_id): cls_boxes_i, cls_segms_i, cls_keyps_i, cls_personmask_i, cls_parss_i, cls_bodys_i = \ im_detect_all(model, im, box_proposals, timers) if cfg.MODEL.PARSING_ON: parsing_i_png, txt_result = parsing_utils.parsing2png( cls_boxes_i, cls_parss_i, output_dir, entry['image'], im.shape[:2]) ''' person_mask_i_png, txt_result_pm = parsing_utils.parsing2png( cls_boxes_i, cls_personmask_i, output_dir, entry['image'], im.shape[:2],flag_pm=True, ) ''' txt_all.append(txt_result) extend_results(i, all_boxes, cls_boxes_i) if cls_segms_i is not None: extend_results(i, all_segms, cls_segms_i) if cls_keyps_i is not None: extend_results(i, all_keyps, cls_keyps_i) if cls_personmask_i is not None: extend_results(i, all_personmasks, cls_personmask_i) if cls_parss_i is not None: extend_results(i, all_parss, cls_parss_i) if cls_bodys_i is not None: extend_results(i, all_bodys, cls_bodys_i) if i % 10 == 0: # Reduce log file size ave_total_time = np.sum([t.average_time for t in timers.values()]) eta_seconds = ave_total_time * (num_images - i - 1) eta = str(datetime.timedelta(seconds=int(eta_seconds))) det_time = (timers['im_detect_bbox'].average_time + timers['im_detect_mask'].average_time + timers['im_detect_keypoints'].average_time + timers['im_detect_body_uv'].average_time) misc_time = (timers['misc_bbox'].average_time + timers['misc_mask'].average_time + timers['misc_keypoints'].average_time + timers['misc_body_uv'].average_time) logger.info(('im_detect: range [{:d}, {:d}] of {:d}: ' '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})').format( start_ind + 1, end_ind, total_num_images, start_ind + i + 1, start_ind + num_images, det_time, misc_time, eta)) if cfg.VIS and not 'has_no_densepose' in entry.keys(): im_name = os.path.splitext(os.path.basename(entry['image']))[0] vis_utils.vis_one_image(im[:, :, ::-1], '{:d}_{:s}'.format(i, im_name), os.path.join(output_dir, 'vis'), cls_boxes_i, segms=cls_personmask_i, keypoints=cls_keyps_i, body_uv=cls_bodys_i, part_segms=parsing_i_png, thresh=cfg.VIS_TH, box_alpha=0.8, dataset=dataset, show_class=True) cfg_yaml = yaml.dump(cfg) if ind_range is not None: det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range) else: det_name = 'detections.pkl' det_file = os.path.join(output_dir, det_name) save_object( dict(all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, all_personmasks=all_personmasks, all_parss=all_parss, all_bodys=all_bodys, cfg=cfg_yaml), det_file) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps, all_personmasks, all_parss, all_bodys
dest='input_model', help='Trained model weights', default='../output/models/R_50_C4_2x_original/model_final.pkl') parser.add_argument( '--output_model', dest='output_model', help='Ouput model weights', default='../output/models/R_50_C4_2x_original_RW/model_final.pkl') args = parser.parse_args() args.input_model = os.path.abspath(args.input_model) args.output_model = os.path.abspath(args.output_model) return args if __name__ == '__main__': args = parse_args() out_dir = os.path.dirname(args.output_model) os.makedirs(out_dir, exist_ok=True) wts = load_object(args.input_model) for blob in list(wts['blobs'].keys()): if blob.startswith('cls_score_') or blob.startswith('bbox_pred_'): del wts['blobs'][blob] save_object(wts, args.output_model) #with open(args.output_model, 'wb') as f: # pkl.dump(wts, f)
sizes=(128, 256, 512, 1024), aspect_ratios=(0.5, 1, 2), layout=['center', 'top', 'left', 'right'], beta=8, include_depth=args.include_depth) proposals = np.append(proposals, np.array(rois), axis=0) ## Clip the boxes to image boundaries img_width = img_info['width'] img_height = img_info['height'] proposals = clip_boxes_to_image(proposals, img_height, img_width) # # Plot the proposal boxes # img_path = os.path.join(args.imgs_dir, img_info['file_name']) # img = cv2.imread(img_path) # plotted_image = draw_xyxy_bbox(img, proposals.tolist(), lineWidth=2) # plotted_image = cv2.cvtColor(plotted_image, cv2.COLOR_BGR2RGB) # ax = plt.subplot(111) # ax.imshow(plotted_image) # save_fig('temp.pdf') # input('here') # plt.clf() boxes.append(proposals) scores.append(np.zeros((proposals.shape[0]), dtype=np.float32)) ids.append(img_id) print('Saving proposals to disk...') save_object(dict(boxes=boxes, scores=scores, ids=ids), output_file) print('Proposals saved to {}'.format(output_file))
import scipy.io as sio import sys from detectron.datasets.json_dataset import JsonDataset from detectron.utils.io import save_object if __name__ == '__main__': dataset_name = sys.argv[1] file_in = sys.argv[2] file_out = sys.argv[3] ds = JsonDataset(dataset_name) roidb = ds.get_roidb() raw_data = sio.loadmat(file_in)['boxes'].ravel() assert raw_data.shape[0] == len(roidb) boxes = [] scores = [] ids = [] for i in range(raw_data.shape[0]): if i % 1000 == 0: print('{}/{}'.format(i + 1, len(roidb))) # selective search boxes are 1-indexed and (y1, x1, y2, x2) i_boxes = raw_data[i][:, (1, 0, 3, 2)] - 1 boxes.append(i_boxes.astype(np.float32)) scores.append(np.zeros((i_boxes.shape[0]), dtype=np.float32)) ids.append(roidb[i]['id']) save_object(dict(boxes=boxes, scores=scores, indexes=ids), file_out)
def test_net( weights_file, dataset_name, proposal_file, output_dir, ind_range=None, gpu_id=0 ): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert not cfg.MODEL.RPN_ONLY, \ 'Use rpn_generate to generate proposals from RPN-only models' if cfg.TEST.IMS_PER_BATCH != 1: return test_net_batch(weights_file, dataset_name, proposal_file, output_dir, ind_range, gpu_id) roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, ind_range ) # roidb = roidb[:500] # roidb = [{'image': im} for im in glob.glob('/staging/leuven/stg_00027/imob/detectron/lib/datasets/data/coco/coco_val2014/*.png')][:500] model = initialize_model_from_cfg(weights_file, gpu_id=gpu_id) num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES all_boxes, all_segms, all_keyps = empty_results(num_classes, num_images) timers = defaultdict(Timer) for i, entry in enumerate(roidb): if cfg.TEST.PRECOMPUTED_PROPOSALS: # The roidb may contain ground-truth rois (for example, if the roidb # comes from the training or val split). We only want to evaluate # detection on the *non*-ground-truth rois. We select only the rois # that have the gt_classes field set to 0, which means there's no # ground truth. box_proposals = entry['boxes'][entry['gt_classes'] == 0] if len(box_proposals) == 0: continue else: # Faster R-CNN type models generate proposals on-the-fly with an # in-network RPN; 1-stage models don't require proposals. box_proposals = None im = cv2.imread(entry['image']) with c2_utils.NamedCudaScope(gpu_id): cls_boxes_i, cls_segms_i, cls_keyps_i = im_detect_all( model, im, box_proposals, timers ) extend_results(i, all_boxes, cls_boxes_i) if cls_segms_i is not None: extend_results(i, all_segms, cls_segms_i) if cls_keyps_i is not None: extend_results(i, all_keyps, cls_keyps_i) if i % 10 == 0: # Reduce log file size ave_total_time = np.sum([t.average_time for t in timers.values()]) eta_seconds = ave_total_time * (num_images - i - 1) eta = str(datetime.timedelta(seconds=int(eta_seconds))) det_time = ( timers['im_detect_bbox'].average_time + timers['im_detect_mask'].average_time + timers['im_detect_keypoints'].average_time ) misc_time = ( timers['misc_bbox'].average_time + timers['misc_mask'].average_time + timers['misc_keypoints'].average_time ) logger.info( ( 'im_detect: range [{:d}, {:d}] of {:d}: ' '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})' ).format( start_ind + 1, end_ind, total_num_images, start_ind + i + 1, start_ind + num_images, det_time, misc_time, eta ) ) if cfg.VIS: im_name = os.path.splitext(os.path.basename(entry['image']))[0] vis_utils.vis_one_image( im[:, :, ::-1], '{:d}_{:s}'.format(i, im_name), os.path.join(output_dir, 'vis'), cls_boxes_i, segms=cls_segms_i, keypoints=cls_keyps_i, thresh=cfg.VIS_TH, box_alpha=0.8, dataset=dataset, show_class=True ) cfg_yaml = envu.yaml_dump(cfg) if ind_range is not None: det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range) else: det_name = 'detections.pkl' det_file = os.path.join(output_dir, det_name) save_object( dict( all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, cfg=cfg_yaml ), det_file ) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps
def voc_eval(detpath, annopath, imagesetfile, classname, cachedir, ovthresh=0.5, use_07_metric=False, subset_pointer=None): """rec, prec, ap = voc_eval(detpath, annopath, imagesetfile, classname, [ovthresh], [use_07_metric]) Top level function that does the PASCAL VOC evaluation. detpath: Path to detections detpath.format(classname) should produce the detection results file. annopath: Path to annotations annopath.format(imagename) should be the xml annotations file. imagesetfile: Text file containing the list of images, one image per line. classname: Category name (duh) cachedir: Directory for caching the annotations [ovthresh]: Overlap threshold (default = 0.5) [use_07_metric]: Whether to use VOC07's 11 point AP computation (default False) """ # assumes detections are in detpath.format(classname) # assumes annotations are in annopath.format(imagename) # assumes imagesetfile is a text file with each line an image name # cachedir caches the annotations in a pickle file this_sub = None if subset_pointer is not None: this_sub = subset_pointer.subset # first load gt if not os.path.isdir(cachedir): os.mkdir(cachedir) imageset = os.path.splitext(os.path.basename(imagesetfile))[0] cachefile = os.path.join(cachedir, imageset + '_annots.pkl') # read list of images with open(imagesetfile, 'r') as f: lines = f.readlines() imagenames = [x.strip() for x in lines] if subset_pointer is not None: imagenames = [n for n,taken in zip(imagenames,this_sub) if taken] if not os.path.isfile(cachefile): # load annots recs = {} for i, imagename in enumerate(imagenames): recs[imagename] = parse_rec(annopath.format(imagename)) if i % 100 == 0: logger.info( 'Reading annotation for {:d}/{:d}'.format( i + 1, len(imagenames))) # save logger.info('Saving cached annotations to {:s}'.format(cachefile)) save_object(recs, cachefile) else: recs = load_object(cachefile) # extract gt objects for this class class_recs = {} npos = 0 for imagename in imagenames: R = [obj for obj in recs[imagename] if obj['name'] == classname] bbox = np.array([x['bbox'] for x in R]) difficult = np.array([x['difficult'] for x in R]).astype(np.bool) det = [False] * len(R) npos = npos + sum(~difficult) class_recs[imagename] = {'bbox': bbox, 'difficult': difficult, 'det': det} # read dets detfile = detpath.format(classname) with open(detfile, 'r') as f: lines = f.readlines() splitlines = [x.strip().split(' ') for x in lines] image_ids = [x[0] for x in splitlines] confidence = np.array([float(x[1]) for x in splitlines]) BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) # sort by confidence sorted_ind = np.argsort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] # go down dets and mark TPs and FPs nd = len(image_ids) tp = np.zeros(nd) fp = np.zeros(nd) for d in range(nd): R = class_recs[image_ids[d]] bb = BB[d, :].astype(float) ovmax = -np.inf BBGT = R['bbox'].astype(float) if BBGT.size > 0: # compute overlaps # intersection ixmin = np.maximum(BBGT[:, 0], bb[0]) iymin = np.maximum(BBGT[:, 1], bb[1]) ixmax = np.minimum(BBGT[:, 2], bb[2]) iymax = np.minimum(BBGT[:, 3], bb[3]) iw = np.maximum(ixmax - ixmin + 1., 0.) ih = np.maximum(iymax - iymin + 1., 0.) inters = iw * ih # union uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) + (BBGT[:, 2] - BBGT[:, 0] + 1.) * (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters) overlaps = inters / uni ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > ovthresh: if not R['difficult'][jmax]: if not R['det'][jmax]: tp[d] = 1. R['det'][jmax] = 1 else: fp[d] = 1. else: fp[d] = 1. # compute precision recall fp = np.cumsum(fp) tp = np.cumsum(tp) rec = tp / float(npos) # avoid divide by zero in case the first detection matches a difficult # ground truth prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) ap = voc_ap(rec, prec, use_07_metric) return rec, prec, ap, npos
with h5py.File(file_in, 'r') as f: raw_boxes = f['boxes'] num_imgs = len(raw_boxes) assert num_imgs == len(roidb) for ind in range(num_imgs): if ind % 1000 == 0: print('{}/{}'.format(ind + 1, len(roidb))) ## -------- Working down below img_boxes = f[raw_boxes[ind, 0]][()] try: swp_boxes = np.swapaxes(img_boxes, 0, 1) except: print(img_boxes) # print(swp_boxes) input('something') # selective search boxes are 1-indexed and (y1, x1, y2, x2) i_boxes = swp_boxes[:, (1, 0, 3, 2)] - 1 # input('something') boxes.append(i_boxes.astype(np.float32)) scores.append(np.zeros((i_boxes.shape[0]), dtype=np.float32)) ids.append(roidb[ind]['id']) save_object(dict(boxes=boxes, scores=scores, ids=ids), file_out)
def test_net( weights_file, dataset_name, proposal_file, output_dir, ind_range=None, gpu_id=0 ): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert not cfg.MODEL.RPN_ONLY, \ 'Use rpn_generate to generate proposals from RPN-only models' roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, ind_range ) model = initialize_model_from_cfg(weights_file, gpu_id=gpu_id) # pose_pred_model = generate_poseJPPNet_pred_model() num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES all_boxes, all_segms, all_keyps = empty_results(num_classes, num_images) timers = defaultdict(Timer) for i, entry in enumerate(roidb): if cfg.TEST.PRECOMPUTED_PROPOSALS: # The roidb may contain ground-truth rois (for example, if the roidb # comes from the training or val split). We only want to evaluate # detection on the *non*-ground-truth rois. We select only the rois # that have the gt_classes field set to 0, which means there's no # ground truth. box_proposals = entry['boxes'][entry['gt_classes'] == 0] if len(box_proposals) == 0: continue else: # Faster R-CNN type models generate proposals on-the-fly with an # in-network RPN; 1-stage models don't require proposals. box_proposals = None im = cv2.imread(entry['image']) with c2_utils.NamedCudaScope(gpu_id): cls_boxes_i, cls_segms_i, cls_keyps_i = im_detect_all( model, im, box_proposals, timers, entry ) # test_res_top.feedBlob_run(model, im, entry) mask_res_top = test_res_top.res_top_result(model, entry) extend_results(i, all_boxes, cls_boxes_i) if cls_segms_i is not None: extend_results(i, all_segms, cls_segms_i) if cls_keyps_i is not None: extend_results(i, all_keyps, cls_keyps_i) if i % 10 == 0: # Reduce log file size ave_total_time = np.sum([t.average_time for t in timers.values()]) eta_seconds = ave_total_time * (num_images - i - 1) eta = str(datetime.timedelta(seconds=int(eta_seconds))) det_time = ( timers['im_detect_bbox'].average_time + timers['im_detect_mask'].average_time + timers['im_detect_keypoints'].average_time ) misc_time = ( timers['misc_bbox'].average_time + timers['misc_mask'].average_time + timers['misc_keypoints'].average_time ) logger.info( ( 'im_detect: range [{:d}, {:d}] of {:d}: ' '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})' ).format( start_ind + 1, end_ind, total_num_images, start_ind + i + 1, start_ind + num_images, det_time, misc_time, eta ) ) if cfg.VIS: im_name = os.path.splitext(os.path.basename(entry['image']))[0] mask_png_20 = vis_utils.vis_one_image( im[:, :, ::-1], '{:d}_{:s}'.format(i, im_name), os.path.join(output_dir, 'vis_9k'), cls_boxes_i, segms=cls_segms_i, keypoints=cls_keyps_i, thresh=cfg.VIS_TH, box_alpha=0.8, dataset=dataset, show_class=True ) # fusion mask_fusion = mask_png_20 + mask_res_top mask_fusion_out = os.path.join(output_dir, 'fusion') if not os.path.exists(mask_fusion_out): os.makedirs(mask_fusion_out) # logger.info('fusion save to {}'.format(mask_fusion_out)) cv2.imwrite(os.path.join(mask_fusion_out, entry['id']+'.png'), mask_fusion.argmax(0)) cfg_yaml = yaml.dump(cfg) if ind_range is not None: det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range) else: det_name = 'detections.pkl' det_file = os.path.join(output_dir, det_name) save_object( dict( all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, cfg=cfg_yaml ), det_file ) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps
def test_net_batch( weights_file, dataset_name, proposal_file, output_dir, ind_range=None, gpu_id=0 ): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU, using batch inference """ assert not cfg.MODEL.RPN_ONLY, \ 'Use rpn_generate to generate proposals from RPN-only models' roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, ind_range ) # roidb = roidb[:500] # Debug purposes # roidb = [{'image': im} for im in glob.glob('/staging/leuven/stg_00027/imob/detectron/lib/datasets/data/coco/coco_val2014/*.png')][:500] model = initialize_model_from_cfg(weights_file, gpu_id=gpu_id) num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES all_boxes, all_segms, all_keyps = empty_results(num_classes, num_images) timers = defaultdict(Timer) ims = [] for i, entry in enumerate(roidb): if cfg.TEST.PRECOMPUTED_PROPOSALS: raise NotImplementedError('Precomputed proposals not implemented for batch inference, set TEST.IMS_PER_BATCH to 1') else: # Faster R-CNN type models generate proposals on-the-fly with an # in-network RPN; 1-stage models don't require proposals. box_proposals = None # im = cv2.imread(roidb[0]['image']) im = cv2.imread(entry['image']) ims.append(im) if not ((len(ims) == cfg.TEST.IMS_PER_BATCH) or (i == (num_images - 1))): continue with c2_utils.NamedCudaScope(gpu_id): cls_boxes_batch, cls_segms_batch, cls_keyps_batch = im_detect_all_batch( model, ims, box_proposals, timers ) for n in range(len(ims)): local_i = i - len(ims) + n + 1 cls_boxes_i = cls_boxes_batch[n] cls_segms_i = cls_segms_batch[n] if cls_segms_batch else None cls_keyps_i = cls_keyps_batch[n] if cls_keyps_batch else None extend_results(local_i, all_boxes, cls_boxes_i) if cls_segms_i is not None: extend_results(local_i, all_segms, cls_segms_i) if cls_keyps_i is not None: extend_results(local_i, all_keyps, cls_keyps_i) if local_i % (10 * cfg.TEST.IMS_PER_BATCH) == 0: # Reduce log file size ave_total_time = np.sum([t.average_time for t in timers.values()]) eta_seconds = int(ave_total_time * (num_images - local_i - 1) / float(cfg.TEST.IMS_PER_BATCH)) eta = str(datetime.timedelta(seconds=int(eta_seconds))) det_time = ( timers['im_detect_bbox'].average_time + timers['im_detect_mask'].average_time + timers['im_detect_keypoints'].average_time ) misc_time = ( timers['misc_bbox'].average_time + timers['misc_mask'].average_time + timers['misc_keypoints'].average_time ) logger.info( ( 'im_detect: range [{:d}, {:d}] of {:d}: ' '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})' ).format( start_ind + 1, end_ind, total_num_images, start_ind + local_i + 1, start_ind + num_images, det_time, misc_time, eta ) ) # This will now only show the last image of each batch if cfg.VIS: im_name = os.path.splitext(os.path.basename(entry['image']))[0] vis_utils.vis_one_image( im[:, :, ::-1], '{:d}_{:s}'.format(i, im_name), os.path.join(output_dir, 'vis'), cls_boxes_i, segms=cls_segms_i, keypoints=cls_keyps_i, thresh=cfg.VIS_TH, box_alpha=0.8, dataset=dataset, show_class=True ) ims = [] cfg_yaml = envu.yaml_dump(cfg) if ind_range is not None: det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range) else: det_name = 'detections.pkl' det_file = os.path.join(output_dir, det_name) save_object( dict( all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, cfg=cfg_yaml ), det_file ) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps
def test_net(weights_file, dataset_name, proposal_file, output_dir, ind_range=None, gpu_id=0, subset_pointer=None): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert not cfg.MODEL.RPN_ONLY, \ 'Use rpn_generate to generate proposals from RPN-only models' # determine file name if ind_range is not None: det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range) else: det_name = 'detections.pkl' det_file = os.path.join(output_dir, det_name) # load results if already present if os.path.exists(det_file): res = load_object(det_file) all_boxes, all_segms, all_keyps = res['all_boxes'], res[ 'all_segms'], res['all_keyps'] else: roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, ind_range) if subset_pointer is not None: voc_subset = subset_pointer.subset this_sub = voc_subset[:len(roidb)] # subset_pointer.subset = voc_subset[len(roidb):] # filter roidb: roidb = [roi for taking, roi in zip(this_sub, roidb) if taking] total_num_images = len(roidb) end_ind = total_num_images model = initialize_model_from_cfg(weights_file, gpu_id=gpu_id) num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES all_boxes, all_segms, all_keyps = empty_results( num_classes, num_images) if cfg.TEST.COLLECT_ALL: all_feats = [] all_class_weights = np.empty(shape=(num_images, num_classes), dtype=np.float32) timers = defaultdict(Timer) for i, entry in enumerate(roidb): if cfg.TEST.PRECOMPUTED_PROPOSALS: # The roidb may contain ground-truth rois (for example, if the roidb # comes from the training or val split). We only want to evaluate # detection on the *non*-ground-truth rois. We select only the rois # that have the gt_classes field set to 0, which means there's no # ground truth. box_proposals = entry['boxes'][entry['gt_classes'] == 0] if len(box_proposals) == 0: continue else: # Faster R-CNN type models generate proposals on-the-fly with an # in-network RPN; 1-stage models don't require proposals. box_proposals = None im = cv2.imread(entry['image']) with c2_utils.NamedCudaScope(gpu_id): cls_boxes_i, cls_segms_i, cls_keyps_i, sum_softmax, topk_feats = im_detect_all( model, im, box_proposals, timers, return_feats=cfg.TEST.COLLECT_ALL) # print('nfeats:', topk_feats.shape[0]) # print(topk_feats) extend_results(i, all_boxes, cls_boxes_i) if cls_segms_i is not None: extend_results(i, all_segms, cls_segms_i) if cls_keyps_i is not None: extend_results(i, all_keyps, cls_keyps_i) if cfg.TEST.COLLECT_ALL: all_class_weights[i] = sum_softmax all_feats.append( topk_feats ) # will accumulate about 9 Gb of feats on COCO train set (118K imgs) if i % 10 == 0: # Reduce log file size ave_total_time = np.sum( [t.average_time for t in timers.values()]) eta_seconds = ave_total_time * (num_images - i - 1) eta = str(datetime.timedelta(seconds=int(eta_seconds))) det_time = (timers['im_detect_bbox'].average_time + timers['im_detect_mask'].average_time + timers['im_detect_keypoints'].average_time) misc_time = (timers['misc_bbox'].average_time + timers['misc_mask'].average_time + timers['misc_keypoints'].average_time) logger.info(('im_detect: range [{:d}, {:d}] of {:d}: ' '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})').format( start_ind + 1, end_ind, total_num_images, start_ind + i + 1, start_ind + num_images, det_time, misc_time, eta)) if cfg.VIS: im_name = os.path.splitext(os.path.basename(entry['image']))[0] vis_utils.vis_one_image(im[:, :, ::-1], '{:d}_{:s}'.format(i, im_name), os.path.join(output_dir, 'vis'), cls_boxes_i, segms=cls_segms_i, keypoints=cls_keyps_i, thresh=cfg.VIS_TH, box_alpha=0.8, dataset=dataset, show_class=True) cfg_yaml = envu.yaml_dump(cfg) save_object( dict(all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, cfg=cfg_yaml), det_file) logger.info('Wrote detections to: {}'.format( os.path.abspath(det_file))) if cfg.TEST.COLLECT_ALL: save_object(all_class_weights, os.path.join(output_dir, 'class_weights.pkl')) save_object(all_feats, os.path.join(output_dir, 'feature_vectors.pkl')) logger.info( 'Wrote class weights and feature vectors to output folder') return all_boxes, all_segms, all_keyps
print('====================================') print('get params in original VGG16') for blob_name in sorted(original_src_blobs.keys()): print(blob_name) if 'fc8' in blob_name: print('fc8 layer not saved') continue out_blobs[blob_name] = original_src_blobs[blob_name] print('====================================') print('get params in deeplab VGG16') for blob_name in sorted(deeplab_src_blobs.keys()): if blob_name in original_src_blobs.keys(): print('check param in two weight: ', blob_name) deeplab_src_blob = deeplab_src_blobs[blob_name] original_src_blob = original_src_blobs[blob_name] assert deeplab_src_blob.shape == original_src_blob.shape assert deeplab_src_blob.sum() == original_src_blob.sum() continue print(blob_name) if 'fc8' in blob_name: print('fc8 layer not saved') continue out_blobs[blob_name] = deeplab_src_blobs[blob_name] print('Wrote blobs:') print(sorted(out_blobs.keys())) save_object(out_blobs, file_out)
if coco_cls_id >= 0: # otherwise ignore (rand init) cs_blob[i] = coco_blob[coco_cls_id] cs_shape = [NUM_CS_CLS * leading_factor] + tail_shape return cs_blob.reshape(cs_shape) def remove_momentum(model_dict): for k in model_dict['blobs'].keys(): if k.endswith('_momentum'): del model_dict['blobs'][k] def load_and_convert_coco_model(args): model_dict = load_object(args.coco_model_file_name) remove_momentum(model_dict) convert_coco_blobs_to_cityscape_blobs(model_dict) return model_dict if __name__ == '__main__': args = parse_args() print(args) assert os.path.exists(args.coco_model_file_name), \ 'Weights file does not exist' weights = load_and_convert_coco_model(args) save_object(weights, args.out_file_name) print('Wrote blobs to {}:'.format(args.out_file_name)) print(sorted(weights['blobs'].keys()))
def test_net( weights_file, dataset_name, proposal_file, output_dir, ind_range=None, gpu_id=0 ): """Run inference on all images in a dataset or over an index range of images in a dataset using a single GPU. """ assert not cfg.MODEL.RPN_ONLY, \ 'Use rpn_generate to generate proposals from RPN-only models' roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, ind_range ) model = initialize_model_from_cfg(weights_file, gpu_id=gpu_id) num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES all_boxes, all_segms, all_keyps, all_bodys = \ empty_results(num_classes, num_images) timers = defaultdict(Timer) for i, entry in enumerate(roidb): if 'has_no_densepose' in entry.keys(): pass else: if cfg.TEST.PRECOMPUTED_PROPOSALS: # The roidb may contain ground-truth rois (for example, if the roidb # comes from the training or val split). We only want to evaluate # detection on the *non*-ground-truth rois. We select only the rois # that have the gt_classes field set to 0, which means there's no # ground truth. box_proposals = entry['boxes'][entry['gt_classes'] == 0] if len(box_proposals) == 0: continue else: # Faster R-CNN type models generate proposals on-the-fly with an # in-network RPN; 1-stage models don't require proposals. box_proposals = None im = cv2.imread(entry['image']) with c2_utils.NamedCudaScope(gpu_id): cls_boxes_i, cls_segms_i, cls_keyps_i,cls_bodys_i = \ im_detect_all(model, im, box_proposals, timers) extend_results(i, all_boxes, cls_boxes_i) if cls_segms_i is not None: extend_results(i, all_segms, cls_segms_i) if cls_keyps_i is not None: extend_results(i, all_keyps, cls_keyps_i) if cls_bodys_i is not None: extend_results(i, all_bodys, cls_bodys_i) if i % 10 == 0: # Reduce log file size ave_total_time = np.sum([t.average_time for t in timers.values()]) eta_seconds = ave_total_time * (num_images - i - 1) eta = str(datetime.timedelta(seconds=int(eta_seconds))) det_time = ( timers['im_detect_bbox'].average_time + timers['im_detect_mask'].average_time + timers['im_detect_keypoints'].average_time + timers['im_detect_body_uv'].average_time ) misc_time = ( timers['misc_bbox'].average_time + timers['misc_mask'].average_time + timers['misc_keypoints'].average_time + timers['misc_body_uv'].average_time ) logger.info( ( 'im_detect: range [{:d}, {:d}] of {:d}: ' '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})' ).format( start_ind + 1, end_ind, total_num_images, start_ind + i + 1, start_ind + num_images, det_time, misc_time, eta ) ) if cfg.VIS: im_name = os.path.splitext(os.path.basename(entry['image']))[0] vis_utils.vis_one_image( im[:, :, ::-1], '{:d}_{:s}'.format(i, im_name), os.path.join(output_dir, 'vis'), cls_boxes_i, segms=cls_segms_i, keypoints=cls_keyps_i, thresh=cfg.VIS_TH, box_alpha=0.8, dataset=dataset, show_class=True ) cfg_yaml = yaml.dump(cfg) if ind_range is not None: det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range) else: det_name = 'detections.pkl' det_file = os.path.join(output_dir, det_name) save_object( dict( all_boxes=all_boxes, all_segms=all_segms, all_keyps=all_keyps, all_bodys=all_bodys, cfg=cfg_yaml ), det_file ) logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file))) return all_boxes, all_segms, all_keyps, all_bodys
bn_mean = dict_data[key_bn_m].numpy() bn_var = dict_data[key_bn_v].numpy() bn_std = np.sqrt(bn_var + 1e-5) aff_scale = bn_scale / bn_std aff_bias = bn_bias - bn_mean * bn_scale / bn_std # merge aff to conv conv_w = new_dict_data[key_conv_w] conv_b = new_dict_data[key_conv_b] c_out, c_in, k_h, k_w = conv_w.shape # bn_w_tile = np.tile(aff_scale, (1,c_in,k_h,k_w)) new_conv_w = conv_w * np.tile( np.reshape(aff_scale, (c_out, 1, 1, 1)), (1, c_in, k_h, k_w)) new_conv_b = conv_b * aff_scale + aff_bias new_dict_data[key_conv_w] = new_conv_w new_dict_data[key_conv_b] = new_conv_b print(cnt, '\tmerge: ', name_map_bn, ' into ', name_map[0]) cnt += 1 new_pkl_path = 'model/pytorch/' + model_name + '_pytorch.pkl' save_object(new_dict_data, new_pkl_path, pickle_format=pickle.HIGHEST_PROTOCOL)
def voc_eval(detpath, annopath, imagesetfile, classname, cachedir, ovthresh=0.5, use_07_metric=False): """rec, prec, ap = voc_eval(detpath, annopath, imagesetfile, classname, [ovthresh], [use_07_metric]) Top level function that does the PASCAL VOC evaluation. detpath: Path to detections detpath.format(classname) should produce the detection results file. annopath: Path to annotations annopath.format(imagename) should be the xml annotations file. imagesetfile: Text file containing the list of images, one image per line. classname: Category name (duh) cachedir: Directory for caching the annotations [ovthresh]: Overlap threshold (default = 0.5) [use_07_metric]: Whether to use VOC07's 11 point AP computation (default False) """ # assumes detections are in detpath.format(classname) # assumes annotations are in annopath.format(imagename) # assumes imagesetfile is a text file with each line an image name # cachedir caches the annotations in a pickle file # first load gt if not os.path.isdir(cachedir): os.mkdir(cachedir) imageset = os.path.splitext(os.path.basename(imagesetfile))[0] cachefile = os.path.join(cachedir, imageset + '_annots.pkl') # read list of images with open(imagesetfile, 'r') as f: lines = f.readlines() imagenames = [x.strip() for x in lines] if not os.path.isfile(cachefile): # load annots recs = {} for i, imagename in enumerate(imagenames): recs[imagename] = parse_rec(annopath.format(imagename)) if i % 100 == 0: logger.info( 'Reading annotation for {:d}/{:d}'.format( i + 1, len(imagenames))) # save logger.info('Saving cached annotations to {:s}'.format(cachefile)) save_object(recs, cachefile) else: recs = load_object(cachefile) # extract gt objects for this class class_recs = {} npos = 0 for imagename in imagenames: R = [obj for obj in recs[imagename] if obj['name'] == classname] bbox = np.array([x['bbox'] for x in R]) difficult = np.array([x['difficult'] for x in R]).astype(np.bool) det = [False] * len(R) npos = npos + sum(~difficult) class_recs[imagename] = {'bbox': bbox, 'difficult': difficult, 'det': det} # read dets detfile = detpath.format(classname) with open(detfile, 'r') as f: lines = f.readlines() splitlines = [x.strip().split(' ') for x in lines] image_ids = [x[0] for x in splitlines] confidence = np.array([float(x[1]) for x in splitlines]) BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) # sort by confidence sorted_ind = np.argsort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] # go down dets and mark TPs and FPs nd = len(image_ids) tp = np.zeros(nd) fp = np.zeros(nd) for d in range(nd): R = class_recs[image_ids[d]] bb = BB[d, :].astype(float) ovmax = -np.inf BBGT = R['bbox'].astype(float) if BBGT.size > 0: # compute overlaps # intersection ixmin = np.maximum(BBGT[:, 0], bb[0]) iymin = np.maximum(BBGT[:, 1], bb[1]) ixmax = np.minimum(BBGT[:, 2], bb[2]) iymax = np.minimum(BBGT[:, 3], bb[3]) iw = np.maximum(ixmax - ixmin + 1., 0.) ih = np.maximum(iymax - iymin + 1., 0.) inters = iw * ih # union uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) + (BBGT[:, 2] - BBGT[:, 0] + 1.) * (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters) overlaps = inters / uni ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > ovthresh: if not R['difficult'][jmax]: if not R['det'][jmax]: tp[d] = 1. R['det'][jmax] = 1 else: fp[d] = 1. else: fp[d] = 1. # compute precision recall fp = np.cumsum(fp) tp = np.cumsum(tp) rec = tp / float(npos) # avoid divide by zero in case the first detection matches a difficult # ground truth prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) ap = voc_ap(rec, prec, use_07_metric) return rec, prec, ap