def _add_proposals_from_file( self, roidb, proposal_file, min_proposal_size, top_k, crowd_thresh ): """Add proposals from a proposals file to an roidb.""" logger.info('Loading proposals from: {}'.format(proposal_file)) proposals = load_object(proposal_file) id_field = 'indexes' if 'indexes' in proposals else 'ids' # compat fix _sort_proposals(proposals, id_field) box_list = [] for i, entry in enumerate(roidb): if i % 2500 == 0: logger.info(' {:d}/{:d}'.format(i + 1, len(roidb))) boxes = proposals['boxes'][i] # Sanity check that these boxes are for the correct image id assert entry['id'] == proposals[id_field][i] # Remove duplicate boxes and very small boxes and then take top k boxes = box_utils.clip_boxes_to_image( boxes, entry['height'], entry['width'] ) keep = box_utils.unique_boxes(boxes) boxes = boxes[keep, :] keep = box_utils.filter_small_boxes(boxes, min_proposal_size) boxes = boxes[keep, :] if top_k > 0: boxes = boxes[:top_k, :] box_list.append(boxes) _merge_proposal_boxes_into_roidb(roidb, box_list) if crowd_thresh > 0: _filter_crowd_proposals(roidb, crowd_thresh)
def _add_proposals_from_file(self, roidb, proposal_file, min_proposal_size, top_k, crowd_thresh): """Add proposals from a proposals file to an roidb.""" logger.info('Loading proposals from: {}'.format(proposal_file)) proposals = load_object(proposal_file) id_field = 'indexes' if 'indexes' in proposals else 'ids' # compat fix _sort_proposals(proposals, id_field) box_list = [] for i, entry in enumerate(roidb): if i % 2500 == 0: logger.info(' {:d}/{:d}'.format(i + 1, len(roidb))) boxes = proposals['boxes'][i] # Sanity check that these boxes are for the correct image id assert entry['id'] == proposals[id_field][i] # Remove duplicate boxes and very small boxes and then take top k boxes = box_utils.clip_boxes_to_image(boxes, entry['height'], entry['width']) keep = box_utils.unique_boxes(boxes) boxes = boxes[keep, :] keep = box_utils.filter_small_boxes(boxes, min_proposal_size) boxes = boxes[keep, :] if top_k > 0: boxes = boxes[:top_k, :] box_list.append(boxes) _merge_proposal_boxes_into_roidb(roidb, box_list) if crowd_thresh > 0: _filter_crowd_proposals(roidb, crowd_thresh)
def accuracy(dataset, detections_pkl): # Load predictions and ground truths ds = JsonDataset(dataset) roidb = ds.get_roidb(gt=True) dets = load_object(detections_pkl) all_boxes = dets['all_boxes'] def id_or_index(ix, val): if len(val) == 0: return val else: return val[ix] trues = 0. # Iterate through all images for ix, entry in enumerate(roidb): cls_boxes_i = [ id_or_index(ix, cls_k_boxes) for cls_k_boxes in all_boxes ] true_boxes = entry['boxes'] if (true_boxes.shape[0] == 0) == (len(cls_boxes_i[3]) == 0): trues += 1 # Finally, calculate accuracy by dividing the sum of true predictions by total samples acc = trues/len(roidb) print("Accuracy: " + str(acc)) return acc
def do_reval(dataset_name, output_dir, args): dataset = JsonDataset(dataset_name) dets = load_object(os.path.join(output_dir, 'detections.pkl')) # Override config with the one saved in the detections file if args.cfg_file is not None: core_config.merge_cfg_from_cfg(core_config.load_cfg(dets['cfg'])) else: core_config._merge_a_into_b(core_config.load_cfg(dets['cfg']), cfg) # re-filter on score threshold: dets['all_boxes'] = \ [ [ im[im[:,4] > cfg.TEST.SCORE_THRESH,:] if len(im) != 0 else [] for im in cls ] for cls in dets['all_boxes'] ] results = task_evaluation.evaluate_all(dataset, dets['all_boxes'], dets['all_segms'], dets['all_keyps'], output_dir, use_matlab=args.matlab_eval) task_evaluation.log_copy_paste_friendly_results(results)
def process_in_parallel(tag, total_range_size, binary, output_dir, opts=''): """Run the specified binary cfg.NUM_GPUS times in parallel, each time as a subprocess that uses one GPU. The binary must accept the command line arguments `--range {start} {end}` that specify a data processing range. """ # Snapshot the current cfg state in order to pass to the inference # subprocesses cfg_file = os.path.join(output_dir, '{}_range_config.yaml'.format(tag)) with open(cfg_file, 'w') as f: envu.yaml_dump(cfg, stream=f) subprocess_env = os.environ.copy() processes = [] subinds = np.array_split(range(total_range_size), cfg.NUM_GPUS) # Determine GPUs to use cuda_visible_devices = os.environ.get('CUDA_VISIBLE_DEVICES') if cuda_visible_devices: gpu_inds = map(int, cuda_visible_devices.split(',')) assert -1 not in gpu_inds, \ 'Hiding GPU indices using the \'-1\' index is not supported' else: gpu_inds = reversed(range(cfg.NUM_GPUS)) # Run the binary in cfg.NUM_GPUS subprocesses for i, gpu_ind in enumerate(gpu_inds): start = subinds[i][0] end = subinds[i][-1] + 1 subprocess_env['CUDA_VISIBLE_DEVICES'] = str(gpu_ind) cmd = '{binary} --range {start} {end} --cfg {cfg_file} NUM_GPUS 1 {opts}' cmd = cmd.format(binary=shlex_quote(binary), start=int(start), end=int(end), cfg_file=shlex_quote(cfg_file), opts=' '.join([shlex_quote(opt) for opt in opts])) logger.info('{} range command {}: {}'.format(tag, i, cmd)) if i == 0: subprocess_stdout = subprocess.PIPE else: filename = os.path.join( output_dir, '%s_range_%s_%s.stdout' % (tag, start, end)) subprocess_stdout = open(filename, 'w') # NOQA (close below) p = subprocess.Popen(cmd, shell=True, env=subprocess_env, stdout=subprocess_stdout, stderr=subprocess.STDOUT, bufsize=1) processes.append((i, p, start, end, subprocess_stdout)) print('Sleep 15s for gpu_id ', gpu_ind) time.sleep(15) # Log output from inference processes and collate their results outputs = [] for i, p, start, end, subprocess_stdout in processes: log_subprocess_output(i, p, output_dir, tag, start, end) if i > 0: subprocess_stdout.close() range_file = os.path.join(output_dir, '%s_range_%s_%s.pkl' % (tag, start, end)) range_data = load_object(range_file) outputs.append(range_data) return outputs
def rrpn_loader(rpn_pkl_file): """ Open, index and return a pickled proposals dictionary """ pkl = load_object(rpn_pkl_file) proposals = {} for boxes, scores, id in zip(pkl['boxes'], pkl['scores'], pkl['ids']): proposals[id] = {'boxes': boxes, 'scores': scores} return proposals
def vis(dataset, detections_pkl, thresh, output_dir, limit=0): ds = JsonDataset(dataset) roidb = ds.get_roidb() dets = load_object(detections_pkl) assert all(k in dets for k in ['all_boxes', 'all_segms', 'all_keyps']), \ 'Expected detections pkl file in the format used by test_engine.py' all_boxes = dets['all_boxes'] all_segms = dets['all_segms'] all_keyps = dets['all_keyps'] def id_or_index(ix, val): if len(val) == 0: return val else: return val[ix] for ix, entry in enumerate(roidb): if limit > 0 and ix >= limit: break if ix % 10 == 0: print('{:d}/{:d}'.format(ix + 1, len(roidb))) im = cv2.imread(entry['image']) im_name = os.path.splitext(os.path.basename(entry['image']))[0] cls_boxes_i = [ id_or_index(ix, cls_k_boxes) for cls_k_boxes in all_boxes ] cls_segms_i = [ id_or_index(ix, cls_k_segms) for cls_k_segms in all_segms ] cls_keyps_i = [ id_or_index(ix, cls_k_keyps) for cls_k_keyps in all_keyps ] vis_utils.vis_one_image( im[:, :, ::-1], '{:d}_{:s}'.format(ix, im_name), os.path.join(output_dir, 'vis'), cls_boxes_i, segms=cls_segms_i, keypoints=cls_keyps_i, thresh=thresh, box_alpha=0.8, dataset=ds, show_class=True, ext = "jpg" )
def do_reval(dataset_name, output_dir, args): dataset = JsonDataset(dataset_name) dets = load_object(os.path.join(output_dir, 'detections.pkl')) # Override config with the one saved in the detections file if args.cfg_file is not None: core_config.merge_cfg_from_cfg(core_config.load_cfg(dets['cfg'])) else: core_config._merge_a_into_b(core_config.load_cfg(dets['cfg']), cfg) results = task_evaluation.evaluate_all(dataset, dets['all_boxes'], dets['all_segms'], dets['all_keyps'], output_dir, use_matlab=args.matlab_eval) task_evaluation.log_copy_paste_friendly_results(results)
def convert_mask_net(args, mask_net): # Initialization net init_net = caffe2_pb2.NetDef() net = caffe2_pb2.NetDef() blobs = io_utils.load_object(args.wts)['blobs'] externals = set( c2_utils.UnscopeName(inp) for inp in mask_net.external_input) for name in set(blobs.keys()).intersection(externals): blob = blobs[name] add_custom_op(init_net, 'GivenTensorFill', [], [name], values=blob.flatten(), shape=blob.shape) # Pre-process the ROIs add_custom_op(net, 'BBoxToRoi', [ Constants.nms_outputs[1], Constants.im_info, Constants.nms_outputs[3] ], [Constants.mask_rois]) # Group the ROIs based on their FPN level if cfg.FPN.MULTILEVEL_ROIS: outputs = [Constants.mask_rois + Constants.idx_restore_suffix] for level in range(cfg.FPN.ROI_MIN_LEVEL, cfg.FPN.ROI_MAX_LEVEL + 1): outputs.append(Constants.mask_rois + Constants.fpn_level_suffix(level)) add_custom_op(net, 'MultiLevelRoi', [Constants.mask_rois], outputs, min_level=cfg.FPN.ROI_MIN_LEVEL, canon_scale=cfg.FPN.ROI_CANONICAL_SCALE, canon_level=cfg.FPN.ROI_CANONICAL_LEVEL) # Generate the masks net.op.extend(mask_net.op) # Post-process the masks add_custom_op(net, 'SegmentMask', Constants.nms_outputs[1:-1] + [Constants.mask_pred, Constants.im_info], [Constants.main_output, Constants.im_info], thresh_bin=cfg.MRCNN.THRESH_BINARIZE) net.name = args.net_name + '_mask' init_net.name = args.net_name + '_mask_init' save_model(net, init_net, args.mask_dir)
def do_reval(dataset_name, output_dir, args): dataset = JsonDataset(dataset_name) dets = load_object(os.path.join(output_dir, 'detections.pkl')) # Override config with the one saved in the detections file if args.cfg_file is not None: core_config.merge_cfg_from_cfg(core_config.load_cfg(dets['cfg'])) else: core_config._merge_a_into_b(core_config.load_cfg(dets['cfg']), cfg) results = task_evaluation.evaluate_all( dataset, dets['all_boxes'], dets['all_segms'], dets['all_keyps'], output_dir, use_matlab=args.matlab_eval ) task_evaluation.log_copy_paste_friendly_results(results)
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 convert_mask_net(args, mask_net): # Initialization net init_net = caffe2_pb2.NetDef() net = caffe2_pb2.NetDef() blobs = io_utils.load_object(args.wts)['blobs'] externals = set(c2_utils.UnscopeName(inp) for inp in mask_net.external_input) for name in set(blobs.keys()).intersection(externals): blob = blobs[name] add_custom_op(init_net, 'GivenTensorFill', [], [name], values = blob.flatten(), shape = blob.shape) # Pre-process the ROIs add_custom_op(net, 'BBoxToRoi', [Constants.nms_outputs[1], Constants.im_info, Constants.nms_outputs[3]], [Constants.mask_rois]) # Group the ROIs based on their FPN level if cfg.FPN.MULTILEVEL_ROIS: outputs = [Constants.mask_rois + Constants.idx_restore_suffix] for level in range(cfg.FPN.ROI_MIN_LEVEL, cfg.FPN.ROI_MAX_LEVEL + 1): outputs.append(Constants.mask_rois + Constants.fpn_level_suffix(level)) add_custom_op(net, 'MultiLevelRoi', [Constants.mask_rois], outputs, min_level = cfg.FPN.ROI_MIN_LEVEL, canon_scale = cfg.FPN.ROI_CANONICAL_SCALE, canon_level = cfg.FPN.ROI_CANONICAL_LEVEL) # Generate the masks net.op.extend(mask_net.op) # Post-process the masks add_custom_op(net, 'SegmentMask', Constants.nms_outputs[1:-1] + [Constants.mask_pred, Constants.im_info], [Constants.main_output, Constants.im_info], thresh_bin = cfg.MRCNN.THRESH_BINARIZE) net.name = args.net_name + '_mask' init_net.name = args.net_name + '_mask_init' save_model(net, init_net, args.mask_dir)
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
parser.add_argument('--out_dir', dest='out_dir', help='Test outputs directory', default='../data/test') args = parser.parse_args() return args ##------------------------------------------------------------------------------ if __name__ == '__main__': args = parse_args() fig = plt.figure(figsize=(16, 9)) # Load the dataset and proposals coco = COCO_PLUS(args.ann_file) proposals = load_object(args.proposals) num_imgs = len(coco.imgs) assert len(proposals['ids']) == num_imgs, \ "Number of proposals do not match the number of images in the dataset" step = 1 for i in tqdm(range(0, num_imgs, step)): img_id = proposals['ids'][i] points = coco.imgToPc[img_id]['points'] img_path = os.path.join(args.imgs_dir, coco.imgs[img_id]["file_name"]) img = np.array(plt.imread(img_path)) boxes = proposals['boxes'][i] ## Plot proposals img = draw_xyxy_bbox(img, list(boxes), lineWidth=2) img = draw_points(img, points, color=(0,0,255), radius=5, thickness=-1, format='RGB')
def visualize_ranking(dataset, detections_pkl, opts): # Load predictions and ground truths ds = JsonDataset(dataset) roidb = ds.get_roidb(gt=True) dets = load_object(detections_pkl) all_boxes = dets['all_boxes'] def id_or_index(ix, val): if len(val) == 0: return val else: return val[ix] # Load coordinates with open(opts.coord_file) as json_file: coord_data = json.load(json_file) # Iterate through all images and note false positive and negatives, as well as entry scores false_positives = [] false_negatives = [] scores = [] for ix, entry in enumerate(roidb): cls_boxes_i = [ id_or_index(ix, cls_k_boxes) for cls_k_boxes in all_boxes ] preds = np.array(cls_boxes_i[opts.class_id]) entry['preds'] = preds true_boxes = entry['boxes'] if preds.shape[0] > 0 and np.max(preds[:, -1]) > opts.threshold: box_scores = preds[:, -1] box_scores = box_scores[np.where(box_scores > opts.threshold)] score = np.sum( box_scores[np.argsort(box_scores)[-opts.box_count:]]) scores.append([entry, score]) if true_boxes.shape[0] == 0: false_positives.append(entry) else: if true_boxes.shape[0] > 0: false_negatives = add_negative(false_negatives, entry, coord_data, opts.min_distance) # Find top rated entries scores = np.array(scores) scores = scores[np.argsort(scores[:, 1])[::-1]] for entry in scores[:, 0]: entry['coords'] = coord_data[os.path.split(entry['image'])[-1]] # Filter by proximity for i in range(scores.shape[0]): if scores[i][1] > 0: current_entry = scores[i][0] for j in range(i + 1, scores.shape[0]): second_entry = scores[j][0] dist = distance( (current_entry['coords'][0], current_entry['coords'][1]), (second_entry['coords'][0], second_entry['coords'][1])).km * 1000 if dist < opts.min_distance: scores[j][1] = 0 scores = scores[np.where(scores[:, 1] > 0)] top_entries = scores[np.argsort(scores[:, 1])[-opts.image_count:][::-1]] # Choose random negative samples false_samples = np.append(false_negatives, false_positives) np.random.shuffle(false_samples) # Visualize positive and negative samples rows_cols = (opts.image_count, 2) if opts.angle == 'ver' else (2, opts.image_count) plt_shape = (6., opts.image_count * 2.5) if opts.angle == 'ver' else (opts.image_count * 2.5, 6.) fig = plt.figure(1, plt_shape) grid = ImageGrid( fig, 111, nrows_ncols=rows_cols, axes_pad=0.03, label_mode='L', ) # Show top ranked images for i, result in enumerate(top_entries): entry = result[0] score = result[1] grid_idx = i if opts.angle == 'ver': grid_idx = i * 2 # Load image and add bounding boxes im = cv2.imread(entry['image']) preds = entry['preds'] true_boxes = entry['boxes'] for bbox in true_boxes: im = vis_bbox( im, (bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]), _GT_COLOR, opts.box_thickness) count = 0 for bbox in preds: if bbox[-1] > opts.threshold: count += 1 print( os.path.split(entry['image'])[-1] + ': ' + str(bbox[0:4])) im = vis_bbox( im, (bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]), _PRED_COLOR, opts.box_thickness) if count >= opts.box_count: break # Adjust grid setting im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) show_img(grid, im, grid_idx) t = grid[grid_idx].text(12, 42, "Score: " + str(round(score, 3)), fontsize=8, bbox=dict(boxstyle='square', fc='white', ec='none', alpha=0.6)) if i == 0: if opts.angle == 'ver': grid[grid_idx].set_title("Top\nPredictions", size=18) else: grid[grid_idx].set_ylabel("Top Predictions", fontsize=13) # Show random negative samples (false positive, false negative) for i, entry in enumerate(false_samples): if i >= opts.image_count: break grid_idx = opts.image_count + i if opts.angle == 'ver': grid_idx = 2 * i + 1 # Load image and add bounding boxes im = cv2.imread(entry['image']) preds = entry['preds'] true_boxes = entry['boxes'] for bbox in true_boxes: im = vis_bbox( im, (bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]), _GT_COLOR, opts.box_thickness) for bbox in preds: if bbox[-1] > opts.threshold: im = vis_bbox( im, (bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]), _PRED_COLOR, opts.box_thickness) # Adjust grid setting im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) grid[grid_idx].imshow(im) grid[grid_idx].grid(False) grid[grid_idx].set_xticks([]) grid[grid_idx].set_yticks([]) if i == 0: if opts.angle == 'ver': grid[grid_idx].set_title("Errors", size=18) else: grid[grid_idx].set_ylabel("Errors", fontsize=13) plt.axis('off') plt.subplots_adjust(hspace=1) plt.savefig("ranking.png", dpi=300, bbox_inches='tight')
# def plot_dist(dist,dist2=None): # fig,ax = plt.subplots() # plt_bars(dist, coco_classes, dist2, ax=ax) # plt.show() if __name__ == '__main__': # workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) logger = setup_logging(__name__) args = parse_args() logger.info('Called with args:') logger.info(args) assert args.class_weights is not None, 'class_weights file required' print(str(args.class_weights[0])) coco_wts = load_object(args.class_weights[0]) print(coco_wts.shape) coco_dist = get_dist(coco_wts) print("coco size: ", coco_wts.sum()) assert args.voc_class_weights is not None, 'voc dist files needed' voc_files = args.voc_class_weights if args.do_val_set: voc_files = [ 'collecting/test/voc_2007_test/generalized_rcnn/class_weights.pkl', 'collecting/test/voc_2012_val/generalized_rcnn/class_weights.pkl' ] voc_wts = np.concatenate([load_object(vocfile) for vocfile in voc_files], axis=0)
def _add_proposals_from_file(self, roidb, proposal_file, min_proposal_size, top_k, crowd_thresh): """Add proposals from a proposals file to an roidb.""" logger.info('Loading proposals from: {}'.format(proposal_file)) proposals = load_object(proposal_file) id_field = 'indexes' if 'indexes' in proposals else 'ids' # compat fix # _remove_proposals_not_in_roidb(proposals, roidb, id_field) _sort_proposals(proposals, id_field) box_list = [] score_list = [] total_roi = 0 up_1024 = 0 up_2048 = 0 up_3072 = 0 up_4096 = 0 for i, entry in enumerate(roidb): if i % 2500 == 0: logger.info(' {:d}/{:d}'.format(i + 1, len(roidb))) boxes = proposals['boxes'][i] scores = proposals['scores'][i] # Sanity check that these boxes are for the correct image id assert entry['id'] == proposals[id_field][i] # Remove duplicate boxes and very small boxes and then take top k # boxes = box_utils.clip_boxes_to_image( # boxes, entry['height'], entry['width'] # ) assert (boxes[:, 0] >= 0).all() assert (boxes[:, 1] >= 0).all() assert (boxes[:, 2] >= boxes[:, 0]).all() assert (boxes[:, 3] >= boxes[:, 1]).all() assert (boxes[:, 2] < entry['width']).all(), entry['image'] assert (boxes[:, 3] < entry['height']).all(), entry['image'] keep = box_utils.unique_boxes(boxes) boxes = boxes[keep, :] scores = scores[keep] keep = box_utils.filter_small_boxes(boxes, min_proposal_size) boxes = boxes[keep, :] scores = scores[keep] # sort by confidence sorted_ind = np.argsort(-scores.flatten()) boxes = boxes[sorted_ind, :] scores = scores[sorted_ind, :] if top_k > 0: boxes = boxes[:top_k, :] scores = scores[:top_k] total_roi += boxes.shape[0] if boxes.shape[0] > 1024: up_1024 += 1 if boxes.shape[0] > 2048: up_2048 += 1 if boxes.shape[0] > 3072: up_3072 += 1 if boxes.shape[0] > 4096: up_4096 += 1 box_list.append(boxes) score_list.append(scores) print('total_roi: ', total_roi, ' ave roi: ', total_roi / len(box_list)) print('up_1024: ', up_1024) print('up_2048: ', up_2048) print('up_3072: ', up_3072) print('up_4096: ', up_4096) _merge_proposal_boxes_into_roidb(roidb, box_list, score_list) if crowd_thresh > 0: _filter_crowd_proposals(roidb, crowd_thresh)
def _add_pseudo_gt_annotations(self, roidb, gt_roidb): """ Return the database of pseudo ground-truth regions of interest from detect result. This function loads/saves from/to a cache file to speed up future calls. """ # gt_roidb = copy.deepcopy(roidb) # for entry in roidb: # self._add_gt_annotations(entry) assert 'train' in self.name or 'val' in self.name, 'Only trainval dataset has pseudo gt.' # detection.pkl is 0-based indices # the VOC result file is 1-based indices cache_files = cfg.PSEUDO_PATH if isinstance(cache_files, basestring): cache_files = (cache_files, ) all_dets = None for cache_file in cache_files: if self.name not in cache_file: continue assert os.path.exists(cache_file), cache_file # with open(cache_file, 'rb') as fid: # res = cPickle.load(fid) res = load_object(cache_file) print('{} pseudo gt roidb loaded from {}'.format( self.name, cache_file)) if all_dets is None: all_dets = res['all_boxes'] else: for i in range(len(all_dets)): all_dets[i].extend(res['all_boxes'][i]) assert len(all_dets[1]) == len(roidb), len(all_dets[1]) if len(all_dets) == self.num_classes: cls_offset = 0 elif len(all_dets) + 1 == self.num_classes: cls_offset = -1 else: raise Exception('Unknown mode.') threshold = 1.0 for im_i, entry in enumerate(roidb): if im_i % 1000 == 0: print('{:d} / {:d}'.format(im_i + 1, len(roidb))) num_valid_objs = 0 if len(gt_roidb[im_i]['gt_classes']) == 0: print(gt_roidb[im_i]) if len(gt_roidb[im_i]['is_crowd']) == sum( gt_roidb[im_i]['is_crowd']): print(gt_roidb[im_i]) # when cfg.WSL = False, background class is in. # detection.pkl only has 20 classes # fast_rcnn need 21 classes for cls in range(1, self.num_classes): # TODO(YH): we need threshold the pseudo label # filter the pseudo label # self._gt_class has 21 classes # if self._gt_classes[ix][cls] == 0: if cls not in gt_roidb[im_i]['gt_classes']: continue dets = all_dets[cls + cls_offset][im_i] if dets.shape[0] <= 0: continue # TODO(YH): keep only one box # if dets.shape[0] > 0: # num_valid_objs += 1 max_score = 0 num_valid_objs_cls = 0 for i in range(dets.shape[0]): det = dets[i] score = det[4] if score > max_score: max_score = score if score < threshold: continue num_valid_objs += 1 num_valid_objs_cls += 1 if num_valid_objs_cls == 0: if max_score > 0: num_valid_objs += 1 boxes = np.zeros((num_valid_objs, 4), dtype=entry['boxes'].dtype) # obn_scores = np.zeros((num_valid_objs, 1), dtype=entry['obn_scores'].dtype) gt_classes = np.zeros((num_valid_objs), dtype=entry['gt_classes'].dtype) gt_overlaps = np.zeros((num_valid_objs, self.num_classes), dtype=entry['gt_overlaps'].dtype) seg_areas = np.zeros((num_valid_objs), dtype=entry['seg_areas'].dtype) is_crowd = np.zeros((num_valid_objs), dtype=entry['is_crowd'].dtype) box_to_gt_ind_map = np.zeros( (num_valid_objs), dtype=entry['box_to_gt_ind_map'].dtype) obj_i = 0 valid_segms = [] for cls in range(1, self.num_classes): # filter the pseudo label # self._gt_class has 21 classes # if self._gt_classes[ix][cls] == 0: if cls not in gt_roidb[im_i]['gt_classes']: continue dets = all_dets[cls + cls_offset][im_i] if dets.shape[0] <= 0: continue max_score = 0 max_score_bb = [] num_valid_objs_cls = 0 for i in range(dets.shape[0]): det = dets[i] x1 = det[0] y1 = det[1] x2 = det[2] y2 = det[3] score = det[4] if score > max_score: max_score = score max_score_bb = [x1, y1, x2, y2] if score < threshold: continue assert x1 >= 0 assert y1 >= 0 assert x2 >= x1 assert y2 >= y1 assert x2 < entry['width'] assert y2 < entry['height'] boxes[obj_i, :] = [x1, y1, x2, y2] gt_classes[obj_i] = cls seg_areas[obj_i] = (x2 - x1 + 1) * (y2 - y1 + 1) is_crowd[obj_i] = 0 box_to_gt_ind_map[obj_i] = obj_i gt_overlaps[obj_i, cls] = 1.0 valid_segms.append([]) obj_i += 1 num_valid_objs_cls += 1 if num_valid_objs_cls == 0: x1, y1, x2, y2 = max_score_bb[:] assert x1 >= 0 assert y1 >= 0 assert x2 >= x1 assert y2 >= y1 assert x2 < entry['width'] assert y2 < entry['height'] boxes[obj_i, :] = [x1, y1, x2, y2] gt_classes[obj_i] = cls seg_areas[obj_i] = (x2 - x1 + 1) * (y2 - y1 + 1) is_crowd[obj_i] = 0 box_to_gt_ind_map[obj_i] = obj_i gt_overlaps[obj_i, cls] = 1.0 valid_segms.append([]) obj_i += 1 assert obj_i == num_valid_objs # Show Pseudo GT boxes if True: # if False: import cv2 im = cv2.imread(entry['image']) for obj_i in range(num_valid_objs): cv2.rectangle(im, (boxes[obj_i][0], boxes[obj_i][1]), (boxes[obj_i][2], boxes[obj_i][3]), (255, 0, 0), 5) save_dir = os.path.join(cfg.OUTPUT_DIR, 'pgt') if not os.path.exists(save_dir): os.makedirs(save_dir) save_path = os.path.join(save_dir, str(im_i) + '.png') # print(save_path) cv2.imwrite(save_path, im) # cv2.imshow('im', im) # cv2.waitKey() entry['boxes'] = np.append(entry['boxes'], boxes, axis=0) # entry['obn_scores'] = np.append(entry['obn_scores'], obn_scores, axis=0) entry['segms'].extend(valid_segms) # To match the original implementation: # entry['boxes'] = np.append( # entry['boxes'], boxes.astype(np.int).astype(np.float), axis=0) entry['gt_classes'] = np.append(entry['gt_classes'], gt_classes) entry['seg_areas'] = np.append(entry['seg_areas'], seg_areas) entry['gt_overlaps'] = np.append(entry['gt_overlaps'].toarray(), gt_overlaps, axis=0) entry['gt_overlaps'] = scipy.sparse.csr_matrix( entry['gt_overlaps']) entry['is_crowd'] = np.append(entry['is_crowd'], is_crowd) entry['box_to_gt_ind_map'] = np.append(entry['box_to_gt_ind_map'], box_to_gt_ind_map)
help='Proposals file', default='../output/temp_proposals_ss.pkl') args = parser.parse_args() args.image_file = os.path.abspath(args.image_file) args.proposals_file = os.path.abspath(args.proposals_file) return args if __name__ == '__main__': args = parse_args() fig = plt.figure(figsize=(16, 6)) # Load the proposals proposals = load_object(args.proposals_file) # print(len(proposals1['indexes'])) # print(proposals2['ids']) # np.set_printoptions(threshold=np.nan) # for i in range(20): # print(proposals1['boxes'][i][0:10,:]) # print('---------------------------') # print(proposals2['boxes'][i][0:10,:]) # input('something') # print('Nucoco proposal keys:') # for key, value in proposals1.items() : # print(key, value) #
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
fc6s = [] fc7s = [] max_classes = [] gt_classes = [] gt_classes_cnt = np.zeros(N, dtype=np.int32) cnt = 0 cnt2 = 0 for root, dirs, files in os.walk(dir_in, topdown=False): for name in files: if name.endswith('pkl'): pass else: continue print(cnt, os.path.join(root, name)) path = os.path.join(root, name) pkl = load_object(path) roi_feat = pkl['roi_feats'] if has_fc: fc6 = pkl['fc6'] fc7 = pkl['fc7'] gt_class = pkl['gt_classes'] print(cnt, cnt2, 'roi_feat: ', roi_feat.shape) t = [] for i in range(roi_feat.shape[0]): if gt_class[i] in t: # continue pass
def voc_eval_corloc(detpath, annopath, imagesetfile, classname, cachedir, ovthresh=0.5, use_07_metric=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: # load recs = load_object(cachefile) # extract gt objects for this class class_recs = {} npos = 0 npos_im = 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} if len(R) > 0: npos_im += min(1, sum(~difficult)) # read dets detfile = detpath.format(classname) with open(detfile, 'r') as f: lines = f.readlines() if len(lines) == 0: return 0.0 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) sorted_scores = np.sort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] nd = len(image_ids) T = [] F = [] too_min = 0 for d in range(nd): if image_ids[d] in T or image_ids[d] in F: continue R = class_recs[image_ids[d]] all_difficult = True for difficult in R['difficult']: if not difficult: all_difficult = False if all_difficult: continue 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: T.append(image_ids[d]) else: F.append(image_ids[d]) uni = (bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) overlaps = inters / uni ovmax = np.max(overlaps) if ovmax > ovthresh: too_min += 1 if len(F) == 0: too_min_rate = 0.0 else: too_min_rate = 1.0 * too_min / len(F) print('npos_im: ', npos_im, '#F: ', len(F), ' too_min: ', too_min, ' rate: ', too_min_rate) return 1.0 * len(T) / npos_im, too_min_rate
import numpy as np import os import sys from detectron.utils.io import save_object from detectron.utils.io import load_object if __name__ == '__main__': original_weights_file = sys.argv[1] file_out = sys.argv[2] out_blobs = {} used_blobs = set() original_src_blobs = load_object(original_weights_file) print('====================================') print('get params in original weights') for blob_name in sorted(original_src_blobs.keys()): if 'bn_s' in blob_name: pass else: continue bn_name = blob_name.rsplit('_', 1)[0] conv_name = blob_name.rsplit('_', 2)[0] if 'res_conv1_bn_s' in blob_name: conv_name = 'conv1' bn_s_name = blob_name
def grid_search(): dataset_name, proposal_file = get_inference_dataset(0, is_parent=False) roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset( dataset_name, proposal_file, None ) num_images = len(roidb) num_classes = cfg.MODEL.NUM_CLASSES subinds = np.array_split(range(num_images), cfg.NUM_GPUS) tag = 'detection' output_dir = get_output_dir(cfg.TEST.DATASETS, training=False) det_file = os.path.join(output_dir, 'detections.pkl') outputs = load_object(det_file) print(len(outputs)) all_dets_cache = outputs['all_boxes'] print(len(all_dets_cache)) all_boxes_cache = [] all_scores_cache = [] for i, entry in enumerate(roidb): print(i) max_det = all_dets_cache[1][i].shape[0] print(max_det, num_classes) boxes = np.zeros((max_det, 4), dtype=np.float32) scores = np.zeros((max_det, num_classes), dtype=np.float32) boxes[:] = -1 scores[:] = -1 for j in range(num_classes): if len(all_dets_cache[j]) > 0: pass else: continue scores[:, j] = all_dets_cache[j][i][:, 4] boxes[:, 0:4] = all_dets_cache[1][i][:, :4] boxes = np.tile(boxes, (1, scores.shape[1])) print(scores.shape, boxes.shape) all_boxes_cache.append(boxes) all_scores_cache.append(scores) timers = defaultdict(Timer) resultss = [] nmses = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0] threshs = [1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1] max_per_images = [10000, 1000, 100, 10, 1] for nms in nmses: for thresh in threshs: for max_per_image in max_per_images: print("----------------------------------------------------") print('NUM: ', nms, ' Thresh: ', thresh, ' MAX_PER_IM: ', max_per_image) cfg.immutable(False) cfg.TEST.NMS = nms cfg.TEST.SCORE_THRESH = thresh cfg.TEST.DETECTIONS_PER_IM = max_per_image cfg.immutable(True) all_boxes, all_segms, all_keyps = empty_results(num_classes, num_images) for i, entry in enumerate(roidb): # print(i) timers['im_detect_bbox'].tic() scores = all_scores_cache[i] boxes = all_boxes_cache[i] # print(scores.shape, boxes.shape) timers['im_detect_bbox'].toc() timers['misc_bbox'].tic() scores, boxes, cls_boxes_i = box_results_with_nms_and_limit(scores, boxes) timers['misc_bbox'].toc() extend_results(i, all_boxes, cls_boxes_i) results = task_evaluation.evaluate_all( dataset, all_boxes, all_segms, all_keyps, output_dir ) print(results) print(resultss) f = open('grid_search.csv', 'wb') wr = csv.writer(f, dialect='excel') wr.writerows(resultss)
def process_in_parallel( tag, total_range_size, binary, output_dir, opts='' ): """Run the specified binary cfg.NUM_GPUS times in parallel, each time as a subprocess that uses one GPU. The binary must accept the command line arguments `--range {start} {end}` that specify a data processing range. """ # Snapshot the current cfg state in order to pass to the inference # subprocesses cfg_file = os.path.join(output_dir, '{}_range_config.yaml'.format(tag)) with open(cfg_file, 'w') as f: envu.yaml_dump(cfg, stream=f) subprocess_env = os.environ.copy() processes = [] subinds = np.array_split(range(total_range_size), cfg.NUM_GPUS) # Determine GPUs to use cuda_visible_devices = os.environ.get('CUDA_VISIBLE_DEVICES') if cuda_visible_devices: gpu_inds = map(int, cuda_visible_devices.split(',')) assert -1 not in gpu_inds, \ 'Hiding GPU indices using the \'-1\' index is not supported' else: gpu_inds = range(cfg.NUM_GPUS) # Run the binary in cfg.NUM_GPUS subprocesses for i, gpu_ind in enumerate(gpu_inds): start = subinds[i][0] end = subinds[i][-1] + 1 subprocess_env['CUDA_VISIBLE_DEVICES'] = str(gpu_ind) cmd = '{binary} --range {start} {end} --cfg {cfg_file} NUM_GPUS 1 {opts}' cmd = cmd.format( binary=shlex_quote(binary), start=int(start), end=int(end), cfg_file=shlex_quote(cfg_file), opts=' '.join([shlex_quote(opt) for opt in opts]) ) logger.info('{} range command {}: {}'.format(tag, i, cmd)) if i == 0: subprocess_stdout = subprocess.PIPE else: filename = os.path.join( output_dir, '%s_range_%s_%s.stdout' % (tag, start, end) ) subprocess_stdout = open(filename, 'w') # NOQA (close below) p = subprocess.Popen( cmd, shell=True, env=subprocess_env, stdout=subprocess_stdout, stderr=subprocess.STDOUT, bufsize=1 ) processes.append((i, p, start, end, subprocess_stdout)) # Log output from inference processes and collate their results outputs = [] for i, p, start, end, subprocess_stdout in processes: log_subprocess_output(i, p, output_dir, tag, start, end) if i > 0: subprocess_stdout.close() range_file = os.path.join( output_dir, '%s_range_%s_%s.pkl' % (tag, start, end) ) range_data = load_object(range_file) outputs.append(range_data) return outputs
def complete_stats(dataset, detections_pkl, threshold, box_idx, long_output=True): # Load predictions and ground truths ds = JsonDataset(dataset) roidb = ds.get_roidb(gt=True) dets = load_object(detections_pkl) all_boxes = dets['all_boxes'] def id_or_index(ix, val): if len(val) == 0: return val else: return val[ix] true_positives = 0 true_negatives = 0 false_positives = 0 false_negatives = 0 total = len(roidb) # Iterate through all images for ix, entry in enumerate(roidb): cls_boxes_i = [ id_or_index(ix, cls_k_boxes) for cls_k_boxes in all_boxes ] preds = np.array(cls_boxes_i[box_idx]) true_boxes = entry['boxes'] # Check if the images resulted in a true/false positive/negative if (true_boxes.shape[0] == 0): if preds.shape[0] > 0 and np.max(preds[:,4]) > threshold: false_positives += 1 else: true_negatives += 1 else: if preds.shape[0] > 0 and np.max(preds[:,4]) > threshold: true_positives += 1 else: false_negatives += 1 # Calculate the statistics prec = float('nan') if true_positives+false_positives > 0: prec = true_positives/float(true_positives+false_positives) elif false_negatives == 0: prec = 1. rec = float('nan') if true_positives+false_negatives > 0: rec = true_positives/float(true_positives+false_negatives) elif false_positives == 0: rec = 1. acc = float(true_positives+true_negatives)/total fm = 0 if prec > 0 or rec > 0: fm = 2.0*prec*rec/(prec+rec) # Re-enable printing enablePrint() # Print results if (long_output): print("True positives: {}\tFalse positives: {}".format(true_positives, false_positives)) print("True negatives: {}\tFalse negatives: {}".format(true_negatives, false_negatives)) print("Total: {}".format(total)) print("Precision: " + str(prec*100)) print("Recall: " + str(rec*100)) print("F-measure: " + str(fm*100)) print("Accuracy: " + str(acc*100)) else: print("{};{};{};{};".format(acc, prec, rec, fm)) return acc
import os from time import strftime from detectron.datasets.json_dataset_wsl import JsonDataset import matplotlib as mpl import matplotlib.pyplot as plt from detectron.utils.io import save_object from detectron.utils.io import load_object if __name__ == '__main__': net_1 = sys.argv[1] net_2 = sys.argv[2] pkl_1 = load_object(net_1) pkl_2 = load_object(net_2) if 'blobs' in pkl_1.keys(): pkl_1 = pkl_1['blobs'] if 'blobs' in pkl_2.keys(): pkl_2 = pkl_2['blobs'] print(pkl_1.keys()) print(pkl_2.keys()) for key in sorted(pkl_1.keys()): if 'momentum' in key: continue if key.endswith('_b'):
def load_and_convert_PubLayNet_model(args): model_dict = load_object(args.PubLayNet_model_file_name) remove_momentum(model_dict) convert_PubLayNet_blobs_to_target_blobs(model_dict) return model_dict
from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import numpy as np import os import sys from collections import OrderedDict from six.moves import cPickle as pickle from detectron.utils.io import save_object from detectron.utils.io import load_object if __name__ == '__main__': in_path = sys.argv[1] out_path = sys.argv[2] pkl_data = load_object(in_path) pkl_data = pkl_data['blobs'] keys = pkl_data.keys() for k in list(keys): if 'momentum' in k: print('delete ', k) t = pkl_data.pop(k, None) save_object(pkl_data, out_path)
help='Proposals file 2', default='../output/proposals/nucoco_sw_f/eb/proposals_nucoco_train.pkl' ) args = parser.parse_args() return args if __name__ == '__main__': args = parse_args() fig = plt.figure(figsize=(16, 6)) coco = COCO_PLUS(args.ann_file, args.imgs_dir) # Load the proposals proposals1 = load_object(args.proposals_file1) proposals2 = load_object(args.proposals_file2) num_imgs = len(proposals1['ids']) assert len(proposals1['ids']) == len(proposals2['ids']), \ "Number of images are different in proposal files" # print(len(proposals1['indexes'])) # print(proposals2['ids']) # np.set_printoptions(threshold=np.nan) # for i in range(20): # print(proposals1['boxes'][i][0:10,:]) # print('---------------------------') # print(proposals2['boxes'][i][0:10,:]) # input('something')
def initialize_gpu_from_weights_file(model, weights_file, gpu_id=0): """Initialize a network with ops on a specific GPU. If you use CUDA_VISIBLE_DEVICES to target specific GPUs, Caffe2 will automatically map logical GPU ids (starting from 0) to the physical GPUs specified in CUDA_VISIBLE_DEVICES. """ logger.info('Loading weights from: {}'.format(weights_file)) ws_blobs = workspace.Blobs() src_blobs = load_object(weights_file) if 'cfg' in src_blobs: saved_cfg = load_cfg(src_blobs['cfg']) configure_bbox_reg_weights(model, saved_cfg) if 'blobs' in src_blobs: # Backwards compat--dictionary used to be only blobs, now they are # stored under the 'blobs' key src_blobs = src_blobs['blobs'] # Initialize weights on GPU gpu_id only unscoped_param_names = OrderedDict() # Print these out in model order for blob in model.params: unscoped_param_names[c2_utils.UnscopeName(str(blob))] = True with c2_utils.NamedCudaScope(gpu_id): for unscoped_param_name in unscoped_param_names.keys(): if (unscoped_param_name.find(']_') >= 0 and unscoped_param_name not in src_blobs): # Special case for sharing initialization from a pretrained # model: # If a blob named '_[xyz]_foo' is in model.params and not in # the initialization blob dictionary, then load source blob # 'foo' into destination blob '_[xyz]_foo' src_name = unscoped_param_name[unscoped_param_name.find(']_') + 2:] else: src_name = unscoped_param_name if src_name not in src_blobs: logger.info('{:s} not found'.format(src_name)) continue dst_name = core.ScopedName(unscoped_param_name) has_momentum = src_name + '_momentum' in src_blobs has_momentum_str = ' [+ momentum]' if has_momentum else '' logger.info( '{:s}{:} loaded from weights file into {:s}: {}'.format( src_name, has_momentum_str, dst_name, src_blobs[src_name].shape)) if dst_name in ws_blobs: # If the blob is already in the workspace, make sure that it # matches the shape of the loaded blob ws_blob = workspace.FetchBlob(dst_name) assert ws_blob.shape == src_blobs[src_name].shape, \ ('Workspace blob {} with shape {} does not match ' 'weights file shape {}').format( src_name, ws_blob.shape, src_blobs[src_name].shape) workspace.FeedBlob( dst_name, src_blobs[src_name].astype(np.float32, copy=False)) if has_momentum: workspace.FeedBlob( dst_name + '_momentum', src_blobs[src_name + '_momentum'].astype(np.float32, copy=False)) # We preserve blobs that are in the weights file but not used by the current # model. We load these into CPU memory under the '__preserve__/' namescope. # These blobs will be stored when saving a model to a weights file. This # feature allows for alternating optimization of Faster R-CNN in which blobs # unused by one step can still be preserved forward and used to initialize # another step. for src_name in src_blobs.keys(): if (src_name not in unscoped_param_names and not src_name.endswith('_momentum') and src_blobs[src_name] is not None): with c2_utils.CpuScope(): workspace.FeedBlob('__preserve__/{:s}'.format(src_name), src_blobs[src_name]) logger.info( '{:s} preserved in workspace (unused)'.format(src_name))
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
def initialize_gpu_from_weights_file(model, weights_file, gup_id=0): logger.info('Loading weights from: {}'.format(weights_file)) ws_blobs = workspace.Blobs() src_blobs = load_object(weights_file) if 'cfg' in src_blobs: saved_cfg = load_cfg(src_blobs['cfg']) configure_bbox_reg_weights(model, saved_cfg) if 'blobs' in src_blobs: src_blobs = src_blobs['blobs'] unscoped_para_names = OrderedDict() for blob in model.params: unscoped_para_names[c2_utils.UnscopeName(str(blob))] = True with c2_utils.NamedCudaScope(gup_id): for unscoped_para_name in unscoped_para_names.keys(): if (unscoped_para_name.find(']_') >= 0 and unscoped_para_name not in src_blobs): # Special case for sharing initialization from a pretrained # model: # If a blob named '_[xyz]_foo' is in model.params and not in # the initialization blob dictionary, then load source blob # 'foo' into destination blob '_[xyz]_foo' src_name = unscoped_para_name[unscoped_para_name.find((']_') + 2)] else: src_name = unscoped_para_name if src_name not in src_blobs: logger.info('{:s} not found.'.format(src_name)) continue dst_name = core.ScopedName(unscoped_para_name) has_momentum = src_name + '_momentum' in src_blobs has_momentum_str = ' [+ momentum] ' if has_momentum else '' logger.info( '{:s}{:} loaded form weights file into {:s}: {}'.format( src_name, has_momentum_str, dst_name, src_blobs[src_name].shape)) if dst_name in ws_blobs: # if the blob is already in the workspace, make sure that it matches # the shape of the loaded blob ws_blob = workspace.FetchBlob(dst_name) assert ws_blob.shape == src_blobs[src_name].shape, \ ('Workspace blob {} with shape {} does not match ' 'weights file shape {}').format( src_name, ws_blob.shape, src_blobs[src_name].shape) workspace.FeedBlob( dst_name, src_blobs[src_name].astype(np.float32, copy=False)) if has_momentum: workspace.FeedBlob( dst_name + '_momentum', src_blobs[src_name + '_momentum'].astype(np.float32, copy=False)) for src_name in src_blobs.keys(): if (src_name not in unscoped_para_names and not src_name.endswith('_momentum') and src_blobs[src_name] is not None): with c2_utils.CpuScope(): workspace.FeedBlob('__presever__/{:s}'.format(src_name), src_blobs[src_name]) logger.info( '{:s} preserved in workspace (unused)'.format(src_name))
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)
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