Tutorial 1: Introduction¶
[1]:
import os
import torch
os.environ['TORCH'] = torch.__version__
print(torch.__version__)
!pip install -q torch-scatter -f https://data.pyg.org/whl/torch-${TORCH}.html
!pip install -q torch-sparse -f https://data.pyg.org/whl/torch-${TORCH}.html
!pip install -q git+https://github.com/pyg-team/pytorch_geometric.git
1.12.1+cu113
[2]:
import torch_geometric
from torch_geometric.datasets import Planetoid
[3]:
use_cuda_if_available = False
Load the dataset¶
[4]:
dataset = Planetoid(root="tutorial1",name= "Cora")
Dataset properties¶
[5]:
print(dataset)
print("number of graphs:\t\t",len(dataset))
print("number of classes:\t\t",dataset.num_classes)
print("number of node features:\t",dataset.num_node_features)
print("number of edge features:\t",dataset.num_edge_features)
Cora()
number of graphs: 1
number of classes: 7
number of node features: 1433
number of edge features: 0
Dataset shapes¶
[6]:
print(dataset.data)
Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], train_mask=[2708], val_mask=[2708], test_mask=[2708])
[7]:
print("edge_index:\t\t",dataset.data.edge_index.shape)
print(dataset.data.edge_index)
print("\n")
print("train_mask:\t\t",dataset.data.train_mask.shape)
print(dataset.data.train_mask)
print("\n")
print("x:\t\t",dataset.data.x.shape)
print(dataset.data.x)
print("\n")
print("y:\t\t",dataset.data.y.shape)
print(dataset.data.y)
edge_index: torch.Size([2, 10556])
tensor([[ 0, 0, 0, ..., 2707, 2707, 2707],
[ 633, 1862, 2582, ..., 598, 1473, 2706]])
train_mask: torch.Size([2708])
tensor([ True, True, True, ..., False, False, False])
x: torch.Size([2708, 1433])
tensor([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]])
y: torch.Size([2708])
tensor([3, 4, 4, ..., 3, 3, 3])
[8]:
import os.path as osp
import torch
import torch.nn.functional as F
from torch_geometric.nn import SAGEConv
[9]:
data = dataset[0]
[10]:
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv = SAGEConv(dataset.num_features,
dataset.num_classes,
aggr="max") # max, mean, add ...)
def forward(self):
x = self.conv(data.x, data.edge_index)
return F.log_softmax(x, dim=1)
[11]:
device = torch.device('cuda' if torch.cuda.is_available() and use_cuda_if_available else 'cpu')
model, data = Net().to(device), data.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
[12]:
device
[12]:
device(type='cpu')
[13]:
def train():
model.train()
optimizer.zero_grad()
F.nll_loss(model()[data.train_mask], data.y[data.train_mask]).backward()
optimizer.step()
def test():
model.eval()
logits, accs = model(), []
for _, mask in data('train_mask', 'val_mask', 'test_mask'):
pred = logits[mask].max(1)[1]
acc = pred.eq(data.y[mask]).sum().item() / mask.sum().item()
accs.append(acc)
return accs
[14]:
best_val_acc = test_acc = 0
for epoch in range(1,100):
train()
_, val_acc, tmp_test_acc = test()
if val_acc > best_val_acc:
best_val_acc = val_acc
test_acc = tmp_test_acc
log = 'Epoch: {:03d}, Val: {:.4f}, Test: {:.4f}'
if epoch % 10 == 0:
print(log.format(epoch, best_val_acc, test_acc))
Epoch: 010, Val: 0.7160, Test: 0.7260
Epoch: 020, Val: 0.7160, Test: 0.7260
Epoch: 030, Val: 0.7160, Test: 0.7260
Epoch: 040, Val: 0.7160, Test: 0.7260
Epoch: 050, Val: 0.7160, Test: 0.7260
Epoch: 060, Val: 0.7180, Test: 0.7070
Epoch: 070, Val: 0.7240, Test: 0.7170
Epoch: 080, Val: 0.7260, Test: 0.7230
Epoch: 090, Val: 0.7260, Test: 0.7230