Пример #1
0
    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]
Пример #2
0
 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))
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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...')
Пример #6
0
    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)
Пример #7
0
  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
Пример #8
0
    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)
Пример #9
0
    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
Пример #10
0
    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(
Пример #11
0
    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
Пример #12
0
 def _run_command(self):
     ret = os.system(self._command)
     if ret != 0:
         logger.error("Command {} failed with ret={}!".format(
             self._command, ret))