Skip to content
VINODvoidPublic

About

a small network learns kinship facts through a 6-unit bottleneck and invents concepts like generation and nationality on its own.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

47 Commits

Folders and files

Repository files navigation

treeq

tree

treeq is a small educational experiment for learning how neural networks can learn structured relationships.

It follows a key paper:

It uses two small, isomorphic family trees — one English and one Italian — and trains a network to answer questions such as:

John  → father  → David
David → sister  → Sarah
James → brother → Robert

Everything here is written from scratch on top of numpy: the forward pass, back-propagation, and the training loop. There is no autograd and no deep learning framework.

The experiment is a squeeze. Each person enters the network through an encoder of N units, and the network is trained twice: once with N = 24, one unit per person and room to just memorise, and once with N = 6, four people per unit so something has to be shared. The question is what the narrow one gives up — and what it works out in exchange.

The data

The family trees live in data/families.csv and are defined using only three primitives:

  • parents
  • spouse
  • sex

Every other relationship is derived from those. Six sex-neutral relations (parents_of, children_of, siblings_of, spouse_of, piblings_of, niblings_of) are filtered by sex to give the twelve the network is trained on:

father  mother  husband  wife  son     daughter
brother sister  uncle    aunt  nephew  niece

Running all twelve over 24 people gives 132 training rows — every (person, relation) pair that has at least one answer. A row can have more than one answer: David → son is both James and Robert, so the target is multi-hot.

Install and run

uv sync
uv run treeq
132 rows  24 people  12 relations
training 6 models...

person_dim  runs   train    test     loss
-----------------------------------------
        24     3   0.987   0.417   0.1738
         6     3   0.997   0.583   0.0451

Useful flags:

uv run treeq --show-codes              # print the learned person representation
uv run treeq --ask David son           # train on every row, then ask a question
uv run treeq --dims 24 12 6 --seeds 0 1 2 3 4
uv run treeq --epochs 2000 --learning-rate 0.5 --n-test 4
uv run treeq --help

Layout

data/families.csv        24 people, two isomorphic trees
src/treeq/kinship.py     primitives and the twelve derived relations
src/treeq/dataset.py     relations → training rows, and the held-out split
src/treeq/network.py     sigmoid, init, forward, backward, train, scoring
src/treeq/experiment.py  running and summarising the dimension comparison
src/treeq/cli.py         the treeq command
docs/                    results and design notes

Tests

uv run pytest

Back-propagation is checked against finite differences — every analytic gradient is compared with the loss actually moving when the weight is nudged, which is the only real proof the derivation is right.

Further reading

  • docs/results.md — what the two representations actually scored, what the bottleneck learned about the two families, and why the numbers are thinner evidence than they look
  • docs/design.md — the architecture, the in-law decision behind uncle/aunt/nephew/niece, how scoring and splitting work, and where this parts company with the paper

This project really gives a proper understanding of relationships 😋

About

a small network learns kinship facts through a 6-unit bottleneck and invents concepts like generation and nationality on its own.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages