findintermediate5 min readseries overview

Find anything in your own photo library, offline

A seven-part series on building a private image search tool that learns which photos you actually want.

Before you start

  • Python3.10 or newer
  • about1 GB of disk for model weights
  • a folder of photos

You have a folder with thousands of photos and no way to find anything in it. Filenames are IMG_4471.jpg. The dates tell you nothing. You know there is a picture in there of the thing you need, and the only tool you have is scrolling.

This series builds the fix. When you are done you will have a tool that runs entirely on your machine, needs no internet after the first setup, sends nothing anywhere, and gets more accurate at finding what you specifically care about the more you use it.

What you end up with#

A browser dashboard on 127.0.0.1 with four things in it.

Type a description and get ranked matches. No tagging, no folders, no manual organization of any kind.

Train a concept by correcting it. Click through a couple hundred photos marking yes and no, and it learns the boundary between what you want and what you do not. After that it sorts new photos without you.

Find people. It detects every face in your library, groups them into individuals on its own, and lets you name each group once. Or upload a photo of someone and get back every picture they appear in.

Export. Copy every match into a folder, one folder per source, safe to re-run.

The idea that makes it work#

Nothing in this series trains a model. That is the part most tutorials get backwards, and it is why they tell you to collect five thousand labeled images and wait overnight for a GPU.

Instead, every photo gets converted once into 512 numbers by a model that already understands images. Those numbers never change. All the learning happens in a tiny classifier fitted on top of them, which takes about a second to train and needs roughly thirty examples instead of five thousand.

That one architectural decision is what makes the whole thing practical on a laptop with no graphics card.

What it costs before you start#

Disk, mostly, and all of it once. The CLIP weights come to roughly 600 MB and the face model adds another 330 MB, both downloaded on first run and never fetched again. The index itself is small: about 2 KB per photo, so a 20,000 image library is around 40 MB sitting next to your originals.

Time is the part worth planning around. Indexing 107 photos ran at 8.3 images/secmeasuredWindows laptop, CPU-only torch, batch 32, and a typical desktop CPU should land nearer 10 to 20 images/secestimatetypical CPU. At that rate a 20,000 photo library is a long lunch rather than an overnight job. Face detection is slower again, somewhere around a few photos/secestimateface detection on CPU, because every image gets a full detection pass before anything is embedded.

You pay that cost once. Everything after indexing is arithmetic over numbers you already have, which is why teaching it a new concept takes about a second instead of an afternoon, and why you can afford to be wrong and try again.

The guides, in order#

  1. Set up CLIP and index a folder offline. Environment, model weights, cutting the network, and turning a folder of photos into a searchable index.

  2. Search by text, and why it is not enough. How a sentence and a photo get compared with arithmetic, how to read the scores, and the specific reason plain text search plateaus.

  3. The correction loop. Fitting a classifier on frozen embeddings, why correcting the uncertain cases beats correcting random ones, and how to tell when you are done.

  4. Build the dashboard. Wrapping all of it in a local Flask page so you stop memorizing command line flags.

  5. Face recognition. Why CLIP cannot tell people apart, what to use instead, and how to discover everyone in your library without labeling.

  6. Every error we actually hit. The real failures, with the literal messages, in the order they showed up.

Start with the first one. Each guide assumes the previous one is done.

How each guide is written#

Every guide explains why a step works rather than only listing what to type, quotes the literal error text you will hit so you can search for it, and ends by saying where the approach stops being the right tool. The last one is the part most tutorials leave out, and it is usually the part that saves you a wasted weekend.

Numbers are marked as measured or estimated. A measured figure came off a real machine and names that machine; an estimate is a reasoned guess and says so. The two are never blurred together, so you can tell at a glance which numbers to plan against and which to treat as a rough shape.

Who this is not for#

If you need to identify objects in a live video stream, or you are working with medical imaging, thermal, or any non-photographic input, the approach here transfers badly. CLIP learned from photos with captions, and its sense of similarity is only useful on things that look like photos with captions.

If you have a hard accuracy requirement and a labeled dataset already, train a proper classifier. This series is for the far more common case: a pile of personal photos, no labels, and a fuzzy idea of what you are looking for.

More on finding things in your own files