import torch from torch_geometric.utils import degree, to_undirected from pGRACE.utils import compute_pr, eigenvector_centrality_mia,eigenvector_centrality def drop_feature(x, drop_prob): drop_mask = torch.empty((x.size(1),), dtype=torch.float32, device=x.device).uniform_(0, 1) < drop_prob x = x.clone() x[:, drop_mask] = 0 return x def drop_feature_weighted(x, w, p: float, threshold: float = 0.7): w = w / w.mean() * p w = w.where(w < threshold, torch.ones_like(w) * threshold) drop_prob = w.repeat(x.size(0)).view(x.size(0), -1) drop_mask = torch.bernoulli(drop_prob).to(torch.bool) x = x.clone() x[drop_mask] = 0. return x def drop_feature_weighted_2(x, w, p: float, threshold: float = 0.7): w = w / w.mean() * p w = w.where(w < threshold, torch.ones_like(w) * threshold) drop_prob = w drop_mask = torch.bernoulli(drop_prob).to(torch.bool) x = x.clone() x[:, drop_mask] = 0. return x def feature_drop_weights(x, node_c): x = x.to(torch.bool).to(torch.float32) w = x.t() @ node_c w = w.log() s = (w.max() - w) / (w.max() - w.mean()) return s def feature_drop_weights_dense(x, node_c): x = x.abs() w = x.t() @ node_c w = w.log() s = (w.max() - w) / (w.max() - w.mean()) return s def drop_edge_weighted(edge_index, edge_weights, p: float, threshold: float = 1.): edge_weights = edge_weights / edge_weights.mean() * p edge_weights = edge_weights.where(edge_weights < threshold, torch.ones_like(edge_weights) * threshold) sel_mask = torch.bernoulli(1. - edge_weights).to(torch.bool) return edge_index[:, sel_mask] def degree_drop_weights(edge_index): edge_index_ = to_undirected(edge_index) deg = degree(edge_index_[1]) deg_col = deg[edge_index[1]].to(torch.float32) s_col = torch.log(deg_col) weights = (s_col.max() - s_col) / (s_col.max() - s_col.mean()) return weights def pr_drop_weights(edge_index, aggr: str = 'sink', k: int = 10): pv = compute_pr(edge_index, k=k) pv_row = pv[edge_index[0]].to(torch.float32) pv_col = pv[edge_index[1]].to(torch.float32) s_row = torch.log(pv_row) s_col = torch.log(pv_col) if aggr == 'sink': s = s_col elif aggr == 'source': s = s_row elif aggr == 'mean': s = (s_col + s_row) * 0.5 else: s = s_col weights = (s.max() - s) / (s.max() - s.mean()) return weights def evc_drop_weights(data): evc = eigenvector_centrality(data) evc = evc.where(evc > 0, torch.zeros_like(evc)) evc = evc + 1e-8 s = evc.log() edge_index = data.edge_index s_row, s_col = s[edge_index[0]], s[edge_index[1]] s = s_col return (s.max() - s) / (s.max() - s.mean()) def evc_drop_weights_mia(g_train0,edges_train_index,x,num_nodes): evc = eigenvector_centrality_mia(g_train0,edges_train_index,x,num_nodes) evc = evc.where(evc > 0, torch.zeros_like(evc)) evc = evc + 1e-8 s = evc.log() edge_index = edges_train_index s_row, s_col = s[edge_index[0]], s[edge_index[1]] s = s_col return (s.max() - s) / (s.max() - s.mean())