Venn

Hot dog or not hot dog#

A local visual demo inspired by Silicon Valley. Supply your own photos; this sample downloads no food dataset. Training photos and local model state are git-ignored; the documentation screenshot below includes an illustrative burger photo.

Hot dog demo showing a Venn Decisions API prompt and hamburger response

The screenshot shows the Venn Decisions API request and response for a burger. No task-specific family was trained for this judgment.

Investigation: the screenshot exposes a dataset mistake. The demonstration used 40 photos per class from the D2L archive, whose negative images inspected here are bananas. A classifier fitted to hot dogs versus bananas does not learn the intended boundary between hot dogs and other foods. Its 20/20 result on similarly narrow test data was misleading. A seeded random run with 400 training and 200 test images reproduced the same confident burger mistake.

The screenshot shows a Venn Decisions API Choice request and response. The request sends the image, asks “Which food is pictured?”, and describes hot dog and hamburger options. The returned answer is hamburger at 78.17% confidence; the model is not calibrated. This is the trained generic Venn decision head working over Gemma's image embedding, with no task-specific family fitting.

The separate embedding comparison is also useful for understanding the result: the image is closer to the hamburger description (0.705) than the hot-dog description (0.674). Those cosine similarities are not the API's confidence scores. The earlier task-family mistake came from banana-only negatives.

Recorded result and investigation. Training images are not redistributed. Burger photo: Unsplash source, used under the Unsplash License. The original is 4338 × 3604 pixels, above Venn's image limits (at most 4 million pixels and 6 MB per image), so download the 1080-pixel-wide copy to try it yourself. Resize larger photos before sending them.

Setup#

Start with installation if Venn is not installed. Use getting started for a first download-free result before setting up the image reader.

Install .[embedding,dev] (family fitting needs scikit-learn) and run venn download-embedder. Create examples/hotdog/photos/ with this layout:

photos/
  train/hotdog/       at least five distinct photos; more is better
  train/not_hotdog/   other foods and tricky negatives
  test/hotdog/        unseen photos, not copies of training photos
  test/not_hotdog/    unseen negative photos
  demo/              unlabeled photos to judge on screen

From the repository root on Linux, run:

python examples/hotdog/hotdog.py --serve --device cpu
# Open http://127.0.0.1:8011

On Windows PowerShell:

.\.venv\Scripts\python.exe examples\hotdog\hotdog.py --serve --device cpu
# Open http://127.0.0.1:8011

Use --device cuda:0 on a supported CUDA installation; omit it to use CPU. --data selects another photo folder; --state selects another cache and saved-family folder. The default head is downloaded on startup; --model-dir uses existing assets. The pinned reader must already be downloaded. The web server binds only to localhost and has no authentication; do not expose it to a network.

What to show#

Train family first embeds labeled training photos with the frozen EmbeddingGemma reader, then fits a small linear Venn Choice family. It reports reader loading, image embedding, cache hits, and family fitting separately. Cross-validation uses training photos only. The family persists across restarts; judging does not retrain it.

Evaluate test folder reports correct/total on unseen labeled photos. Exact duplicate files and train/test overlap are rejected. Different crops of the same original should also be kept in one split by the person providing photos. A small test set is not a general accuracy claim.

Judge this photo shows the photo, verdict, probabilities, reader/cache time, and decision-only time. The reader uses CPU or GPU float32; the family scorer runs on CPU. A bare sausage can still fool this model: include such negatives in training, reserve others for testing, and show mistakes honestly. Probabilities may be uncalibrated.

For clean measurements, use a new --state folder (rather than deleting one) and run one device at a time. First-image timing includes cold reader loading reported separately. After reader warm-up, judge a new photo to measure fresh embedding; judge it again to measure cached-vector lookup. Neither is the same as decision-only latency. HTTP, browser rendering, downloads, and service startup are outside the displayed per-stage timers.

The same actions work without a browser:

.\.venv\Scripts\python.exe examples\hotdog\hotdog.py --action train --device cuda:0
.\.venv\Scripts\python.exe examples\hotdog\hotdog.py --action evaluate --device cuda:0
.\.venv\Scripts\python.exe examples\hotdog\hotdog.py --action judge --image lunch.jpg --device cuda:0

View this page on GitHub

On this page