def remake_to_labelorder(pred_tensor: torch.tensor,
                         label_tensor: torch.tensor) -> dict:
    pred_ = pred_tensor.cuda().cpu().detach().numpy().copy()
    pred_ = np.array([np.argmax(i) for i in pred_])
    label_ = label_tensor.cuda().cpu().detach().numpy().copy()
    n_of_clusters = max(label_) + 1
    pred_ids, label_ids = {}, {}
    for vid, (pred_id, label_id) in enumerate(zip(pred_, label_)):
        if (pred_id in pred_ids):
            pred_ids[pred_id].append(vid)
        else:
            pred_ids[pred_id] = []
            pred_ids[pred_id].append(vid)
        if (label_id in label_ids):
            label_ids[label_id].append(vid)
        else:
            label_ids[label_id] = []
            label_ids[label_id].append(vid)

    pred_pairs, label_pairs = [set() for _ in range(n_of_clusters)
                               ], [set() for _ in range(n_of_clusters)]
    for pred_key, label_key in zip(pred_ids.keys(), label_ids.keys()):
        pred_pairs[pred_key] |= set(
            [pair for pair in itertools.combinations(pred_ids[pred_key], 2)])
        label_pairs[label_key] |= set(
            [pair for pair in itertools.combinations(label_ids[label_key], 2)])

    table = np.array(
        [[len(label_pair & pred_pair) for label_pair in label_pairs]
         for pred_pair in pred_pairs])

    G = nx.DiGraph()
    G.add_node('s', demand=-n_of_clusters)
    G.add_node('t', demand=n_of_clusters)
    for pred_id in range(n_of_clusters):
        G.add_edge('s', 'p_{}'.format(pred_id), weight=0, capacity=1)
    for source, weights in enumerate(table):
        for target, w in enumerate(weights):
            G.add_edge('p_{}'.format(source),
                       'l_{}'.format(target),
                       weight=-w,
                       capacity=1)
    for label_id in range(n_of_clusters):
        G.add_edge('l_{}'.format(label_id), 't', weight=0, capacity=1)

    clus_label_map = {}
    result = nx.min_cost_flow(G)
    for i, d in result.items():
        for j, f in d.items():
            if f and i[0] == 'p' and j[0] == 'l':
                clus_label_map[int(i[2])] = int(j[2])
    w = torch.FloatTensor(
        [[1 if j == clus_label_map[i] else 0 for j in range(n_of_clusters)]
         for i in range(n_of_clusters)]).cuda()
    return torch.mm(pred_tensor, w)
Exemple #2
0
def evaluate(g_model: cgan.Generator, d_model: cgan.Discriminator,
             metrics: dict, halves: torch.tensor, val_cond: torch.tensor,
             val_true: torch.tensor, val_obs: torch.tensor,
             params: utils.Params) -> dict:
    """Evaluate the metrics to specify when to save out the weights.
    
    Args:
        g_model (cgan.Generator): the Generator model
        d_model (cgan.Discriminator): the Discriminator model
        metrics (dict): the metrics to evaluate the model on
        halves (torch.tensor): tensor filled with the scalar value 0.5
        val_cond (torch.tensor): the conditional layer for the
            validation dataset
        val_true (torch.tensor): the ground truth true magnitudes for
            the validation dataset
        val_obs (torch.tensor): the ground truth observed magnitudes for
            the validation dataset
        params (utils.Params): the hyperparameters

    Returns:
        (dict): a dictionary of the mean of each metric.
    """
    g_model.eval()

    noise = Variable(torch.randn(val_cond.shape[0], params.z_dim))

    if params.cuda:
        noise = noise.cuda(non_blocking=True)
        val_true = val_true.cuda(non_blocking=True)
        val_cond = val_cond.cuda(non_blocking=True)
    
    g_out = g_model(noise, val_cond, val_true)
    d_out = d_model(g_out, val_cond, val_true).squeeze().cpu()

    metrics_mean = {"d_MSE": metrics["MSE"](d_out, halves),
                    "d_Var": metrics["VAR"](d_out),
                    "MSE": metrics["MSE"](g_out.cpu(), val_obs),
                    "main_metric": metrics["main"](
                        d_out, halves, val_cond.shape[0])}
    metrics_string = " ; ".join(
        f"{k}: {v:05.3f}" for k, v in metrics_mean.items())
    logging.info("- Eval metrics : " + metrics_string)

    return metrics_mean
Exemple #3
0
    def chamferDist(self, gt_points: torch.tensor,
                    source_points: torch.tensor):
        """computes the chamfer distance between 2 point clouds

        Arguments:
            gt_points {torch.tensor} -- [description]
            source_points {torch.tensor} -- [description]

        Returns:
            [type] -- [description]
        """
        gt_points = gt_points.cuda().detach()
        source_points = source_points.cuda().detach()
        d_gt2source, d_source2gt, idx3, idx4 = self.cham_loss(
            gt_points.unsqueeze(0), source_points.unsqueeze(0))
        # mean(squared_d(gt->source)) + mean(squared_d(source->gt))
        loss = (d_gt2source.mean() + d_source2gt.mean())  # /2 FIXME:
        self.running_loss += loss.cpu().item()
        self.n += 1
        return loss
 def train_discriminator(self, xb: torch.tensor):
     self.dis_optim.zero_grad()
     #passing real images into discriminator and finding loss of the model
     out_real = self.discriminator(xb.cuda().float())
     loss_real = self.loss(out_real,
                           torch.ones(out_real.shape[0], 1).cuda())
     #generate a fake image batch
     fake_img = self.generator(self.latent)
     self.latest = fake_img
     #passing fake image into discriminator and finding loss of the model
     out_fake = self.discriminator(fake_img)
     loss_fake = self.loss(out_fake,
                           torch.zeros(out_fake.shape[0], 1).cuda())
     #parameters update
     dis_loss = loss_fake + loss_real
     dis_loss.backward()
     #return loss of the model
     self.dis_optim.step()
     return dis_loss.item()
def conditional_to_cuda(x: torch.tensor,
                        non_blocking: bool = False) -> torch.tensor:
    #print(x.cuda.__doc__)
    #return x.cuda(non_blocking=non_blocking) if args.gpu_count > 0 else x
    return x.cuda() if args.gpu_count > 0 else x
        def similarity_2_graph(self, similarity: SparseSimilarity,
                               fg_prob: torch.tensor, min_fg_prob: float,
                               min_edge_weight: float,
                               normalize_graph_edges: bool) -> ig.Graph:
            """ Create the graph from the sparse similarity matrix """
            if not normalize_graph_edges:
                print(
                    "WARNING! You are going to create a graph without normalizing the edges by the sqrt of the node degree. \
                       Are you sure you know what you are doing?!")

            # Move operation on GPU is available. Only at the end move back to cpu
            if torch.cuda.is_available():
                fg_prob = fg_prob.cuda()
                sparse_matrix = similarity.sparse_matrix.cuda()
                similarity_index_matrix = similarity.index_matrix.cuda()
            else:
                sparse_matrix = similarity.sparse_matrix.cpu()
                similarity_index_matrix = similarity.index_matrix.cpu()

            assert sparse_matrix._nnz(
            ) > 0, "WARNING: Graph is empty. Nothing to do"

            # Map the location with small fg_prob to index = -1
            vertex_mask = fg_prob[0, 0] > min_fg_prob
            n_max = torch.max(similarity.index_matrix).item()
            transform_index = -1 * torch.ones(
                n_max + 1,
                dtype=torch.long,
                device=similarity_index_matrix.device)
            transform_index[similarity_index_matrix[
                vertex_mask]] = similarity_index_matrix[vertex_mask]

            # Do the remapping (old to medium)
            v_tmp = sparse_matrix._values()
            ij_tmp = transform_index[sparse_matrix._indices()]

            # Do the filtering
            my_filter = (v_tmp > min_edge_weight) * (ij_tmp[0, :] >=
                                                     0) * (ij_tmp[1, :] >= 0)
            v = v_tmp[my_filter]
            ij = ij_tmp[:, my_filter]

            # Shift the labels so that there are no gaps (medium to new)
            ij_present = (torch.bincount(ij.view(-1)) > 0)
            self.n_fg_pixel = ij_present.sum().item()
            medium_2_new = (torch.cumsum(ij_present, dim=-1) * ij_present) - 1
            ij_new = medium_2_new[ij]

            # Make a transformation of the index_matrix (old to new)
            transform_index.fill_(-1)
            transform_index[sparse_matrix._indices()[:, my_filter]] = ij_new
            self.index_matrix = transform_index[similarity_index_matrix]
            ni, nj = self.index_matrix.shape[-2:]

            i_matrix, j_matrix = torch.meshgrid([
                torch.arange(ni,
                             dtype=torch.long,
                             device=self.index_matrix.device),
                torch.arange(nj,
                             dtype=torch.long,
                             device=self.index_matrix.device)
            ])
            self.i_coordinate_fg_pixel = i_matrix[self.index_matrix >= 0]
            self.j_coordinate_fg_pixel = j_matrix[self.index_matrix >= 0]

            #            # Check
            #            tmp = -1 * torch.ones_like(self.index_matrix)
            #            tmp[self.i_coordinate_fg_pixel,
            #                self.j_coordinate_fg_pixel] = torch.arange(self.n_fg_pixel,
            #                                                           dtype=torch.long,
            #                                                           device=self.device)
            #            assert (tmp == self.index_matrix).all()

            # Normalize the edges if necessary
            if normalize_graph_edges:
                # Before normalization v ~ 1.
                # After normalization v ~ 1/#neighbors so that sum_i v_ij ~ 1
                m = torch.sparse.FloatTensor(
                    ij_new, v, torch.Size([self.n_fg_pixel, self.n_fg_pixel]))
                if m._nnz() > 0:
                    m_tmp = (torch.sparse.sum(m, dim=-1) +
                             torch.sparse.sum(m, dim=-2)).coalesce()
                    sqrt_sum_edges_at_vertex = torch.sqrt(m_tmp._values())
                    v.div_(sqrt_sum_edges_at_vertex[ij_new[0]] *
                           sqrt_sum_edges_at_vertex[ij_new[1]])
                else:
                    raise Exception("WARNING: Graph is empty. Nothing to do")

            print("Building the graph with python-igraph")
            return ig.Graph(vertex_attrs={
                "label":
                numpy.arange(self.n_fg_pixel, dtype=numpy.int64)
            },
                            edges=ij_new.permute(1, 0).cpu().numpy(),
                            edge_attrs={"weight": v.cpu().numpy()},
                            graph_attrs={
                                "total_edge_weight": v.sum().item(),
                                "total_nodes": self.n_fg_pixel
                            },
                            directed=False)
Exemple #7
0
    def evaluate(self,
                 gt_points: torch.tensor,
                 source_points: torch.tensor,
                 gt_normals=None):
        """computes the chamfer distance between 2 point clouds

        Arguments:
            gt_points {torch.tensor} -- [description]
            source_points {torch.tensor} -- [description]

        Returns:
            [dict] -- [description]
        """
        ##### Computing Chamfer Distances ######
        gt_points = gt_points.cuda().detach()
        source_points = source_points.cuda().detach()
        d_gt2source, d_source2gt, idx3, idx4 = self.cham_loss(
            gt_points.unsqueeze(0), source_points.unsqueeze(0))
        idx3 = idx3.long().squeeze()
        idx4 = idx4.long().squeeze()
        # mean(squared_d(gt->source)) + mean(squared_d(source->gt))
        chamfer_dist = (d_gt2source.mean() + d_source2gt.mean()) / 2
        chamfer_dist_abs = (d_gt2source.sqrt().mean() +
                            d_source2gt.sqrt().mean()) / 2
        out_dict = {}
        out_dict['chamfer_dist'] = chamfer_dist.cpu().item()
        self.eval_results['chamfer_dist'].append(out_dict['chamfer_dist'])
        out_dict['chamfer_dist_abs'] = chamfer_dist_abs.cpu().item()
        self.eval_results['chamfer_dist_abs'].append(
            out_dict['chamfer_dist_abs'])

        ############ PSNR ##############
        if gt_normals is not None:  # Computing PSNR if we have normals
            gt_normals = gt_normals.cuda().detach()
            d_plane_gt2source = torch.sum(
                (gt_points - source_points[idx3, :]) * gt_normals, dim=1)
            d_plane_source2gt = torch.sum(
                (source_points - gt_points[idx4, :]) * gt_normals[idx4, :],
                dim=1)
            chamfer_plane = (d_plane_gt2source.abs().mean() +
                             d_plane_source2gt.abs().mean()) / 2
            out_dict['chamfer_dist_plane'] = chamfer_plane.cpu().item()
            self.eval_results['chamfer_dist_plane'].append(
                out_dict['chamfer_dist_plane'])

        ###### IOU #######
        gt_points_np = gt_points.cpu().numpy()
        source_points_np = source_points.cpu().numpy()

        # print('gt_points shape',g)
        center = (np.max(gt_points_np, axis=0, keepdims=True) +
                  np.min(gt_points_np, axis=0, keepdims=True)) / 2
        resolution = np.array(
            [self.config['evaluation']['iou_grid']['resolution']])
        size_meter = np.array([self.config['grid']['size']])
        gt_grid = occupancy_grid.OccupancyGrid(center=center,
                                               resolution=resolution,
                                               size_meter=size_meter)
        gt_grid.addPoints(gt_points_np)
        source_grid = occupancy_grid.OccupancyGrid(center=center,
                                                   resolution=resolution,
                                                   size_meter=size_meter)
        source_grid.addPoints(source_points_np)

        out_dict['iou'] = occupancy_grid.gridIOU(gt_grid.grid,
                                                 source_grid.grid)
        self.eval_results['iou'].append(out_dict['iou'])

        return out_dict
Exemple #8
0
def tensor_to_cuda(tensor: torch.tensor):
    return tensor.cuda() if torch.cuda.is_available() else tensor