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 ### 928*1*100 x0 = x0.view([V, Fin * B]) # V x Fin*B ### 928*100 x = x0.unsqueeze(0) # 1 x V x Fin*B ### 1*928*100 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 ### 928*100 x = torch.cat((x, x1.unsqueeze(0)), 0) # 2 x V x Fin*B ### 2*928*100 for k in range(2, K): x2 = 2 * my_sparse_mm()(L, x1) - x0 ### 928*100 x = torch.cat((x, x2.unsqueeze(0)), 0) # M x Fin*B ### 3*928*100 x0, x1 = x1, x2 x = x.view([K, V, Fin, B]) # K x V x Fin x B ### 25*928*1*100 x = x.permute(3, 1, 2, 0).contiguous() # B x V x Fin x K ### 100*928*1*25 x = x.view([B * V, Fin * K]) # B*V x Fin*K ### 92800*25 # Compose linearly Fin features to get Fout features x = cl(x) # B*V x Fout ### 92800*32 x = x.view([B, V, Fout]) # B x V x Fout ### 100*928*32 return x
def graph_conv_cheby(self, x, cl, L, lmax, Fout, K): # parameters # B = batch size # V = number of vertices # Fin = number of input features # Fout = number of 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 matrix 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 = L.requires_grad_(False).to(args.device) # 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 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 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])