pyg-team/pytorch_geometric

How can get the adjacent matrix that only cantain k-hop neighbors?

Closed this issue · 12 comments

From now on, we recommend using our discussion forum (https://github.com/rusty1s/pytorch_geometric/discussions) for general questions.

❓ Questions & Help

Thank you for your work!
Please, I want to know hot to get the adjacent matrix that only cantain k-hop neighbors?
For example, cora dataset, the edge_index is the complete adjacent matrix. If I want to get the adjacent matrix, which is only contain 2-hop neighbors but not contain 1-hop and x-hop x>2, how can I do?
I m looking forward to your answer! Thank you!

If it is applicable, you could use dense adjacency matrices to achieve that:

adj = torch.zeros(N, N, dtype=torch.long)
adj[edge_index[0], edge_index[1]] = 1

new_adj = (adj @ adj)
new_adj = ((new_adj > 0).to(torch.long) + adj) == 1

If it is applicable, you could use dense adjacency matrices to achieve that:

adj = torch.zeros(N, N, dtype=torch.long)
adj[edge_index[0], edge_index[1]] = 1

new_adj = (adj @ adj)
new_adj = ((new_adj > 0).to(torch.long) + adj) == 1

Thank you for your answer!
Is any sparse approach?

You could use np.isin to filter out the edges that appear in both adj and adj @ adj. That should work for sparse adjacencies.

You could use np.isin to filter out the edges that appear in both adj and adj @ adj. That should work for sparse adjacencies.

I'm sorry for my slowness. Could you be more specific?

Sure. It might look like the following code (note that I didn't test it):

edge_index = ...
edge_index2 = spspmm(...)

idx = edge_index[0] * num_nodes + edge_index[1]
idx2 = edge_index2[0] * num_nodes + edge_index2[1]

mask = torch.from_numpy(np.isin(idx2.numpy(), idx.numpy()))
mask = ~mask  # Invert mask to only contain the elements not in `idx`

edge_index2 = edge_index2[:, mask]

Sure. It might look like the following code (note that I didn't test it):

edge_index = ...
edge_index2 = spspmm(...)

idx = edge_index[0] * num_nodes + edge_index[1]
idx2 = edge_index2[0] * num_nodes + edge_index2[1]

mask = torch.from_numpy(np.isin(idx2.numpy(), idx.numpy()))
mask = ~mask  # Invert mask to only contain the elements not in `idx`

edge_index2 = edge_index2[:, mask]

I m sorry that there is a problem.
All computation is finished on cuda. So it seems that converting to numpy is not feasible.
:)Do you have any approches implement it on cuda?

The goal of obtain the k-hop edge_index is to make messege passing only in k-hop neighbor.
For example, I only want implement GraphConv layers on 2-hop neighbor but no 1-hop and other k-hop neighbor.
Do you have other mrthods? Thank you!

As far as I know, there is no isin functionality implemented in PyTorch, but you can transfer your tensors to CPU first before calling numpy().

Yes, I didn't do it because transfer to CPU and transfer to GPU can cause problem of speed.
Is there any approaches that can make messege passing only in k-hop neighbor but no other neighbor?
Thank you!

I don't know of any. I also do not think that speed is a deciding factor, as you can usually simply pre-process the 2-hop graph, and therefore only have to do it once.

U 're right. I have to implement it first.
Thanks again for your reply from the other side of the ocean

Hi, I check the code and write it as follow:

x, edge_index = data.x, data.edge_index
        
N = x.size(0)

row, col = edge_index
edge_index2 = torch_sparse.spspmm(edge_index, torch.ones([col.size(0)], device='cuda'), 
                                    edge_index, torch.ones([col.size(0)], device='cuda'), 
                                    N, N, N)

idx = edge_index[0] * N + edge_index[1]
idx2 = edge_index2[0] * N + edge_index2[1]

mask = torch.from_numpy(np.isin(idx2.cpu().numpy(), idx.cpu().numpy()))
mask = ~mask  # Invert mask to only contain the elements not in `idx`

edge_index2 = edge_index2[:, mask]

But it reported the error:

  File "k-hop.py", line 53, in <module>
    edge_index2 = edge_index2[:, mask]
TypeError: tuple indices must be integers or slices, not tuple

How can I fix this error? Thank you!

Hi, I check the code and write it as follow:

x, edge_index = data.x, data.edge_index
        
N = x.size(0)

row, col = edge_index
edge_index2 = torch_sparse.spspmm(edge_index, torch.ones([col.size(0)], device='cuda'), 
                                    edge_index, torch.ones([col.size(0)], device='cuda'), 
                                    N, N, N)

idx = edge_index[0] * N + edge_index[1]
idx2 = edge_index2[0] * N + edge_index2[1]

mask = torch.from_numpy(np.isin(idx2.cpu().numpy(), idx.cpu().numpy()))
mask = ~mask  # Invert mask to only contain the elements not in `idx`

edge_index2 = edge_index2[:, mask]

But it reported the error:

  File "k-hop.py", line 53, in <module>
    edge_index2 = edge_index2[:, mask]
TypeError: tuple indices must be integers or slices, not tuple

How can I fix this error? Thank you!

I found it just need to add an _ in spspmm and fix this error.
And how can I check it and insure it dose get k-hop neighbor?