Esempio n. 1
0
def test_class_accuracy(network: torch.nn, loader: torch.utils.data.DataLoader,
                        device: torch.device) -> float:
    """
    Test the class accuracy of a network on a dataset.

    :param network: network to test
    :param loader: loader to test
    :param device: device to use
    :return: result accuracy
    """
    network.eval()
    network.classify = True

    accuracy = 0
    classes = utils.datasets.get_vggface2_classes("train")

    for _, sample in enumerate(loader):
        inputs, labels = sample
        inputs = inputs.to(device)

        outputs = network(inputs)

        # Convert the class names with the class id and transpose the tensor.
        labels = [classes.index(label) for label in labels]
        labels = torch.LongTensor(labels).T
        labels = labels.to(device)

        output_labels = torch.topk(outputs, 1).indices.view(-1)
        accuracy += torch.count_nonzero(output_labels == labels)

    accuracy = accuracy / (len(loader.dataset) * 3)
    return accuracy
Esempio n. 2
0
def valid_fn(
    model: torch.nn, 
    data_loader: DataLoader, 
    device: torch.device, 
    class_names: Dict[int, str], 
    valid: bool = True):
    """
    평가 및 결과 저장
    """
    xml_root = ET.Element('predictions')
    batch_size: int = data_loader.batch_size
    model.eval()
    with torch.set_grad_enabled(False):
        for i, (images, _) in tqdm(enumerate(data_loader)):
            images = list(image.to(device) for image in images)
            outputs = model(images)
            for j, output in enumerate(outputs):
                image_name: str = data_loader.dataset.images[i*batch_size+j]
                xml_image = ET.SubElement(xml_root, 'image', {'name': image_name})

                boxes = output['boxes'].detach().cpu().numpy()
                labels = output['labels'].detach().cpu().numpy()
                scores = output['scores'].detach().cpu().numpy()

                for box, label, score in zip(boxes, labels, scores):
                    attribs = {
                        'class_name': class_names[label],
                        'score': str(float(score)), 
                        'x1': str(int(box[0])), 
                        'y1': str(int(box[1])), 
                        'x2': str(int(box[2])), 
                        'y2': str(int(box[3]))
                    }
                    ET.SubElement(xml_image, 'predict', attribs)
                
    indent(xml_root)
    tree = ET.ElementTree(xml_root)
    if not os.path.exists('./output/'):
        os.mkdir('./output/')

    if valid:
        tree.write('./output/validation.xml')
    else:
        tree.write('./output/prediction.xml')
    print('Save predicted labels.xml...\n')
Esempio n. 3
0
def test_fn(
    model: torch.nn, 
    data_loader: DataLoader, 
    class_nums: Dict,
    device: torch.device):
    image_ids = [image_id.split('.')[1][-17:] for image_id in data_loader.dataset.image_ids]
    xml_root = ET.Element('predictions')
    model.eval()
    batch_size = data_loader.batch_size
    with torch.no_grad():
        for i, (images, _) in tqdm(enumerate(data_loader)):
            images = list(image.to(device) for image in images)
            outputs = model(images)
            for j, output in enumerate(outputs):
                image_name = image_ids[i*batch_size+j]
                xml_image = ET.SubElement(xml_root, 'image', {'name': image_name})

                masks = output['masks'].detach().cpu().numpy()
                labels = output['labels'].detach().cpu().numpy()
                scores = output['scores'].detach().cpu().numpy()

                for mask, label, score in zip(masks, labels, scores):
                    mask_bin = np.where(mask[0] > 0.1, True, False)
                    polygons = Mask(mask_bin).polygons()
                    points = polygons.points
                    point = ''.join([str(p[0]) + ',' + str(p[1]) +';' for p in points[0]])
                    attribs = {
                        'class_name': class_nums[label],
                        'score': str(float(score)), 
                        'polygon': point,
                    }
                    ET.SubElement(xml_image, 'predict', attribs)
                
    indent(xml_root)
    tree = ET.ElementTree(xml_root)
    if not os.path.exists('./output/'):
        print('Not exists ./output/ making an weight folder...')
        os.mkdir('./output/')

    tree.write('./output/prediction.xml')
    print('Save predicted labels.xml...\n')
Esempio n. 4
0
def predict( model:torch.nn, final_activ:torch.nn.functional, dl, out_type, with_preds = False ):
  model.eval()
  for n, batch in enumerate( dl ):
    batch = [ nb.to( device = DEFAULT_DEVICE ) for nb in batch ]
    preds_batch = model( batch[0] )
    outputs_batch = apply_final_activ( \
      input = preds_batch, out_type = out_type, final_activ = final_activ, with_preds = with_preds
    )
    if with_preds: outputs_batch, preds_batch = outputs_batch
    if not n:
      if with_preds:
        preds = torch.empty( len( dl.dataset ), preds_batch.shape[1], \
                device = DEFAULT_DEVICE, dtype = preds_batch.dtype )
      outputs = torch.empty( len( dl.dataset ), \
                device = DEFAULT_DEVICE, dtype = outputs_batch.dtype )
    if with_preds:
      preds[ n*dl.batch_size : (n+1)*dl.batch_size, : ] = preds_batch
    outputs[ n*dl.batch_size : (n+1)*dl.batch_size ] = outputs_batch

  if with_preds: _re = ( outputs, preds )
  else: _re = output

  return _re
    def _get_cv_stats(self, model: torch.nn) -> Tuple[torch.tensor, ...]:
        """
        Collect CV data accuracy, loss, prediction distribution, and targets
        distribution.

        Arguments:
            model {torch.nn} -- model to learn

        Returns:
            Tuple[torch.tensor * 4] -- accuracy, loss, prediction distribution, and
                targets distribution.
        """
        cv_acc = torch.tensor(0.0).to(self.device)
        cv_loss = torch.tensor(0.0).to(self.device)
        samples_no = float(len(self.cvloader.dataset))
        outputs_dist = None
        targets_dist = None

        with torch.no_grad():
            model = model.eval()

            for inputs, targets in self.cvloader:
                batch_size = inputs.shape[
                    0]  # last sample can have different items

                targets = targets.to(self.device)
                outputs = model(inputs.to(self.device))

                if outputs_dist is None and targets_dist is None:
                    outputs_dist = outputs.argmax(1).long()
                    targets_dist = targets.long()
                else:
                    outputs_dist = torch.cat(
                        [outputs_dist, outputs.argmax(1).long()])
                    targets_dist = torch.cat([targets_dist, targets.long()])

                cv_acc += (outputs.argmax(1) == targets).sum()
                cv_loss += self.criterion(outputs, targets) * batch_size

            cv_acc = (cv_acc / samples_no).to(CPU_DEVICE)
            cv_loss = (cv_loss / samples_no).to(CPU_DEVICE)
            outputs_dist = outputs_dist.to(CPU_DEVICE)
            targets_dist = targets_dist.to(CPU_DEVICE)

        model = model.train()
        return cv_acc, cv_loss, outputs_dist, targets_dist
def generate_sample(
    model: torch.nn,
    features: int = 10,
    targets: int = 1,
    iterations: int = 10,
    image: Tensor = None,
    image_size: int = 64,
    return_intermediate: bool = True,
    device: str = "cpu",
    rotations: int = 2,
    batch_size: int = 256,
    all_random: bool = True,
) -> List[Tensor]:
    """
    Create a sample either generated on top of a starting image
    or from a random image. Return a series of images with the
    for each time the network is applied.
    Args :
      model : The nn model
      features : The number of points used for interpolation
      targets : The number of target points where RGB will be predicted
      iterations : Number of times to apply the network to the image
      image : An unnormalized image to use as the initial value
      image_size : The width of the image (assumed square)
      return_intermediate : Return intermediate values if true
      device : The device to perform operations on
      rotations : The number of rotations used by the network
      batch_size : Set the batch size to run through the network
    Returns :
      A list of images for each time the network is applied
    """

    num_pixels = image_size * image_size
    model.eval()

    if image is None:
        image = torch.rand([3, image_size, image_size], device=device) * 2 - 1
    else:
        image = (image / 255) * 2 - 1

    stripe_list = positions_from_mesh(
        width=image_size,
        height=image_size,
        device=device,
        rotations=rotations,
        normalize=True,
    )

    # These need to be normalized otherwise the max is the width of the grid
    new_vals = torch.cat([val.unsqueeze(0) for val in stripe_list])

    result_list = []
    for count in range(iterations):
        logger.info(f"Generating for count {count}")

        if all_random is True:
            image = torch.rand([3, image_size, image_size], device=device) * 2 - 1

        full_features = torch.cat([image, new_vals])
        channels, h, w = full_features.shape
        full_features = full_features.reshape(channels, -1).permute(1, 0)

        feature_indices = torch.remainder(
            torch.randperm(num_pixels * features, device=device), num_pixels
        )
        target_indices = torch.arange(start=0, end=num_pixels, device=device)

        features_tensor = full_features[feature_indices].reshape(-1, features, channels)
        targets_tensor = full_features[target_indices].reshape(-1, 1, channels)

        # Distances are measured relative to target so remove that component
        features_tensor[:, :, 3:] = features_tensor[:, :, 3:] - targets_tensor[:, :, 3:]

        result = model(features_tensor.flatten(1))
        image = result.reshape(image_size, image_size, 3).permute(2, 0, 1)

        result_list.append(image)

    return result_list
def generate_sample_radial(
    model: torch.nn,
    features: int = 10,
    targets: int = 1,
    iterations: int = 10,
    start_image: Tensor = None,
    image_size: int = 64,
    return_intermediate: bool = True,
    device: str = "cpu",
    rotations: int = 2,
    batch_size: int = 256,
    all_random: bool = True,
) -> List[Tensor]:
    """
    Create a sample either generated on top of a starting image
    or from a random image. Return a series of images with the
    for each time the network is applied.
    Args :
      model : The nn model
      features : The number of points used for interpolation
      targets : The number of target points where RGB will be predicted
      iterations : Number of times to apply the network to the image
      start_image : An normalized image to use as the initial value in range [-1, 1]
      image_size : The width of the image (assumed square)
      return_intermediate : Return intermediate values if true
      device : The device to perform operations on
      rotations : The number of rotations used by the network
      batch_size : Set the batch size to run through the network
    Returns :
      A list of images for each time the network is applied
    """

    num_pixels = image_size * image_size
    model.eval()

    if start_image is None:
        image = torch.rand([3, image_size, image_size], device=device) * 2 - 1
    else:
        image = copy.deepcopy(start_image)

    stripe_list = positions_from_mesh(
        width=image_size,
        height=image_size,
        device=device,
        rotations=rotations,
        normalize=True,
    )

    # These need to be normalized otherwise the max is the width of the grid
    stripe_list = torch.cat([val.unsqueeze(0) for val in stripe_list])

    indices, target_linear_indices = indices_from_grid(image_size, device=device)

    result_list = []
    for count in range(iterations):
        logger.info(f"Generating for count {count}")

        if all_random is True and start_image is None:
            image = torch.rand([3, image_size, image_size], device=device) * 2 - 1
        elif all_random is True and start_image is not None:
            image = copy.deepcopy(start_image)

        features_tensor, targets_tensor = random_radial_samples_from_image(
            img=image,
            stripe_list=stripe_list,
            image_size=image_size,
            feature_pixels=features,
            indices=indices,
            target_linear_indices=target_linear_indices,
            device=device,
        )

        result = model(features_tensor.flatten(1))
        image = result.reshape(image_size, image_size, 3).permute(2, 0, 1)

        result_list.append(image)

    return result_list
Esempio n. 8
0
def update_training_pool_ids(net: torch.nn, training_pool_ids_path: str,
                             all_training_data, device: str):
    """
    training_pool_ids_path: the path to json file which contains images id in training pool.
    This function will use an acquisition function to collect new 100 imgs into training pool each phase.
        /Increase the json file 100 more imgs each phase.
    """
    batch_size = 1
    training_pool_data = get_pool_data(training_pool_ids_path)
    all_training_data = get_pool_data(all_training_data)
    active_pool = set(all_training_data) - set(training_pool_data)
    dataset = RestrictedDataset(dir_img, dir_mask, list(active_pool))
    pool_loader = DataLoader(dataset,
                             batch_size=1,
                             shuffle=True,
                             num_workers=4,
                             pin_memory=True)

    std = []
    imgs_id = []

    net.eval()
    n_pool = len(dataset)
    with tqdm(total=n_pool, desc='STD calculating', unit='batch',
              leave=False) as pbar:
        for ind, batch in enumerate(tqdm(pool_loader)):
            imgs, true_masks = batch['image'], batch['mask']
            imgs = imgs.to(device=device, dtype=torch.float32)
            true_masks = true_masks.to(device=device,
                                       dtype=torch.float32)  # BHWC
            true_masks = true_masks[:, :1, :, :]

            y_pred_samples = []
            for i in range(GAUSS_ITERATION):
                with torch.no_grad():
                    logits = net(imgs)
                    y_pred = torch.sigmoid(logits)
                    # y_pred = (y_pred > 0.5).float()
                    y_pred = y_pred[:, :1, :, :]
                    y_pred_samples.append(
                        y_pred[:, 0, :, :]
                    )  # y_pred_samples's shape: (inx, bat, H, W )
            y_pred_samples = torch.stack(y_pred_samples, dim=0)
            y_pred_samples = y_pred_samples.type(torch.FloatTensor)
            mean_y_pred = y_pred_samples.mean(dim=0)  # shape: batch, H, W
            std_y_pred = y_pred_samples.std(dim=0)  # shape: batch, H, W
            grid = torchvision.utils.make_grid(mean_y_pred.unsqueeze(1))
            _std = get_segmentation_mask_uncertainty(std_y_pred)
            _imgs_id = batch['id']
            for i in range(batch_size):
                if i >= len(_std):
                    continue
                std.extend(_std)
                imgs_id.extend(_imgs_id)
            pbar.update()

    std, imgs_id = zip(*sorted(zip(std, imgs_id)))  # order = ascending
    print("length of std/imgs_id: ", len(std), len(imgs_id))
    top_100img = imgs_id[-100:]
    for i in top_100img:
        add_image_id_to_pool(i, training_pool_ids_path)
    print("Adding successfully!")
Esempio n. 9
0
def update_training_pool_ids_2(net: torch.nn,
                               training_pool_ids_path: str,
                               all_training_data,
                               device: str,
                               acquisition_func: str = "cfe"):
    """
    training_pool_ids_path: the path to json file which contains images id in training pool.
    acquisition_func: string name of acquisition function:
                    available function: mutual_information, mean_first_entropy, category_first_entropy
    This function will use an acquisition function to collect new 100 imgs into training pool each phase.
        /Increase the json file 100 more imgs each phase.

    """
    batch_size = 1
    training_pool_data = get_pool_data(training_pool_ids_path)
    all_training_data = get_pool_data(all_training_data)
    active_pool = set(all_training_data) - set(training_pool_data)
    dataset = RestrictedDataset(dir_img, dir_mask, list(active_pool))
    pool_loader = DataLoader(dataset,
                             batch_size=1,
                             shuffle=True,
                             num_workers=4,
                             pin_memory=True)

    value = []
    imgs_id = []

    if acquisition_func == "cfe":
        evaluation_criteria = acquisition_function.category_first_entropy
    elif acquisition_func == "mfe":
        evaluation_criteria = acquisition_function.mean_first_entropy
    elif acquisition_func == "mi":
        evaluation_criteria = acquisition_function.mutual_information
    else:
        print("Error choosing acquisition function")
        evaluation_criteria = None

    net.eval()
    n_pool = len(dataset)
    with tqdm(total=n_pool, desc='STD calculating', unit='batch',
              leave=False) as pbar:
        for ind, batch in enumerate(tqdm(pool_loader)):
            imgs, true_masks = batch['image'], batch['mask']
            imgs = imgs.to(device=device, dtype=torch.float32)
            true_masks = true_masks.to(device=device,
                                       dtype=torch.float32)  # BHWC
            true_masks = true_masks[:, :1, :, :]

            _value = evaluation_criteria(GAUSS_ITERATION, net, imgs)
            _imgs_id = batch['id']
            for i in range(batch_size):
                if i >= len(_value):
                    continue
                value.extend(_value)
                imgs_id.extend(_imgs_id)
            pbar.update()

    value, imgs_id = zip(*sorted(zip(value, imgs_id)))  # order = ascending
    print("length of value/imgs_id: ", len(value), len(imgs_id))
    top_100img = imgs_id[-100:]  # the higher
    for i in top_100img:
        add_image_id_to_pool(i, training_pool_ids_path)
    print("Adding successfully!")