The model output result is incorrect after exporting the code that called the torch_geometric package as onnx mode #9011
Unanswered
SpadgerBoy
asked this question in
Q&A
Replies: 1 comment
-
This works for me from typing import Callable, Union
import numpy as np
import onnxruntime as ort
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.onnx as onnx
# from models.common import MultiLayerPerceptron
from torch import Tensor
from torch_sparse import SparseTensor, matmul
from torch_geometric.nn import MLP, MessagePassing
from torch_geometric.typing import Adj, OptPairTensor, OptTensor, Size
class GINConv(MessagePassing):
def __init__(self, nn: Callable, eps: float = 0., train_eps: bool = False,
activation="softplus", **kwargs):
super(GINConv, self).__init__(aggr='add', **kwargs)
self.nn = nn # MLP
self.initial_eps = eps
if isinstance(activation, str):
self.activation = getattr(F, activation)
else:
self.activation = None
if train_eps:
self.eps = torch.nn.Parameter(torch.Tensor([eps]))
else:
self.register_buffer('eps', torch.Tensor([eps]))
def forward(self, x: Union[Tensor, OptPairTensor], edge_index: Adj,
edge_attr: OptTensor = None, size: Size = None) -> Tensor:
if isinstance(x, Tensor):
x: OptPairTensor = (x, x)
'''if isinstance(edge_index, Tensor):
assert edge_attr is not None
print(x[0].size(-1), edge_attr.size(-1))
assert x[0].size(-1) == edge_attr.size(-1)
elif isinstance(edge_index, SparseTensor):
assert x[0].size(-1) == edge_index.size(-1)
'''
out = self.propagate(edge_index, x=x, edge_attr=edge_attr, size=size)
x_r = x[1]
if x_r is not None:
out = out + (1 + self.eps) * x_r
return self.nn(out)
def message(self, x_j: Tensor, edge_attr: Tensor) -> Tensor:
return self.activation(x_j + edge_attr)
def __repr__(self):
return '{}(nn={})'.format(self.__class__.__name__, self.nn)
def code_run(conv_input, edge_index, edge_attr):
gin = GINConv(MLP([5, 5]))
output = gin(conv_input, edge_index, edge_attr)
print(output[:5, :5])
gin.eval()
torch.onnx.export(
gin,
(conv_input, edge_index, edge_attr),
"gin.onnx",
opset_version=16,
input_names=["conv_input", "edge_index", "edge_attr"],
output_names=["output"],
)
def onnx_run(conv_input, edge_index, edge_attr):
model_path = "gin.onnx"
providers = ['CPUExecutionProvider']
sess = ort.InferenceSession(model_path, providers=providers)
input_dict = {
"conv_input": conv_input,
"edge_index": edge_index,
"edge_attr": edge_attr
}
output = sess.run(None, input_dict)
print(output)
if __name__ == '__main__':
conv_input = torch.randn(4, 5)
edge_index = torch.tensor([[0, 1, 1, 2, 2, 3], [1, 0, 2, 1, 3, 2]])
edge_attr = torch.randn(6, 5)
code_run(conv_input, edge_index, edge_attr)
conv_input0 = conv_input.numpy()
edge_index0 = edge_index.numpy()
edge_attr0 = edge_attr.numpy()
onnx_run(conv_input0, edge_index0, edge_attr0) Can you try to set |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
In my model, I used the torch_geometric package. After exporting the model as onnx, the result of the onnx model is inconsistent with the source code, as explicitly stated in the above code. I don’t know which operator is causing the problem, I hope to get everyone’s guidance.
Beta Was this translation helpful? Give feedback.
All reactions