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)
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
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)
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
def tensor_to_cuda(tensor: torch.tensor): return tensor.cuda() if torch.cuda.is_available() else tensor