Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating different explanations' subgraphs from the same trained model by using PyG GNNExplainer #26

Open
BILLYLIAOWEI opened this issue Jan 21, 2021 · 1 comment

Comments

@BILLYLIAOWEI
Copy link

Hi
I'm using GCN to classify the node on datasets "KarateClub", then I using GNNExplainer to explain node 12. However, when I explain the node twice, GNNExplainer gives me two different subgraph, and them have different node_feat_mask&edge_mask.
I‘m so confused about the different explanations generated from the same trained model.

run code on jupyter notebook
cell one:
`
import torch
from torch_geometric.datasets import KarateClub
import torch.nn.functional as F
from torch_geometric.nn import GCNConv, GNNExplainer
from torch_geometric.datasets import KarateClub
import networkx as nx
import matplotlib.pyplot as plt

dataset = KarateClub()#torch_geometric.datasets

class Net(torch.nn.Module):
def init(self):
super().init()
self.conv1 = GCNConv(dataset.num_node_features, 16)
self.conv2 = GCNConv(16, dataset.num_classes)
pass

def forward(self, x, edge_index):
#x, edge_index = data.x, data.edge_index

x = self.conv1(x, edge_index)
x = F.relu(x)
x = F.dropout(x, training=self.training)
x = self.conv2(x, edge_index)

return F.log_softmax(x, dim=1)

pass
pass

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net().to(device)
data = dataset[0].to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
x, edge_index = data.x, data.edge_index

for epoch in range(61):
model.train()
optimizer.zero_grad()
out = model(x, edge_index)
loss = F.nll_loss(out, data.y)
loss.backward()
optimizer.step()

#print('Epoch {} | Loss: {:.4f}'.format(epoch,loss.item()))
model.eval()
_, pred=out.max(dim=1)
#print(pred)
correct = int(pred.eq(data.y).sum().item())
acc = correct / int(data.x.sum())
#print('Accuracy:{:.4f}'.format(acc))
print('Epoch {} | Loss: {:.4f}'.format(epoch,loss.item())+' | Accuracy:{:.4f}'.format(acc))

pass
pass
`

cell two:
explainer = GNNExplainer(model, epochs=60) node_idx = 12 node_feat_mask, edge_mask = explainer.explain_node(node_idx, x, edge_index) ax, G = explainer.visualize_subgraph(node_idx, edge_index, edge_mask, y=data.y) plt.show()

cell three:
explainer = GNNExplainer(model, epochs=61) node_idx = 12 node_feat_mask, edge_mask = explainer.explain_node(node_idx, x, edge_index) ax, G = explainer.visualize_subgraph(node_idx, edge_index, edge_mask, y=data.y,threshold=0.6) plt.show()

@HosseinMousavi
Copy link

Hi I'm using GCN to classify the node on datasets "KarateClub", then I using GNNExplainer to explain node 12. However, when I explain the node twice, GNNExplainer gives me two different subgraph, and them have different node_feat_mask&edge_mask. I‘m so confused about the different explanations generated from the same trained model.

run code on jupyter notebook cell one: ` import torch from torch_geometric.datasets import KarateClub import torch.nn.functional as F from torch_geometric.nn import GCNConv, GNNExplainer from torch_geometric.datasets import KarateClub import networkx as nx import matplotlib.pyplot as plt

dataset = KarateClub()#torch_geometric.datasets

class Net(torch.nn.Module): def init(self): super().init() self.conv1 = GCNConv(dataset.num_node_features, 16) self.conv2 = GCNConv(16, dataset.num_classes) pass

def forward(self, x, edge_index): #x, edge_index = data.x, data.edge_index

x = self.conv1(x, edge_index)
x = F.relu(x)
x = F.dropout(x, training=self.training)
x = self.conv2(x, edge_index)

return F.log_softmax(x, dim=1)

pass pass

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = Net().to(device) data = dataset[0].to(device) optimizer = torch.optim.Adam(model.parameters(), lr=0.01) x, edge_index = data.x, data.edge_index

for epoch in range(61): model.train() optimizer.zero_grad() out = model(x, edge_index) loss = F.nll_loss(out, data.y) loss.backward() optimizer.step()

#print('Epoch {} | Loss: {:.4f}'.format(epoch,loss.item())) model.eval() _, pred=out.max(dim=1) #print(pred) correct = int(pred.eq(data.y).sum().item()) acc = correct / int(data.x.sum()) #print('Accuracy:{:.4f}'.format(acc)) print('Epoch {} | Loss: {:.4f}'.format(epoch,loss.item())+' | Accuracy:{:.4f}'.format(acc))

pass pass `

cell two: explainer = GNNExplainer(model, epochs=60) node_idx = 12 node_feat_mask, edge_mask = explainer.explain_node(node_idx, x, edge_index) ax, G = explainer.visualize_subgraph(node_idx, edge_index, edge_mask, y=data.y) plt.show()

cell three: explainer = GNNExplainer(model, epochs=61) node_idx = 12 node_feat_mask, edge_mask = explainer.explain_node(node_idx, x, edge_index) ax, G = explainer.visualize_subgraph(node_idx, edge_index, edge_mask, y=data.y,threshold=0.6) plt.show()

Hello BILLYLIAOWEI,
Could you able to run the code and get the result? I want to use PyG and GNNExplainer as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants