pyg-team / pytorch_geometric

Graph Neural Network Library for PyTorch
https://pyg.org
MIT License
21.18k stars 3.64k forks source link

Trouble to use Tensorboard's add_graph with my network #1095

Open evakrowarska opened 4 years ago

evakrowarska commented 4 years ago

❓ Questions & Help

I am using code built upon this code example. Now I would like to add Tensorboard functionality.

Unfortunately, I am not able to get it work. I tried to adapt the insights from this tensorboard example provided at PyTorch Geometric's repository.

Since the network expects a batch in the forward pass, I tried to use tensorboard.add_graph like this:


model = model.to(device)
for data in train_loader:
    data = data.to(device)
    model(data)
    break

writer.add_graph(model, data)

But then I get the following error message:

Type 'Tuple[Tuple[str, Tensor], Tuple[str, Tensor], Tuple[str, Tensor], Tuple[str, Tensor], Tuple[str, Tensor], Tuple[str, Tensor], Tuple[str, Tensor]]' cannot be traced. Only Tensors and (possibly nested) Lists, Dicts, and Tuples of Tensors can be traced (toTraceableStack at /opt/conda/conda-bld/pytorch_1579022030672/work/torch/csrc/jit/pybind_utils.h:305)

But the data I pass as a parameter to add_graph, next to the model should be some object, that can be forwarded through the network, shouldn't it?

According to the tensorboard example I tried next:

model = model.to(device)
for data in train_loader:
    data = data.to(device)
    model(data)
    break

writer.add_graph(model, [data.x, data.edge_index])

But I get the following error message: TypeError: forward() takes 2 positional arguments but 3 were given

I really would like to now, how I can add my model to Tensorboard, since I would like to see, how the layers train and be able to do better debugging of my network.

Thank you in advance.

rusty1s commented 4 years ago

Yes, this is a PyTorch jit limitation, since it cannot handle custom objects as arguments. You need to modify the forward call of model to: def forward(self, x, edge_index).

evakrowarska commented 4 years ago

Thanks for that answer.

What if I have different networks, while some require more parameters than others? Especially, I have networks, that get more information inside the forward that pos, edge_index and batch.

Do I have to make case distinctions inside test and train function for the forward pass, which network is used at the moment?

Or is there a more elegant way?

rusty1s commented 4 years ago

I am not sure I understand. As long as you input tensors to the forward pass, anything should be fine.

douglasrizzo commented 4 years ago

Yes, this is a PyTorch jit limitation, since it cannot handle custom objects as arguments. You need to modify the forward call of model to: def forward(self, x, edge_index).

@rusty1s how does this impact the use of the model when using batches? I usually have a model that receives a Data object, but it also works with a Batch object. If I change the call to forward to receive x and edge_index, will it still accept a Batch object?

FarzanT commented 3 years ago

How should the model be changed when it receives both graph and non-graph inputs? E.g. right now I have:

    def forward(self, *inputs):

And I know that the first element of inputs contains my graph. How should I dissect that particular graph object to x and edge_index? The length of inputs is arbitrary.

rusty1s commented 3 years ago

Tracing does not support arguments of arbitrary size. You should find the union set of arguments and pass them as optional parameters:

def forward(self, edge_index: Tensor, x: Optional[Tensor] = None, batch: Optional[Tensor] = None, ...):
    ...
mhorlacher commented 2 years ago

Any solutions on this? Facing the same problem.

rusty1s commented 2 years ago

What's the problem when inputting tensors rather than data objects into model.forward?

KiriKoppelgaard commented 2 years ago

My forward function looks like this:

    def forward(self, x: Optional = None, lengths: Optional = None):
        lengths = lengths.cpu().int()
        output_lengths = self.get_seq_lens(lengths)
        x, _ = self.conv(x, output_lengths)

        sizes = x.size()
        x = x.view(sizes[0], sizes[1] * sizes[2], sizes[3])  # Collapse feature dimension
        x = x.transpose(1, 2).transpose(0, 1).contiguous()  # TxNxH

        for rnn in self.rnns:
            x = rnn(x, output_lengths)

        if not self.bidirectional:  # no need for lookahead layer in bidirectional
            x = self.lookahead(x)

        x = self.fc(x)
        x = x.transpose(0, 1)
        # identity in training mode, softmax in eval mode
        x = self.inference_softmax(x)
        return x, output_lengths

and I try to add a graph to TensorBoard like this:

    if logging_process:
        x, targets, input_percentages, target_sizes, file = [i for i in train_batch_loader][0]
        lengths = input_percentages.mul_(int(x.size(3))).int()
        tensorboard_logger.add_graph(model, [x, lengths])

However, I still get the error: TypeError: TensorBoardLogger.add_graph() takes 2 positional arguments but 3 were given

Any clue why?

rusty1s commented 2 years ago

How is tensorboard_logger defined? It doesn't seem to be a torch.utils.tensorboard.SummaryWriter.