A 5KB model that learns which photos you delete
Every photo cleaner sorts your library the same way: duplicates over here, blurry ones over there, screenshots in a pile. Useful once. The second time, the app has learned nothing about you — it hands the same suggestions to a wedding photographer and to someone whose camera roll is eight thousand screenshots of train times. Sift learns the difference, on your phone, in 65 numbers.
The question a cleaner should be asking
Apple’s Vision framework can already tell you what is in a photograph. It runs on the Neural Engine, it was trained on a dataset no small team could ever assemble, and it recognises around 1,300 things. Competing with that would be the expensive kind of foolish, and I know better than to try.
But “what is in this photo” was never actually the question. The real question is will this person delete it — and Vision cannot know that, because the answer depends entirely on the person. One user bins every screenshot on sight. Another keeps every one, because their whole job lives inside screenshots. Both of them are right, and no general model can be right about both at once.
So I only built the part that was missing
Vision’s output becomes an input. Alongside it go the signals I am already computing during the scan — sharpness, whether the photo is one of a burst, whether it is a screenshot or a Live Photo, its age and its size. Sixty-five numbers in total, feeding one logistic regression:
- 21 signals about the file
- 44 confidences from Vision’s own classifier
- one output: how likely you are to bin this
Sixty-five weights come out to about five kilobytes. Not a model download. Not a training cluster. It ships inside the app and updates itself in place.
Where the training data comes from
This is the part that actually makes it work, and it is almost an accident of the design. Sift has a review mode where you go through a pile of photos one at a time and swipe — left to bin, right to keep.
Every swipe is a labelled example. A photo, its features, and your verdict. The feature that makes the app pleasant to use turns out to be the same thing that teaches it, and the data never has to travel anywhere, because it was generated on the device by the one person it describes.
Compare that with almost any other machine-learning feature in a consumer app, where the model gets trained centrally on data collected from everyone. There is nothing to collect here. There is no server. The model on your phone belongs to you, and it ends up different from the one on anybody else’s phone.
Why not Core ML’s on-device training?
Apple provides MLUpdateTask for exactly this kind of
thing — personalising a model on the device. I deliberately
did not use it.
It exists to retrain the last layers of a large neural network, where the bookkeeping gets genuinely hard. For sixty-five parameters, one step of stochastic gradient descent is about ten lines of arithmetic. Using the framework would have meant shipping a compiled model file, versioning it, handling its failure modes, and reading a stack trace through an abstraction — all to wrap ten lines you can read in one screen and debug by printing them.
A model small enough to understand completely is a model I can be honest with you about.
Useful on day one, yours by day three
A model that starts out blank is useless at exactly the moment someone is deciding whether an app is any good. So the weights start at sensible defaults: a blurry photo that is also part of a burst leans hard toward binning, a photograph of a person leans hard toward keeping.
The Vision weights, though, start at zero. What a picture of a dog means to you is precisely the thing I do not know and have no business guessing. Two exceptions, because they are not taste but near-universal: a face in frame, and a page of text. Starting those blank would waste your first fifty swipes relearning what everybody already agrees on.
After a dozen swipes the app starts telling you what it found, in plain words — which categories it now puts in front of you, and which it holds back. If it is wrong, one button forgets everything. A model of your taste is data about you, and you get to delete it.
It ranks. It never deletes.
The model orders the review queue so the photos you are most likely to bin come first, while your attention is at its sharpest. Beyond that ordering, it has no authority at all.
That limit is deliberate, and it is permanent. A confident wrong prediction about a malware file costs you a scan; a confident wrong prediction about someone’s photographs is not recoverable. Every deletion in Sift is confirmed by a person, told how many files and how many megabytes, and lands in Recently Deleted where iOS keeps it for thirty days.
What this looks like in practice
A pile of four hundred photos that used to be four hundred equal decisions becomes front-loaded instead: the obvious bins arrive in the first minute, the genuinely uncertain ones later, and the photos you would never part with sink to the bottom where you can stop without missing them.
No round trip. No account. Nothing uploaded. Five kilobytes of arithmetic that happens to be about you.
Sift finds the duplicates, the near-copies, the blurry shots, the screenshots and the oversized video — and learns which of them you actually want gone. See what it does →