๐ Chicken Counting
Count chickens via density maps โ with a frozen encoder you're not allowed to touch.
๐The task, in plain English
Count the chickens in farm images. The organizers hand you a frozen pretrained image encoder โ you may not fine-tune it. Your job is to design and train the decoder that turns its features into a count (via a density map that sums to the number of chickens).
| Input | Images โ frozen encoder features |
|---|---|
| Output | Chicken count per image (via predicted density map) |
| Really tests | PyTorch model surgery: reading someone else's module, matching shapes, building your own head |
๐งThe baseline you're given
A trivial decoder (e.g., global pooling + linear regression on the count). Limitations: throwing away spatial information, no density-map supervision, weak on crowded images.
๐Baseline vs. solution
- Pool everything โ regress one number
- No spatial supervision
- Crowded scenes fail
- Density-map decoder: a few upsampling conv layers producing a heat map whose SUM is the count โ supervise with per-pixel targets built from dot annotations
- Count =
density.sum(); loss = MSE on maps (optionally + count loss) - Freeze means freeze:
requires_grad=Falseand encoder in.eval()โ verify with a param count - Precompute encoder features ONCE (encoder is frozen!) โ decoder training becomes lightning fast
๐งExplain it like I'm brand new
Why density maps? Counting by detecting each chicken fails when they overlap. Instead, predict a "chicken heat" image โ each bird contributes a small blob summing to 1 โ and integrate the heat. 30 blobs โ sum โ 30.
The precompute trick is the big transferable lesson: if a component is frozen, its outputs never change, so compute them once and train only the small part on top. Turns hours into minutes โ and reappears everywhere (John Wilkins' precomputed table is the same idea in disguise).
๐ฌThe Gemma 4 playthrough (2000-token limit)
PyTorch: frozen encoder `enc` maps (B,3,224,224) -> (B,512,14,14). Write ONLY code to iterate a DataLoader, run enc under torch.no_grad(), and save features+targets to features.pt. Then a TensorDataset loading them. Max 25 lines.
Design ONLY an nn.Module decoder: input (B,512,14,14), output a (B,1,56,56) non-negative density map. Two ConvTranspose2d upsampling steps + final 1x1 conv + ReLU. Code only, max 25 lines.
๐ฏTakeaways & what Day 1 might do with this
- Pattern family: frozen encoder + trainable head โ the IOAI yearly ritual (2026 Night Watch = same skeleton).
- Overfit-10-samples is the fastest wiring test in deep learning. Keep it in your ritual bank.