MUTAG molecular graphs¶
MUTAG is Tinymesh's first collection of variable-size graphs. This stage only establishes a pinned, sparse data boundary for graph-level experiments; it makes no representation or classification claim.
Pinned source¶
The loader fetches the canonical TU Dortmund archive:
The default path uses a ten-second request, reads at most 32 KiB, and verifies the exact checksum and byte count. An explicit ZIP path supports offline use and fixtures; it remains archive- and member-size bounded and is validated structurally. No dataset payload is committed or redistributed. The archive README does not state a license, so Tinymesh makes no redistribution claim.
Public boundary¶
from tinymesh.datasets import mutag
data = mutag(device="CPU")
graph, atom, bond, label = data[0]
node_features = atom.one_hot(len(data.node_types)).float()
print(len(data), graph.nodes, graph.edges)
# 188 17 38
print(node_features.shape, bond.shape, label)
# (17, 7) (38,) 1
MUTAG owns four aligned facts per molecule:
graph sparse directed storage of an undirected molecular graph
node_labels [N] categorical atom type in node_types order
edge_labels [E] categorical bond type in bond_types order
labels graph class remapped from source {-1, 1} to {0, 1}
Each chemical bond is represented by two matching directed edges because
Graph has one directed primitive. The loader preserves source edge order,
keeps edge labels aligned with COO identity, and rejects cross-graph edges,
self-loops, duplicates, missing reverse edges, invalid label domains, malformed
member rows, and oversized input.
The pinned PyG
TUDataset
reports the same 188 graphs, seven one-hot node features, four one-hot edge
features, and two classes. Tinymesh retains integer source labels as the single
fact; ordinary tinygrad one_hot derives model inputs.
Full-source witness¶
Revision
290d055
produced identical CPU and Metal observations:
graphs 188
classes 2 (63, 125)
nodes 3,371 (10 to 28 per graph)
directed edges 7,442
undirected bonds 3,721
reciprocal edges 7,442
node-type counts 2,395 345 593 12 1 23 2
bond-type counts 4,708 2,008 724 2
The exact agreement proves device-independent categorical lowering. The reciprocal count proves every stored edge has its reverse; it does not prove a model uses atom, bond, or topology information.
uv run --locked python -m experiments.run mutag_data DEV=CPU
uv run --locked python -m experiments.run mutag_data DEV=METAL
The next stage will define train-only self-supervision, frozen probes, splits, and controls. Those policies do not belong in the loader.
The cross-dataset network measurement confirms that all 188 molecular graphs are connected and contain no isolated nodes. Their per-graph diameters have mean 8.22, p90 11, and maximum 15. Because every bond is reciprocal, weak and directed distance agree.