question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is there any way to convert an pytorch Tensor adjacency matrix into a pytorch_geometric Data object while allowing backprop?

See original GitHub issue

Is there a way to convert an adjacency tensor produced by a MLP into a Data object while allowing backprop for a generative adversarial network? The generative adversarial network has an MLP generator with a pytorch_geometric based GNN as the discriminator I have not been able to find the answer to this question yet. Here is a simplified example of what the problem is.

Say I have this MLP generator:

class Generator(nn.Module):
    def __init__(self):  
        super().__init__()
        self.fc1 = nn.Linear(3, 6)
    def forward(self, z):
        return torch.tanh(self.fc1(z))

output = gen(torch.randn(3))
# output = tensor([ 0.2085, -0.0576,  0.4957, -0.6059,  0.2571, -0.2866], grad_fn=<TanhBackward>)

So, this generator returns a vector representing a graph with two nodes, which we can reshape to form an adjacency matrix and a node feature vector.

adj = output[:4].view(2,2)
# adj = tensor([[-0.5811,  0.0070],
                        [ 0.3754, -0.2587]], grad_fn=<ViewBackward>)

node_features  = output[4:].view(2, 1)
# node_features = tensor([[0.1591],
                                         [0.0821]], grad_fn=<ViewBackward>)

Now to convert this to a pytorch_geometric Data object, we must construct a COO matrix (the x parameter in the Data object is already the node_features). However, if we loop through the adj matrix and add a connection to a COO matrix with the code below, back propagation does not work from the pytorch_geometric GNN to the pytorch MLP.

coo = [[], []]
for i in len(adj):
    for j in len(adj[i]):
         # for our purposes, say there is an edge if the value >0
         if adj[i][j] >0:
             coo[0].append(i)
             coo[1].append(j)

We can now construct the Data object like so:

d = Data(x = node_features, edge_index = torch.LongTensor(coo))

However, when training a GAN by converting the generator output to a Data object for the GNN discriminator, back propagation and optimization does not work (I assume because the grad_fn and grad properties are lost. Does anyone know how to convert a tensor to a pytorch_geometric Data object while allowing back prop to happen in the generative adversarial network with MLP generator that outputs adj matrix/tensor and node features and GNN (pytorch_geometric based) discriminator that takes a Data object as input?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

7reactions
rusty1scommented, Aug 7, 2020

It is correct that you lose gradients that way. In order to backpropagate through sparse matrices, you need to compute both edge_index and edge_weight (the first one holding the COO index and the second one holding the value for each edge). This way, gradients flow from edge_weight to your dense adjacency matrix.

In code, this would look as following:

edge_index = (adj > 0).nonzero().t()
row, col = edge_index
edge_weight = adj[row, col]
self.conv(x, edge_index, edge_weight)
1reaction
smoradcommented, May 27, 2021

@vctorwei you may want to look at https://github.com/rusty1s/pytorch_geometric/issues/2543

I’m planning on upstreaming this after a paper deadline in ~3 weeks.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there any way to convert an pytorch Tensor adjacency ...
So, this generator returns a vector representing a graph with two nodes, which we can reshape to form an adjacency matrix and a...
Read more >
torch_geometric.utils.convert - PyTorch Geometric
from collections import defaultdict from typing import Any, Iterable, List, Optional, Tuple, Union import scipy.sparse import torch from torch import Tensor ...
Read more >
torch_geometric.nn — pytorch_geometric documentation
Takes in the output of aggregation as first argument and any argument which was ... The adjacency matrix can include other values than...
Read more >
torch_geometric.transforms - PyTorch Geometric
Performs tensor device conversion, either for all attributes of the Data object or only the ones given by attrs (functional name: to_device )....
Read more >
torch_geometric.utils — pytorch_geometric documentation
Converts batched sparse adjacency matrices given by edge indices and edge attributes to a single dense batched adjacency matrix.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found