def graph_conv_cheby(self, x, cl, L, lmax, Fout, K): # parameters # B = batch size # V = nb vertices # Fin = nb input features # Fout = nb output features # K = Chebyshev order & support size B, V, Fin = x.size() B, V, Fin = int(B), int(V), int(Fin) # rescale Laplacian lmax = lmax_L(L) L = rescale_L(L, lmax) # convert scipy sparse matric L to pytorch L = L.tocoo() indices = np.column_stack((L.row, L.col)).T indices = indices.astype(np.int64) indices = torch.from_numpy(indices) indices = indices.type(torch.LongTensor) L_data = L.data.astype(np.float32) L_data = torch.from_numpy(L_data) L_data = L_data.type(torch.FloatTensor) L = torch.sparse.FloatTensor(indices, L_data, torch.Size(L.shape)) L = Variable(L, requires_grad=False) if torch.cuda.is_available(): L = L.cuda() # transform to Chebyshev basis x0 = x.permute(1, 2, 0).contiguous() # V x Fin x B x0 = x0.view([V, Fin * B]) # V x Fin*B x = x0.unsqueeze(0) # 1 x V x Fin*B def concat(x, x_): x_ = x_.unsqueeze(0) # 1 x V x Fin*B return torch.cat((x, x_), 0) # K x V x Fin*B if K > 1: x1 = my_sparse_mm()(L, x0) # V x Fin*B x = torch.cat((x, x1.unsqueeze(0)), 0) # 2 x V x Fin*B for k in range(2, K): x2 = 2 * my_sparse_mm()(L, x1) - x0 x = torch.cat((x, x2.unsqueeze(0)), 0) # M x Fin*B x0, x1 = x1, x2 x = x.view([K, V, Fin, B]) # K x V x Fin x B x = x.permute(3, 1, 2, 0).contiguous() # B x V x Fin x K x = x.view([B * V, Fin * K]) # B*V x Fin*K # Compose linearly Fin features to get Fout features x = cl(x) # B*V x Fout x = x.view([B, V, Fout]) # B x V x Fout return x
def graph_conv_cheby(self, x, cl, L, Fout, K): # parameters # B = batch size # V = nb vertices # Fin = nb input features # Fout = nb output features # K = Chebyshev order & support size B, V, Fin = x.size() B, V, Fin = int(B), int(V), int(Fin) # rescale Laplacian lmax = lmax_L(L) L = rescale_L(L, lmax) # convert scipy sparse matric L to pytorch L = sparse_mx_to_torch_sparse_tensor(L) if torch.cuda.is_available(): L = L.cuda() # transform to Chebyshev basis x0 = x.permute(1, 2, 0).contiguous() # V x Fin x B x0 = x0.view([V, Fin * B]) # V x Fin*B x = x0.unsqueeze(0) # 1 x V x Fin*B def concat(x, x_): x_ = x_.unsqueeze(0) # 1 x V x Fin*B return torch.cat((x, x_), 0) # K x V x Fin*B if K > 1: x1 = my_sparse_mm()(L, x0) # V x Fin*B x = torch.cat((x, x1.unsqueeze(0)), 0) # 2 x V x Fin*B for k in range(2, K): x2 = 2 * my_sparse_mm()(L, x1) - x0 x = torch.cat((x, x2.unsqueeze(0)), 0) # M x Fin*B --> K x V x Fin*B x0, x1 = x1, x2 x = x.view([K, V, Fin, B]) # K x V x Fin x B x = x.permute(3, 1, 2, 0).contiguous() # B x V x Fin x K x = x.view([B * V, Fin * K]) # B*V x Fin*K # Compose linearly Fin features to get Fout features x = cl(x) # B*V x Fout x = x.view([B, V, Fout]) # B x V x Fout return x
def prepare(self): # split train and test self.training_events = self.dataset[:self.n_training_events] self.test_events = self.dataset[self.n_training_events:] # set up model self.model = Graph_ConvNet(self.options) self.grid_side = self.options['grid_side'] self.number_edges = self.options['number_edges'] self.metric = self.options['metric'] # create graph of Euclidean grid self.Grid = grid_graph(self.grid_side, self.number_edges, self.metric) # Compute coarsened graphs self.L, self.perm = coarsen(self.Grid, self.options['coarsening']) lmax = [] for i in range(self.options['coarsening']): lmax.append(lmax_L(self.L[i])) self.options['D'] = max(perm) + 1 self.options['FC1Fin'] = self.options['CL2_F'] * \ (self.options['D'] // 16)
def build_coarse_graphs(mesh_face, joint_num, skeleton, flip_pairs, levels=9): joint_adj = build_adj(joint_num, skeleton, flip_pairs) # Build graph mesh_adj = build_graph(mesh_face, mesh_face.max() + 1) graph_Adj, graph_L, graph_perm = coarsen(mesh_adj, levels=levels) input_Adj = sp.csr_matrix(joint_adj) input_Adj.eliminate_zeros() input_L = laplacian(input_Adj, normalized=True) graph_L[-1] = input_L graph_Adj[-1] = input_Adj # Compute max eigenvalue of graph Laplacians, rescale Laplacian graph_lmax = [] renewed_lmax = [] for i in range(levels): graph_lmax.append(lmax_L(graph_L[i])) graph_L[i] = rescale_L(graph_L[i], graph_lmax[i]) # renewed_lmax.append(lmax_L(graph_L[i])) return graph_Adj, graph_L, graph_perm, perm_index_reverse(graph_perm[0])
t_start = time.time() grid_side = 28 number_edges = 4 metric = 'euclidean' A = grid_graph(grid_side, number_edges, metric) # create graph of Euclidean grid # Compute coarsened graphs coarsening_levels = 4 L, perm = coarsen(A, coarsening_levels) # Compute max eigenvalue of graph Laplacians lmax = [] for i in range(coarsening_levels): lmax.append(lmax_L(L[i])) print('lmax: ' + str([lmax[i] for i in range(coarsening_levels)])) # Reindex nodes to satisfy a binary tree structure train_data = perm_data(train_data, perm) val_data = perm_data(val_data, perm) test_data = perm_data(test_data, perm) print(train_data.shape) print(val_data.shape) print(test_data.shape) print('Execution time: {:.2f}s'.format(time.time() - t_start)) del perm