Work

Models I've trained and the interfaces I've built around them. Each ML project has a case study.

Retrieve
Grade
Rewrite
Answer
  1. Pick a question to trace it through the graph.

Illustration of the LangGraph control flow, not a recorded run.

Retrieval-augmented generation

DocQA

Upload a PDF and ask it questions, including about its tables and images. Each answer points back to the page it came from.

  • Python
  • LangGraph
  • Gemini
  • FastAPI
  • Streamlit
A height map generated by GanScape, rendered as relief
A height map generated by GanScape, rendered as relief

Generative models

GanScape

A GAN that turns a segmentation mask into a height map, which I then render as 3D terrain.

  • Python
  • PyTorch
  • NumPy
  • SciPy
A crop pest found by the detector, with its bounding box and confidence
A crop pest found by the detector, with its bounding box and confidence
A crop pest found by the detector, with its bounding box and confidence

Embedded computer vision

Pest detection on a Raspberry Pi

A YOLOv5n model with attention that spots crop pests in real time on a Raspberry Pi. I quantized and pruned it so it would run fast enough on the Pi.

  • Python
  • PyTorch
  • Ultralytics
  • Raspberry Pi
hover the chart
-100010020030001k2k3k4k5k300 = solved

Reinforcement learning

Bipedal walking agents

I trained PPO, TD3 and SAC agents to walk in BipedalWalker-v3 and compared how each one learned.

  • Python
  • PyTorch

Builds

Websites I designed and built myself.

Homepage of Zineps, reimagined

Design challenge entry

Zineps, reimagined

My entry for Zineps' public redesign challenge: a 15-page site for a shipping platform, with an animated route globe, a carrier comparison and a pricing estimator.

  • React
  • TypeScript
  • Vite
Homepage of takeUforward, reimagined

Unofficial design concept

takeUforward, reimagined

A design concept for takeUforward, a DSA learning platform, with guided walkthroughs, a learner workspace and ⌘K search.

  • React
  • TypeScript
  • Vite
  • Motion

Playground

Draw up to three digits, then lower the weight precision and see when it starts getting them wrong.

An example 27. Draw over the pad to try your own.

What the model sees: each digit cut out, shrunk to 28 by 28 pixels and centred, the way MNIST digits are.

Loading the model…

It reads

?

Every guess the model considered

  • 00.0%
  • 10.0%
  • 20.0%
  • 30.0%
  • 40.0%
  • 50.0%
  • 60.0%
  • 70.0%
  • 80.0%
  • 90.0%

Squeeze the weights

Model size
75.4 KB
Accuracy on 10,000 test digits
98.7%outlined 96.9%

Squeeze the weights and watch it change its mind. At 8 bits the network is a quarter of the size and reads just as well, and at 4 bits it still holds. At 3 bits it starts guessing, and at 2 it forgets almost everything it learned.