def _add_detection_gt(self, img, add_mask): """ Add 'boxes', 'class', 'is_crowd' of this image to the dict, used by detection. If add_mask is True, also add 'segmentation' in coco poly format. """ # ann_ids = self.coco.getAnnIds(imgIds=img['image_id']) # objs = self.coco.loadAnns(ann_ids) objs = self.coco.imgToAnns[img['image_id']] # equivalent but faster than the above two lines # clean-up boxes valid_objs = [] width = img.pop('width') height = img.pop('height') for objid, obj in enumerate(objs): if obj.get('ignore', 0) == 1: continue x1, y1, w, h = obj['bbox'] # bbox is originally in float # x1/y1 means upper-left corner and w/h means true w/h. This can be verified by segmentation pixels. # But we do make an assumption here that (0.0, 0.0) is upper-left corner of the first pixel x1 = np.clip(float(x1), 0, width) y1 = np.clip(float(y1), 0, height) w = np.clip(float(x1 + w), 0, width) - x1 h = np.clip(float(y1 + h), 0, height) - y1 # Require non-zero seg area and more than 1x1 box size if obj['area'] > 1 and w > 0 and h > 0 and w * h >= 4: obj['bbox'] = [x1, y1, x1 + w, y1 + h] valid_objs.append(obj) if add_mask: segs = obj['segmentation'] if not isinstance(segs, list): assert obj['iscrowd'] == 1 obj['segmentation'] = None else: valid_segs = [np.asarray(p).reshape(-1, 2).astype('float32') for p in segs if len(p) >= 6] if len(valid_segs) == 0: logger.error("Object {} in image {} has no valid polygons!".format(objid, img['file_name'])) elif len(valid_segs) < len(segs): logger.warn("Object {} in image {} has invalid polygons!".format(objid, img['file_name'])) obj['segmentation'] = valid_segs # all geometrically-valid boxes are returned boxes = np.asarray([obj['bbox'] for obj in valid_objs], dtype='float32') # (n, 4) cls = np.asarray([ self.COCO_id_to_category_id[obj['category_id']] for obj in valid_objs], dtype='int32') # (n,) is_crowd = np.asarray([obj['iscrowd'] for obj in valid_objs], dtype='int8') # add the keys img['boxes'] = boxes # nx4 img['class'] = cls # n, always >0 img['is_crowd'] = is_crowd # n, if add_mask: # also required to be float32 img['segmentation'] = [ obj['segmentation'] for obj in valid_objs]
def _run_command(self): m = self.trainer.monitors v = {k: round(m.get_latest(k), 4) for k in self._stats} v['epoch'] = self.epoch_num cmd = self._command.format(**v) ret = os.system(cmd) if ret != 0: logger.error("Command {} failed with ret={}!".format( cmd, ret))
def convert_param_name(param): resnet_param = {} for k, v in six.iteritems(param): try: newname = name_conversion(k) except: logger.error("Exception when processing caffe layer {}".format(k)) raise logger.info("Name Transform: " + k + ' --> ' + newname) resnet_param[newname] = v return resnet_param
def convert_param_name(param): resnet_param = {} for k, v in six.iteritems(param): try: newname = name_conversion(k) except Exception: logger.error("Exception when processing caffe layer {}".format(k)) raise logger.info("Name Transform: " + k + ' --> ' + newname) resnet_param[newname] = v return resnet_param
def predict_unlabeled(model, model_path, nr_visualize=100, output_dir='output_patch_samples'): """Predict the pseudo label information of unlabeled data.""" assert cfg.EVAL.PSEUDO_INFERENCE, 'set cfg.EVAL.PSEUDO_INFERENCE=True' df, dataset_size = get_eval_unlabeled_dataflow(cfg.DATA.TRAIN, return_size=True) df.reset_state() predcfg = PredictConfig( model=model, session_init=SmartInit(model_path), input_names=['image'], # ['image', 'gt_boxes', 'gt_labels'], output_names=[ 'generate_{}_proposals/boxes'.format( 'fpn' if cfg.MODE_FPN else 'rpn'), 'generate_{}_proposals/scores'.format( 'fpn' if cfg.MODE_FPN else 'rpn'), 'fastrcnn_all_scores', 'output/boxes', 'output/scores', # score of the labels 'output/labels', ]) pred = OfflinePredictor(predcfg) if os.path.isdir(output_dir): if os.path.isfile(os.path.join(output_dir, 'pseudo_data.npy')): os.remove(os.path.join(output_dir, 'pseudo_data.npy')) if not os.path.isdir(os.path.join(output_dir, 'vis')): os.makedirs(os.path.join(output_dir, 'vis')) else: shutil.rmtree(os.path.join(output_dir, 'vis')) fs.mkdir_p(output_dir + '/vis') else: fs.mkdir_p(output_dir) fs.mkdir_p(output_dir + '/vis') logger.warning('-' * 100) logger.warning('Write to {}'.format(output_dir)) logger.warning('-' * 100) with tqdm.tqdm(total=nr_visualize) as pbar: for idx, dp in itertools.islice(enumerate(df), nr_visualize): img, img_id = dp # dp['image'], dp['img_id'] rpn_boxes, rpn_scores, all_scores, \ final_boxes, final_scores, final_labels = pred(img) outs = { 'proposals_boxes': rpn_boxes, # (?,4) 'proposals_scores': rpn_scores, # (?,) 'boxes': final_boxes, 'scores': final_scores, 'labels': final_labels } ratios = [10, 10] # [top 20% as background, bottom 20% as background] bg_ind, fg_ind = custom.find_bg_and_fg_proposals(all_scores, ratios=ratios) bg_viz = draw_predictions(img, rpn_boxes[bg_ind], all_scores[bg_ind]) fg_viz = draw_predictions(img, rpn_boxes[fg_ind], all_scores[fg_ind]) results = [ DetectionResult(*args) for args in zip(final_boxes, final_scores, final_labels, [None] * len(final_labels)) ] final_viz = draw_final_outputs(img, results) viz = tpviz.stack_patches([bg_viz, fg_viz, final_viz], 2, 2) if os.environ.get('DISPLAY', None): tpviz.interactive_imshow(viz) assert cv2.imwrite('{}/vis/{:03d}.png'.format(output_dir, idx), viz) pbar.update() logger.info('Write {} samples to {}'.format(nr_visualize, output_dir)) ## Parallel inference the whole unlabled data pseudo_preds = collections.defaultdict(list) num_tower = max(cfg.TRAIN.NUM_GPUS, 1) graph_funcs = MultiTowerOfflinePredictor(predcfg, list( range(num_tower))).get_predictors() dataflows = [ get_eval_unlabeled_dataflow(cfg.DATA.TRAIN, shard=k, num_shards=num_tower) for k in range(num_tower) ] all_results = multithread_predict_dataflow(dataflows, graph_funcs) for id, result in tqdm.tqdm(enumerate(all_results)): img_id = result['image_id'] outs = { 'proposals_boxes': result['proposal_box'].astype(np.float16), # (?,4) 'proposals_scores': result['proposal_score'].astype(np.float16), # (?,) # 'frcnn_all_scores': result['frcnn_score'].astype(np.float16), 'boxes': result['bbox'].astype(np.float16), # (?,4) 'scores': result['score'].astype(np.float16), # (?,) 'labels': result['category_id'].astype(np.float16) # (?,) } pseudo_preds[img_id] = outs logger.warn('Writing to {}'.format( os.path.join(output_dir, 'pseudo_data.npy'))) try: dd.io.save(os.path.join(output_dir, 'pseudo_data.npy'), pseudo_preds) except RuntimeError: logger.error('Save failed. Check reasons manually...')
parser.add_argument('-d', '--depth', help='resnet depth', required=True, type=int, choices=[50, 101, 152]) parser.add_argument('--input', help='an input image') parser.add_argument('--eval', help='ILSVRC dir to run validation on') args = parser.parse_args() assert args.input or args.eval, "Choose either input or eval!" if args.gpu: os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu MODEL_DEPTH = args.depth param = np.load(args.load, encoding='latin1').item() resnet_param = {} for k, v in six.iteritems(param): try: newname = name_conversion(k) except: logger.error("Exception when processing caffe layer {}".format(k)) raise logger.info("Name Transform: " + k + ' --> ' + newname) resnet_param[newname] = v if args.eval: eval_on_ILSVRC12(resnet_param, args.eval) else: run_test(resnet_param, args.input)
def _add_detection_gt(self, img, add_mask): """ Add 'boxes', 'class', 'is_crowd' of this image to the dict, used by detection. If add_mask is True, also add 'segmentation' in coco poly format. """ # ann_ids = self.coco.getAnnIds(imgIds=img['image_id']) # objs = self.coco.loadAnns(ann_ids) objs = self.coco.imgToAnns[ img["image_id"]] # equivalent but faster than the above two lines if "minival" not in self.annotation_file: # TODO better to check across the entire json, rather than per-image ann_ids = [ann["id"] for ann in objs] assert len(set(ann_ids)) == len(ann_ids), \ "Annotation ids in '{}' are not unique!".format(self.annotation_file) # clean-up boxes width = img.pop("width") height = img.pop("height") all_boxes = [] all_segm = [] all_cls = [] all_iscrowd = [] for objid, obj in enumerate(objs): if obj.get("ignore", 0) == 1: continue x1, y1, w, h = list(map(float, obj["bbox"])) # bbox is originally in float # x1/y1 means upper-left corner and w/h means true w/h. This can be verified by segmentation pixels. # But we do make an assumption here that (0.0, 0.0) is upper-left corner of the first pixel x2, y2 = x1 + w, y1 + h # np.clip would be quite slow here x1 = min(max(x1, 0), width) x2 = min(max(x2, 0), width) y1 = min(max(y1, 0), height) y2 = min(max(y2, 0), height) w, h = x2 - x1, y2 - y1 # Require non-zero seg area and more than 1x1 box size if obj["area"] > 1 and w > 0 and h > 0: all_boxes.append([x1, y1, x2, y2]) all_cls.append( self.COCO_id_to_category_id.get(obj["category_id"], obj["category_id"])) iscrowd = obj.get("iscrowd", 0) all_iscrowd.append(iscrowd) if add_mask: segs = obj["segmentation"] if not isinstance(segs, list): assert iscrowd == 1 all_segm.append(None) else: valid_segs = [ np.asarray(p).reshape(-1, 2).astype("float32") for p in segs if len(p) >= 6 ] if len(valid_segs) == 0: logger.error( "Object {} in image {} has no valid polygons!".format( objid, img["file_name"])) elif len(valid_segs) < len(segs): logger.warn("Object {} in image {} has invalid polygons!".format( objid, img["file_name"])) all_segm.append(valid_segs) # all geometrically-valid boxes are returned if len(all_boxes): img["boxes"] = np.asarray(all_boxes, dtype="float32") # (n, 4) else: img["boxes"] = np.zeros((0, 4), dtype="float32") cls = np.asarray(all_cls, dtype="int32") # (n,) if len(cls): assert cls.min() > 0, "Category id in COCO format must > 0!" img["class"] = cls # n, always >0 img["is_crowd"] = np.asarray(all_iscrowd, dtype="int8") # n, if add_mask: # also required to be float32 img["segmentation"] = all_segm
parser.add_argument('--gpu', help='comma separated list of GPU(s) to use.') parser.add_argument('--data', help='ILSVRC dataset dir') parser.add_argument('-r', '--ratio', type=float, default=0.5, choices=[1., 0.5]) parser.add_argument('--group', type=int, default=8, choices=[3, 4, 8], help="Number of groups for ShuffleNetV1") parser.add_argument('--v2', action='store_true', help='Use ShuffleNetV2') parser.add_argument('--load', help='path to load a model from') parser.add_argument('--eval', action='store_true') parser.add_argument('--flops', action='store_true', help='print flops and exit') args = parser.parse_args() if args.gpu: os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu if args.v2 and args.group != parser.get_default('group'): logger.error("group= is not used in ShuffleNetV2!") model = Model() if args.eval: batch = 128 # something that can run on one gpu ds = get_data('val', batch) eval_on_ILSVRC12(model, get_model_loader(args.load), ds) elif args.flops: # manually build the graph with batch=1 input_desc = [ InputDesc(tf.float32, [1, 224, 224, 3], 'input'), InputDesc(tf.int32, [1], 'label') ] input = PlaceholderInput() input.setup(input_desc)
def _aggregate_batch(data_holder, use_list=False): error_msg = "batch must contain tensors, numbers, dicts or lists; found {}" size = len(data_holder[0]) result = [] for k in range(size): if use_list: result.append([x[k] for x in data_holder]) else: dt = data_holder[0][k] batch = [x[k] for x in data_holder] if type(dt) in list(six.integer_types) + [bool]: tp = 'int32' elif type(dt) == float: tp = 'float32' else: try: tp = dt.dtype except AttributeError: raise TypeError("Unsupported type to batch: {}".format( type(dt))) try: if isinstance(dt, torch.Tensor): out = None if _use_shared_memory: # If we're in a background process, concatenate directly into a # shared memory tensor to avoid an extra copy numel = sum([b.numel() for b in batch]) storage = data_holder[0][k].storage()._new_shared( numel) out = data_holder[0][k].new(storage) result.append(torch.stack(batch, 0, out=out)) elif type(dt).__name__ == 'ndarray': # array of string classes and object if re.search('[SaUO]', dt.dtype.str) is not None: raise TypeError(error_msg.format(dt.dtype)) result.append( torch.stack([torch.from_numpy(b) for b in batch], 0)) elif isinstance(dt, six.integer_types): result.append(torch.LongTensor(batch)) elif isinstance(dt, float): result.append(torch.DoubleTensor(batch)) elif isinstance(dt, six.string_types): result.append(batch) else: raise TypeError((error_msg.format(type(dt)))) except Exception as e: # noqa logger.exception(e.message) logger.exception( "Cannot batch data. Perhaps they are of inconsistent shape?" ) if isinstance(dt, np.ndarray): s = pprint.pformat([x[k].shape for x in data_holder]) logger.error("Shape of all arrays to be batched: " + s) try: # open an ipython shell if possible import IPython as IP IP.embed() # noqa except ImportError: pass return result
parser.add_argument('--data', help='ILSVRC dataset dir') parser.add_argument('-r', '--ratio', type=float, default=0.5, choices=[1., 0.5]) parser.add_argument('--group', type=int, default=8, choices=[3, 4, 8], help="Number of groups for ShuffleNetV1") parser.add_argument('--v2', action='store_true', help='Use ShuffleNetV2') parser.add_argument('--batch', type=int, default=1024, help='total batch size') parser.add_argument('--load', help='path to load a model from') parser.add_argument('--eval', action='store_true') parser.add_argument('--flops', action='store_true', help='print flops and exit') args = parser.parse_args() if args.gpu: os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu if args.v2 and args.group != parser.get_default('group'): logger.error("group= is not used in ShuffleNetV2!") if args.batch != 1024: logger.warn("Total batch size != 1024, you need to change other hyperparameters to get the same results.") TOTAL_BATCH_SIZE = args.batch model = Model() if args.eval: batch = 128 # something that can run on one gpu ds = get_data('val', batch) eval_classification(model, SmartInit(args.load), ds) elif args.flops: # manually build the graph with batch=1 with TowerContext('', is_training=False): model.build_graph(
def _add_detection_gt(self, img, add_mask): """ Add 'boxes', 'class', 'is_crowd' of this image to the dict, used by detection. If add_mask is True, also add 'segmentation' in coco poly format. """ # ann_ids = self.coco.getAnnIds(imgIds=img['id']) # objs = self.coco.loadAnns(ann_ids) objs = self.coco.imgToAnns[img['image_id']] # equivalent but faster than the above two lines # clean-up boxes width = img['width'] height = img['height'] all_boxes = [] all_segm = [] all_cls = [] all_iscrowd = [] for objid, obj in enumerate(objs): if obj.get('ignore', 0) == 1: continue x1, y1, w, h = list(map(float, obj['bbox'])) # bbox is originally in float # x1/y1 means upper-left corner and w/h means true w/h. This can be verified by segmentation pixels. # But we do make an assumption here that (0.0, 0.0) is upper-left corner of the first pixel x2, y2 = x1 + w, y1 + h # np.clip would be quite slow here x1 = min(max(x1, 0), width) x2 = min(max(x2, 0), width) y1 = min(max(y1, 0), height) y2 = min(max(y2, 0), height) w, h = x2 - x1, y2 - y1 # Require non-zero seg area and more than 1x1 box size if obj['area'] > 1 and w > 0 and h > 0 and w * h >= 4: all_boxes.append([x1, y1, x2, y2]) all_cls.append(self.COCO_id_to_category_id.get(obj['category_id'], obj['category_id'])) iscrowd = obj.get("iscrowd", 0) all_iscrowd.append(iscrowd) if add_mask: segs = obj['segmentation'] if not isinstance(segs, list): assert iscrowd == 1 all_segm.append(None) else: valid_segs = [np.asarray(p).reshape(-1, 2).astype('float32') for p in segs if len(p) >= 6] if len(valid_segs) == 0: logger.error("Object {} in image {} has no valid polygons!".format(objid, img['file_name'])) elif len(valid_segs) < len(segs): logger.warn("Object {} in image {} has invalid polygons!".format(objid, img['file_name'])) all_segm.append(valid_segs) # all geometrically-valid boxes are returned img['boxes'] = np.asarray(all_boxes, dtype='float32') # (n, 4) cls = np.asarray(all_cls, dtype='int32') # (n,) if len(cls): assert cls.min() > 0, "Category id in COCO format must > 0!" img['class'] = cls # n, always >0 img['is_crowd'] = np.asarray(all_iscrowd, dtype='int8') # n, if add_mask: # also required to be float32 img['segmentation'] = all_segm
def _run_command(self): ret = os.system(self._command) if ret != 0: logger.error("Command {} failed with ret={}!".format( self._command, ret))