"tests/python/common/data/test_data.py" did not exist on "e234fcfa8f89a902b15e4a5f2d3e41cd9f20b95a"
Unverified Commit 117dd252 authored by Quan (Andy) Gan's avatar Quan (Andy) Gan Committed by GitHub
Browse files

[Doc] Fix inconsistencies and GPU code (#2642)

* fix inconsistencies and GPu

* bug fixes

* fix

* trigger new tutorials
parent 8ccb8206
...@@ -182,7 +182,7 @@ optimizer = torch.optim.Adam(model.parameters(), lr=0.01) ...@@ -182,7 +182,7 @@ optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
for epoch in range(20): for epoch in range(20):
for batched_graph, labels in train_dataloader: for batched_graph, labels in train_dataloader:
pred = model(batched_graph, batched_graph.ndata['attr']) pred = model(batched_graph, batched_graph.ndata['attr'].float())
loss = F.cross_entropy(pred, labels) loss = F.cross_entropy(pred, labels)
optimizer.zero_grad() optimizer.zero_grad()
loss.backward() loss.backward()
...@@ -191,7 +191,7 @@ for epoch in range(20): ...@@ -191,7 +191,7 @@ for epoch in range(20):
num_correct = 0 num_correct = 0
num_tests = 0 num_tests = 0
for batched_graph, labels in test_dataloader: for batched_graph, labels in test_dataloader:
pred = model(batched_graph, batched_graph.ndata['attr']) pred = model(batched_graph, batched_graph.ndata['attr'].float())
num_correct += (pred.argmax(1) == labels).sum().item() num_correct += (pred.argmax(1) == labels).sum().item()
num_tests += len(labels) num_tests += len(labels)
......
...@@ -3,9 +3,9 @@ Training GNN with Neighbor Sampling for Node Classification ...@@ -3,9 +3,9 @@ Training GNN with Neighbor Sampling for Node Classification
=========================================================== ===========================================================
This tutorial shows how to train a multi-layer GraphSAGE for node This tutorial shows how to train a multi-layer GraphSAGE for node
classification on Amazon Co-purchase Network provided by `Open Graph classification on ``ogbn-arxiv`` provided by `Open Graph
Benchmark (OGB) <https://ogb.stanford.edu/>`__. The dataset contains 2.4 Benchmark (OGB) <https://ogb.stanford.edu/>`__. The dataset contains around
million nodes and 61 million edges. 170 thousand nodes and 1 million edges.
By the end of this tutorial, you will be able to By the end of this tutorial, you will be able to
...@@ -30,16 +30,19 @@ import torch ...@@ -30,16 +30,19 @@ import torch
import numpy as np import numpy as np
from ogb.nodeproppred import DglNodePropPredDataset from ogb.nodeproppred import DglNodePropPredDataset
dataset = DglNodePropPredDataset('ogbn-products') dataset = DglNodePropPredDataset('ogbn-arxiv')
device = 'cpu' # change to 'cuda' for GPU
###################################################################### ######################################################################
# OGB dataset is a collection of graphs and their labels. The Amazon # OGB dataset is a collection of graphs and their labels. ``ogbn-arxiv``
# Co-purchase Network dataset only contains a single graph. So you can # dataset only contains a single graph. So you can
# simply get the graph and its node labels like this: # simply get the graph and its node labels like this:
# #
graph, node_labels = dataset[0] graph, node_labels = dataset[0]
# Add reverse edges since ogbn-arxiv is unidirectional.
graph = dgl.add_reverse_edges(graph)
graph.ndata['label'] = node_labels[:, 0] graph.ndata['label'] = node_labels[:, 0]
print(graph) print(graph)
print(node_labels) print(node_labels)
...@@ -110,7 +113,7 @@ train_dataloader = dgl.dataloading.NodeDataLoader( ...@@ -110,7 +113,7 @@ train_dataloader = dgl.dataloading.NodeDataLoader(
graph, # The graph graph, # The graph
train_nids, # The node IDs to iterate over in minibatches train_nids, # The node IDs to iterate over in minibatches
sampler, # The neighbor sampler sampler, # The neighbor sampler
device='cuda', # Put the sampled bipartite graphs to GPU device=device, # Put the sampled bipartite graphs on CPU or GPU
# The following arguments are inherited from PyTorch DataLoader. # The following arguments are inherited from PyTorch DataLoader.
batch_size=1024, # Batch size batch_size=1024, # Batch size
shuffle=True, # Whether to shuffle the nodes for every epoch shuffle=True, # Whether to shuffle the nodes for every epoch
...@@ -184,7 +187,7 @@ class Model(nn.Module): ...@@ -184,7 +187,7 @@ class Model(nn.Module):
h = self.conv2(bipartites[1], (h, h_dst)) # <--- h = self.conv2(bipartites[1], (h, h_dst)) # <---
return h return h
model = Model(num_features, 128, num_classes).cuda() model = Model(num_features, 128, num_classes).to(device)
###################################################################### ######################################################################
...@@ -255,7 +258,8 @@ valid_dataloader = dgl.dataloading.NodeDataLoader( ...@@ -255,7 +258,8 @@ valid_dataloader = dgl.dataloading.NodeDataLoader(
batch_size=1024, batch_size=1024,
shuffle=False, shuffle=False,
drop_last=False, drop_last=False,
num_workers=0 num_workers=0,
device=device
) )
...@@ -295,9 +299,8 @@ for epoch in range(10): ...@@ -295,9 +299,8 @@ for epoch in range(10):
labels = [] labels = []
with tqdm.tqdm(valid_dataloader) as tq, torch.no_grad(): with tqdm.tqdm(valid_dataloader) as tq, torch.no_grad():
for input_nodes, output_nodes, bipartites in tq: for input_nodes, output_nodes, bipartites in tq:
bipartites = [b.to(torch.device('cuda')) for b in bipartites] inputs = bipartites[0].srcdata['feat']
inputs = node_features[input_nodes].cuda() labels.append(bipartites[-1].dstdata['label'].cpu().numpy())
labels.append(node_labels[output_nodes].numpy())
predictions.append(model(bipartites, inputs).argmax(1).cpu().numpy()) predictions.append(model(bipartites, inputs).argmax(1).cpu().numpy())
predictions = np.concatenate(predictions) predictions = np.concatenate(predictions)
labels = np.concatenate(labels) labels = np.concatenate(labels)
......
...@@ -3,9 +3,9 @@ Stochastic Training of GNN for Link Prediction ...@@ -3,9 +3,9 @@ Stochastic Training of GNN for Link Prediction
============================================== ==============================================
This tutorial will show how to train a multi-layer GraphSAGE for link This tutorial will show how to train a multi-layer GraphSAGE for link
prediction on Amazon Co-purchase Network provided by `Open Graph Benchmark prediction on ``ogbn-arxiv`` provided by `Open Graph Benchmark
(OGB) <https://ogb.stanford.edu/>`__. The dataset (OGB) <https://ogb.stanford.edu/>`__. The dataset
contains 2.4 million nodes and 61 million edges. contains around 170 thousand nodes and 1 million edges.
By the end of this tutorial, you will be able to By the end of this tutorial, you will be able to
...@@ -57,9 +57,12 @@ import torch ...@@ -57,9 +57,12 @@ import torch
import numpy as np import numpy as np
from ogb.nodeproppred import DglNodePropPredDataset from ogb.nodeproppred import DglNodePropPredDataset
dataset = DglNodePropPredDataset('ogbn-products') dataset = DglNodePropPredDataset('ogbn-arxiv')
device = 'cpu' # change to 'cuda' for GPU
graph, node_labels = dataset[0] graph, node_labels = dataset[0]
# Add reverse edges since ogbn-arxiv is unidirectional.
graph = dgl.add_reverse_edges(graph)
print(graph) print(graph)
print(node_labels) print(node_labels)
...@@ -114,7 +117,7 @@ train_dataloader = dgl.dataloading.EdgeDataLoader( ...@@ -114,7 +117,7 @@ train_dataloader = dgl.dataloading.EdgeDataLoader(
torch.arange(graph.number_of_edges()), # The edges to iterate over torch.arange(graph.number_of_edges()), # The edges to iterate over
sampler, # The neighbor sampler sampler, # The neighbor sampler
negative_sampler=negative_sampler, # The negative sampler negative_sampler=negative_sampler, # The negative sampler
device='cuda', # Put the bipartite graphs on GPU device=device, # Put the bipartite graphs on CPU or GPU
# The following arguments are inherited from PyTorch DataLoader. # The following arguments are inherited from PyTorch DataLoader.
batch_size=1024, # Batch size batch_size=1024, # Batch size
shuffle=True, # Whether to shuffle the nodes for every epoch shuffle=True, # Whether to shuffle the nodes for every epoch
...@@ -185,7 +188,7 @@ class Model(nn.Module): ...@@ -185,7 +188,7 @@ class Model(nn.Module):
h = self.conv2(bipartites[1], (h, h_dst)) h = self.conv2(bipartites[1], (h, h_dst))
return h return h
model = Model(num_features, 128).cuda() model = Model(num_features, 128).to(device)
###################################################################### ######################################################################
...@@ -250,7 +253,7 @@ def inference(model, graph, node_features): ...@@ -250,7 +253,7 @@ def inference(model, graph, node_features):
shuffle=False, shuffle=False,
drop_last=False, drop_last=False,
num_workers=4, num_workers=4,
device='cuda') device=device)
result = [] result = []
for input_nodes, output_nodes, bipartites in train_dataloader: for input_nodes, output_nodes, bipartites in train_dataloader:
...@@ -263,12 +266,12 @@ def inference(model, graph, node_features): ...@@ -263,12 +266,12 @@ def inference(model, graph, node_features):
import sklearn.metrics import sklearn.metrics
def evaluate(emb, label, train_nids, valid_nids, test_nids): def evaluate(emb, label, train_nids, valid_nids, test_nids):
classifier = nn.Linear(emb.shape[1], label.max().item()).cuda() classifier = nn.Linear(emb.shape[1], num_classes).to(device)
opt = torch.optim.LBFGS(classifier.parameters()) opt = torch.optim.LBFGS(classifier.parameters())
def compute_loss(): def compute_loss():
pred = classifier(emb[train_nids].cuda()) pred = classifier(emb[train_nids].to(device))
loss = F.cross_entropy(pred, label[train_nids].cuda()) loss = F.cross_entropy(pred, label[train_nids].to(device))
return loss return loss
def closure(): def closure():
...@@ -289,7 +292,7 @@ def evaluate(emb, label, train_nids, valid_nids, test_nids): ...@@ -289,7 +292,7 @@ def evaluate(emb, label, train_nids, valid_nids, test_nids):
prev_loss = loss prev_loss = loss
with torch.no_grad(): with torch.no_grad():
pred = classifier(emb.cuda()).cpu() pred = classifier(emb.to(device)).cpu()
label = label label = label
valid_acc = sklearn.metrics.accuracy_score(label[valid_nids].numpy(), pred[valid_nids].numpy().argmax(1)) valid_acc = sklearn.metrics.accuracy_score(label[valid_nids].numpy(), pred[valid_nids].numpy().argmax(1))
test_acc = sklearn.metrics.accuracy_score(label[test_nids].numpy(), pred[test_nids].numpy().argmax(1)) test_acc = sklearn.metrics.accuracy_score(label[test_nids].numpy(), pred[test_nids].numpy().argmax(1))
...@@ -303,8 +306,8 @@ def evaluate(emb, label, train_nids, valid_nids, test_nids): ...@@ -303,8 +306,8 @@ def evaluate(emb, label, train_nids, valid_nids, test_nids):
# The following initializes the model and defines the optimizer. # The following initializes the model and defines the optimizer.
# #
model = Model(node_features.shape[1], 128).cuda() model = Model(node_features.shape[1], 128).to(device)
predictor = DotPredictor().cuda() predictor = DotPredictor().to(device)
opt = torch.optim.Adam(list(model.parameters()) + list(predictor.parameters())) opt = torch.optim.Adam(list(model.parameters()) + list(predictor.parameters()))
...@@ -339,7 +342,7 @@ for epoch in range(1): ...@@ -339,7 +342,7 @@ for epoch in range(1):
tq.set_postfix({'loss': '%.03f' % loss.item()}, refresh=False) tq.set_postfix({'loss': '%.03f' % loss.item()}, refresh=False)
if step % 1000 == 999: if (step + 1) % 500 == 0:
model.eval() model.eval()
emb = inference(model, graph, node_features) emb = inference(model, graph, node_features)
valid_acc, test_acc = evaluate(emb, node_labels, train_nids, valid_nids, test_nids) valid_acc, test_acc = evaluate(emb, node_labels, train_nids, valid_nids, test_nids)
......
...@@ -18,9 +18,13 @@ import torch ...@@ -18,9 +18,13 @@ import torch
import numpy as np import numpy as np
from ogb.nodeproppred import DglNodePropPredDataset from ogb.nodeproppred import DglNodePropPredDataset
dataset = DglNodePropPredDataset('ogbn-products') dataset = DglNodePropPredDataset('ogbn-arxiv')
device = 'cpu' # change to 'cuda' for GPU
graph, node_labels = dataset[0] graph, node_labels = dataset[0]
# Add reverse edges since ogbn-arxiv is unidirectional.
graph = dgl.add_reverse_edges(graph)
graph.ndata['label'] = node_labels[:, 0]
idx_split = dataset.get_idx_split() idx_split = dataset.get_idx_split()
train_nids = idx_split['train'] train_nids = idx_split['train']
node_features = graph.ndata['feat'] node_features = graph.ndata['feat']
...@@ -170,7 +174,7 @@ class SAGEConv(nn.Module): ...@@ -170,7 +174,7 @@ class SAGEConv(nn.Module):
g.srcdata['h'] = h_src # <--- g.srcdata['h'] = h_src # <---
g.dstdata['h'] = h_dst # <--- g.dstdata['h'] = h_dst # <---
# update_all is a message passing API. # update_all is a message passing API.
g.update_all(fn.copy_u('h', 'm'), fn.mean('m', 'h_neigh')) g.update_all(fn.copy_u('h', 'm'), fn.mean('m', 'h_N'))
h_N = g.dstdata['h_N'] h_N = g.dstdata['h_N']
h_total = torch.cat([h_dst, h_N], dim=1) # <--- h_total = torch.cat([h_dst, h_N], dim=1) # <---
return self.linear(h_total) return self.linear(h_total)
...@@ -192,18 +196,18 @@ class Model(nn.Module): ...@@ -192,18 +196,18 @@ class Model(nn.Module):
sampler = dgl.dataloading.MultiLayerNeighborSampler([4, 4]) sampler = dgl.dataloading.MultiLayerNeighborSampler([4, 4])
train_dataloader = dgl.dataloading.NodeDataLoader( train_dataloader = dgl.dataloading.NodeDataLoader(
graph, train_nids, sampler, graph, train_nids, sampler,
device=device,
batch_size=1024, batch_size=1024,
shuffle=True, shuffle=True,
drop_last=False, drop_last=False,
num_workers=0 num_workers=0
) )
model = Model(graph.ndata['feat'].shape[1], 128, dataset.num_classes).cuda() model = Model(graph.ndata['feat'].shape[1], 128, dataset.num_classes).to(device)
with tqdm.tqdm(train_dataloader) as tq: with tqdm.tqdm(train_dataloader) as tq:
for step, (input_nodes, output_nodes, bipartites) in enumerate(tq): for step, (input_nodes, output_nodes, bipartites) in enumerate(tq):
bipartites = [b.to(torch.device('cuda')) for b in bipartites] inputs = bipartites[0].srcdata['feat']
inputs = node_features[input_nodes].cuda() labels = bipartites[-1].dstdata['label']
labels = node_labels[output_nodes].cuda()
predictions = model(bipartites, inputs) predictions = model(bipartites, inputs)
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
. /opt/conda/etc/profile.d/conda.sh . /opt/conda/etc/profile.d/conda.sh
conda activate pytorch-ci conda activate pytorch-ci
TUTORIAL_ROOT="./tutorials" TUTORIAL_ROOT="./tutorials"
NEW_TUTORIAL_ROOT="./new-tutorial"
function fail { function fail {
echo FAIL: $@ echo FAIL: $@
...@@ -27,4 +28,12 @@ do ...@@ -27,4 +28,12 @@ do
python3 $f || fail "run ${f}" python3 $f || fail "run ${f}"
done done
popd > /dev/null popd > /dev/null
\ No newline at end of file
pushd ${NEW_TUTORIAL_ROOT} > /dev/null
for f in $(find . -name "*.py" ! -name "*_mx.py")
do
echo "Running tutorial ${f} ..."
python3 $f || fail "run ${f}"
done
popd > /dev/null
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment