示例#1
0
def generate_pseudo(model: nn.Module, dataset: Dataset, transform: Augmentation,
                    device: torch.device = None, args: Arguments.parse.Namespace = None, **kwargs) \
        -> dict:
    result = {}

    evaluator = Evaluator(num_classes=dataset.num_classes)

    ground = Path(args.unlabeled_gt)
    dest = Path(
        args.dest).joinpath('pseudo').joinpath(f"{kwargs['iteration']:08}")
    dest.mkdir(exist_ok=True, parents=True)

    model.eval()
    for index in tqdm(range(len(dataset))):
        name = dataset.pull_name(index)
        destination = dest.joinpath(f'{name}{dataset.DETECTION_EXT}')
        groundtruth = ground.joinpath(f'{name}{dataset.DETECTION_EXT}')

        image = dataset.pull_image(index)
        scale = torch.Tensor([
            image.shape[1],
            image.shape[0],
            image.shape[1],
            image.shape[0],
        ]).to(device)

        image = Variable(
            torch.from_numpy(transform(image)[0]).permute(
                2, 0, 1).unsqueeze(0)).to(device)

        detection = np.empty((0, 6), dtype=np.float32)
        detections, *_ = model(image).data

        for klass, boxes in enumerate(detections):
            if klass != dataset.class_id:
                continue
            candidates = boxes[boxes[:, 0] >= args.thresh]
            # filter out of image
            candidates = candidates[(torch.sum(
                (candidates < -1) | (candidates > 2), axis=1) == 0
                                     ).nonzero().squeeze(0), :].reshape(-1, 5)

            # filter nan and inf
            candidates = candidates[(
                torch.
                sum(torch.isinf(candidates)
                    | torch.isnan(candidates), axis=1) == 0
            ).nonzero().squeeze(0), :].reshape(-1, 5)

            if candidates.size(0) == 0:
                continue

            candidates[:, 1:] *= scale

            detection = np.concatenate((
                detection,
                np.hstack((
                    np.full((np.size(candidates, 0), 1), klass,
                            dtype=np.uint8),
                    candidates.cpu().detach().numpy(),
                )),
            ))

        if args.unlabeled_gt and groundtruth.exists():
            gt = pd.read_csv(str(groundtruth), header=None).values

            if detection.size and gt.size:
                evaluator.update((
                    detection[:, 0].astype(np.int),
                    detection[:, 1].astype(np.float32),
                    detection[:, 2:].astype(np.float32),
                    None,
                ), (
                    np.ones(np.size(gt, 0), dtype=np.int),
                    gt.astype(np.float32),
                    None,
                ))

        pd.DataFrame(detection).to_csv(str(destination),
                                       header=None,
                                       index=None)

    if args.unlabeled_gt:
        result.update({'acc': evaluator.mAP[1:].mean()})

    model.train()
    dataset.detections = list(sorted(dest.glob(f'*{dataset.DETECTION_EXT}')))

    return result