KPK

Kevin Paul Klaiber · Developer and ML engineer

Machine learning you can press a button on.

I train models on data: photos of Earth from a million miles away, a folder of kick drums, whatever a local language model can be talked into doing. Then I put them somewhere you can try them. Two of the three projects below run in this page.

Scroll

About

I'm a machine learning engineer. Most of what I do comes down to the same thing: take a raw signal and turn it into something you can use. A picture becomes a pair of coordinates. A folder of drum samples becomes a space you can move through with five sliders.

That mostly means computer vision and audio, though lately it also means Android. I like problems where the data comes from the physical world and arrives messy, and I like shipping the result somewhere people can actually poke at it rather than leaving it in a notebook.

If it involves signal processing, generative models, or an odd use for deep learning, I'm probably interested.

What I work with

  • PythonLanguages
  • PyTorchML and DSP
  • Computer visionML and DSP
  • Audio and DSPML and DSP
  • Deep learningML and DSP
  • CNNsML and DSP
  • VAEsML and DSP
  • Signal processingML and DSP
  • NumPy and SciPyTooling
  • TensorBoardTooling

Work

Three projects, each with the short version first and the technical detail a click away.

Computer vision

Where on Earth are we

A neural network that looks at one photo of Earth from a satellite and works out which point on the planet the camera was above.

Frame
Convolve
lon,lat
Predict
PredictedWhere it really was
401 km
Mean error, in browser
197 km
Mean error, ensemble
1,628 km
Previous model
99%
Within 1,000 km

The problem

The DSCOVR satellite sits a million miles out and photographs the whole sunlit face of Earth. Every photo comes labelled with the coordinates of the spot the camera was centred on. The question was whether a network could read those coordinates back out of the picture alone, having trained on a small slice of the archive rather than all of it.

The approach

Three blocks of convolutions squeeze the image down to a set of feature maps, and a small dense layer turns those into a position. Two changes did most of the work. The model now also trains on Copernicus Sentinel-2 photos, which adds far more labelled ground to learn from. And instead of predicting longitude as a plain number, it predicts a point on a circle, so the jump from +180 to -180 in the middle of the Pacific stops being a cliff the model falls off.

The result

Mean error fell to 401 km for the model running on this page, and to 197 km when several models vote. The version it replaced averaged 1,628 km while training on years more data. The pipeline also draws what the network has learned onto a world map: once it understands geography, its features cluster into recognisable continents and latitude bands.

Process

  1. FetchDownload the images and their coordinates
  2. SplitDivide by date, so no day appears twice
  3. TrainAdam and MSE, logged to TensorBoard
  4. ScoreGreat-circle distance, in km and degrees
  5. DrawCluster the features onto a world map
PythonPyTorchNASA EPIC APISentinel-2TensorBoardCartopy
Source

Generative audio

An intelligent Drum Machine

Train a model on a folder of kick drums and it learns a space where similar sounds sit near each other. Five sliders move you through that space, and what comes out is a kick that was never in the folder.

Spectrogram

Waveform

Sub

Punch

Click

Bright

Decay

5
Named sliders
44.1 kHz
Output audio
16-step
Sequencer
BigVGAN
Vocoder

The problem

A sample library is a flat list of files. You audition kicks by filename until one fits, which tells you nothing about how any of them actually sound. The question was whether the library could be a space instead, with controls named after what you hear rather than what the file is called.

The approach

A variational autoencoder trains on pictures of the sound, log-mel spectrograms, and learns to compress each one to a handful of numbers and back again. PCA then reduces that space to five directions, and each direction gets a name by measuring which audible quality it tracks: sub, punch, click, brightness, decay. A vocoder turns the generated spectrogram back into audio at 44.1 kHz, with a slower CPU-only method available when there is no GPU.

The result

One engine behind several front ends: a terminal app, a web interface with a sequencer, a plain HTML page served by the API itself, and a dashboard for looking at the sample library. Moving a slider changes the sound in the direction its name promises. The decay slider was deliberately decorrelated from the others, so changing brightness no longer quietly changes how long the sample runs.

Process

  1. StripIsolate the kick, detect loops automatically
  2. LevelNormalise loudness to -14 LUFS
  3. EncodeTurn each sample into a log-mel spectrogram
  4. TrainVariational autoencoder, annealed
  5. ReducePCA down to 5 sliders, each auto-named
  6. RenderSpectrogram back to audio through the vocoder
PythonPyTorchBigVGAN v2FastAPINext.jsTextual
Source

Android

An Ollama Client

An Android app for talking to Ollama models, built for people who want the model to do things: read their repositories, search the web, remember what it was told, and run prompts on a schedule.

294
Tests
22.4K
Lines of Kotlin
18
Callable tools
0
Trackers

The problem

Most mobile Ollama clients are a text box around a single API call. They guess what a model can do from its name, leave every setting unexplained, and when you press stop the phone stops listening while the server carries on generating. Close the thread and everything it knew is gone. None of that is caused by being on a phone.

The approach

Ask the server what each model can do instead of guessing, by reading the entry it publishes. Tie the stop button to the network call, so stopping actually stops the server. Give the model a fixed set of tools it can call in a loop that is capped rather than open-ended, and a memory it writes to on purpose and can search later. Typeset maths properly instead of flattening it into plain characters. Keep the ability to write to GitHub behind a switch that is off by default and enforced at the network layer, not inside each tool.

The result

22,400 lines of Kotlin in one module, covered by 294 tests, released through a build that refuses to ship if the tag and the version disagree. Markdown keeps rendering while it streams, including a half-finished code block. Formulas are laid out rather than approximated: fractions stack over a rule and brackets stretch to fit. There is no analytics, no crash reporter and no backend of mine. The only servers it talks to are the ones you pointed it at.

Process

  1. AskRead each model's capabilities from the server
  2. StreamToken by token, and stop means stop
  3. TypesetLay out maths while it is still arriving
  4. DelegateLet the model call tools, six rounds at most
  5. RememberKeep the facts worth keeping, and rank them
  6. ScheduleRun prompts on a clock, in the background
KotlinJetpack ComposeMaterial 3OkHttpRoomWorkManager
Source

Try them

Two of the projects run here in the page. The models do their work in your browser, so give them a moment on a slow connection.

Computer vision

Guess where a photo was taken

Pick a photo of Earth taken by NASA's EPIC camera. The network looks at it and marks the spot on the globe it thinks the camera was above. The real answer gets marked too, so you can see how close it got.

How to use it

Load the latest images, choose one, and let it predict. The map plots the guess next to the true point.

A line joins each guess to the true point. The longer write-up is in the case study.

Generative audio

Build a kick drum with five sliders

The sliders move you through a space the model learned from a library of kick samples. Each one is named after what it changes: how much sub, how much punch, how much click.

How to use it

Move a slider, press Generate, and listen. Then program a pattern in the 8-step sequencer to hear the kick next to a snare and two hats.

Each slider is one direction through the learned space, named by the quality it correlates with.

Get in touch

Questions about how any of this works, freelance briefs, or a note about something you are building. All welcome, and I read what arrives.