Show RF: False Positive Scout, hard-negative mining in your pocket (open-source iOS app)
Link to project: GitHub - pmn4/false-positive-scout: Native Swift iOS app: capture null / false-positive frames for Roboflow detectors · GitHub (MIT)
Demo: (video in the repo linked above)
Project description: Hard-negative mining in your pocket
I’m training an RF-DETR model to find a lacrosse stick, stick head, and ball for a wall-ball app. It kept seeing lacrosse gear all over my house. A rake in the garage read as a stick. A rug pattern came back as a stick head at 79%. A pair of shoes set it off too.
The fix is well known: add null images of exactly those things. Collecting them by hand is the slow part.
So I built False Positive Scout, a native Swift/SwiftUI iPhone app. Walk around with your own model running on your phone, find the stuff it’s confidently wrong about, and send those frames back to your project as nulls.
How it works:
- Log in and pick a model. Tap Log in with Roboflow, approve consent, pick workspace > project > version. Scout downloads that version’s Core ML export and runs it on device.
- Hold to scout. Live camera with boxes; detection runs about 10 times a second. Frames are saved only while you hold the shutter, and only if the model fired. Near-duplicates get skipped (8x8 perceptual hash) unless the object count went up, so you don’t end up with 40 copies of the same rug. Global and per-class confidence thresholds if one class is noisier than the rest.
- Swipe to review. Right = false positive, keep it. Left = toss.
- Upload & Nullify. Kept frames go to the project of the model that caught them, as a zip upload into one batch named
Scout - <date time>, splittrain, tagscout. Each image gets marked null.
In the demo, it’s a pair of sneakers on the lawn reading as a stick head.
One rule if you try it: only swipe right on frames with zero real objects of any class you care about. If a real stick (or ball, or whatever you detect) is in the frame, label it instead. Otherwise it’s a missing annotation, not a null, and you’re teaching the model to ignore the real thing. Roboflow’s post explains it: Missing vs. Null Annotations in Computer Vision Datasets | Roboflow
How it fits with what Roboflow already has: Active Learning and the Dataset Upload block mostly surface predictions your model is unsure about from production, and the iOS starter’s “Upload Incorrect Image” button sends one unlabeled frame per tap. Scout goes after what the model is confidently wrong about, with you walking up to it, and lands each frame already null.
How to try it: there’s no TestFlight or App Store build, and there won’t be unless there is demand. You build it onto your own iPhone with Xcode and an Apple account.
git clone https://github.com/pmn4/false-positive-scout.git && cd false-positive-scoutcp Config/Secrets.xcconfig.example Config/Secrets.xcconfig(required; the build stops with an error telling you to do this if it’s missing)- In
Config/Secrets.xcconfig, setDEVELOPMENT_TEAMto your Team ID andPRODUCT_BUNDLE_IDENTIFIERto something unique, likecom.yourname.falsepositivescout - Optional: copy
Config/Secrets.plist.exampletoConfig/Secrets.plistfor a default workspace/project, or to use your own OAuth client ID - Open
Scout.xcodeproj, plug in your iPhone, Run - Settings > Log in with Roboflow, then pick workspace > project > version
(if this is all too much, lmk, and I’ll get it on TestFlight)
Model support: only RF-DETR Core ML exports have been tested end to end. There’s a Vision/YOLO code path, but I haven’t verified it. If you have a YOLO model and an iPhone, tell me if it works.
Where this goes: this one is for the people! I built it for my own model, and I don’t plan to maintain it forever. If someone wants to take it further, or Roboflow wants to fold it into the Active Learning loop, please do! Issues and PRs welcome, especially YOLO testing. And if your model has its own rug, I want to hear what it is.
I’m @pnewell4 on X/Twitter