Correct and Smooth on Cora
Author: K3-Node Team
Backend: Multi-Backend
Dataset: Cora (Planetoid)
Description: Classify papers in the Cora citation network by topic in two stages (Huang et al., 2020).
Correct and Smooth on Cora
Classify papers in the Cora citation network by topic in two stages (Huang et al., 2020). First, a plain MLP predicts each paper's topic from its own features only. Then Correct and Smooth uses the graph without any training: it spreads the MLP's errors on the labeled papers to their neighbors ("correct"), and then smooths the predictions over the graph ("smooth").
Same model as PyG's examples/correct_and_smooth.py; on Cora instead of ogbn-products to keep the dataset small, trained for 200 epochs instead of 300.
Install K3-Node, then choose a backend: "tensorflow", "torch" or "jax"
Load the data
data holds one graph: node features x, edges edge_index, labels y, and masks marking the training, validation and test nodes.
import keras
from keras import ops
from k3_node.datasets import Planetoid
from k3_node.loader import FullGraphDataset
dataset = Planetoid("data/Planetoid", name="Cora")
data = dataset[0]
print(data)
Train a plain MLP
The MLP ignores the graph and looks only at each paper's words.
from k3_node.models import MLP, CorrectAndSmooth
class MLPClassifier(keras.Model):
def __init__(self, in_channels, out_channels):
super().__init__()
self.mlp = MLP([in_channels, 200, 200, out_channels], dropout=0.5, norm="batch_norm", act_first=True)
def call(self, data, training=False):
return self.mlp(data.x, training=training)
model = MLPClassifier(dataset.num_features, dataset.num_classes)
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.01),
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
weighted_metrics=["accuracy"],
)
model.fit(FullGraphDataset(data, mask="train_mask"), epochs=200, verbose=0)
y_soft = ops.softmax(model.predict(FullGraphDataset(data), verbose=0))
print(f"MLP test accuracy: {data.accuracy(y_soft, mask='test_mask'):.4f}")
Correct and smooth
No training here: both steps propagate information along the citation links.
post = CorrectAndSmooth(num_correction_layers=50, correction_alpha=1.0,
num_smoothing_layers=50, smoothing_alpha=0.8, autoscale=False, scale=20.0)
y_soft = post.correct(y_soft, data.y, data.train_mask, data.edge_index)
y_soft = post.smooth(y_soft, data.y, data.train_mask, data.edge_index)
print(f"Test accuracy after Correct and Smooth: {data.accuracy(y_soft, mask='test_mask'):.4f}")