Skip to content

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:

MUTAG.zip
24,550 bytes
SHA-256 c419bdc853c367d2d83da4973c45100954ae15e10f5ae2cddde6ca431f8207f6

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.