This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
Hawkesbury, Ontario, is a town of about ten thousand people on the Ottawa River. Around it, iNaturalist holds about 3,000 research-grade records in total. Across every October on record, the most-logged species within 10 km of town was seen four times.
That number is the whole problem. The obvious way to get someone outside in October is to hand them a list of what people saw near them last October. In Montreal that list writes itself. In Hawkesbury it is whatever one or two people happened to photograph, and you cannot rank anything from four sightings.
Nature Bingo is a card of the 16 things most likely to be out near your town this October. You open it, put the phone away, and go find them. When you find one, you tap its square and it gets dabbed with ink and stamped with the time. You can also print it and leave the phone at home entirely. The card is the screen; the walk is the point.
The trick for small towns is that the card borrows from its neighbours. It is ranked by an open-weight model that learned ten years of Octobers across 48 towns between Ottawa and Montreal, so a quiet town can lean on what the whole region knows.
Demo
Try it: naturebingo.vercel.app (pick any of the 48 towns, or keep Hawkesbury).
There is also a 51-second version.
Code
JonathanSolvesProblems
/
nature-bingo
A bingo card of the 16 things most likely out this October near your town. TabPFN, an open-weight model, ranked on a laptop GPU from iNaturalist records.
Nature Bingo
A bingo card of the 16 things most likely to be out near your town this October. Open it, put the phone away, and go find them. Tap a square when you do, or print the card.
Open the app · Demo video · Short · Write-up · My walk on iNaturalist
Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 1: Touch Grass.
Why small towns
A "what was seen near here last October" list works in a city. It does not work in a small town. Around Hawkesbury, Ontario, iNaturalist has about 3,000 research-grade records in total, and the most-logged species across every October on record has four sightings.
So the card borrows from the neighbours. TabPFN, an open-weight tabular model, learns from ten years of Octobers (2016 to 2025) across 48 towns between Ottawa and Montreal. For each candidate species in each town it…
Every number in this post is in the repo: the backtest in results/backtest.json, the split by town history in results/backtest_bands.json, and the walk in data/walks.json.
How I Built It
The data. For 48 small towns between Ottawa and Montreal, I pulled iNaturalist research-grade species counts for every year from 2016 to 2025: within 10 km of the town in October, within 10 km in any month, and within 50 km in October. For each town and year, the 300 species most logged across the region become candidates, about 86,000 training rows of (town, year, species), each described only by what happened in earlier years: how often it was logged here, how often across the region, in how many separate years, how seasonal it is locally, and how much anyone was out logging at all.
The model. TabPFN is an open-weight foundation model for tables. Instead of training a model on my data, it reads a sample of labelled rows as context and predicts the rest in one pass, which suits a problem where every town is small and the useful signal is in how towns resemble each other. It runs locally on my laptop's RTX 5060. Making Hawkesbury's card takes 19 seconds, and nothing goes to a model API.
The test. I did not want to grade this against my own idea of what should be out, so I let the public grade it. I trained on target years up to 2024, held October 2025 out entirely, made every town's card blind, and counted how many of its 16 squares somebody actually photographed and logged on iNaturalist that month. Four methods, same towns, same month:
| Method | Squares photographed, of 16 |
|---|---|
| TabPFN | 5.02 |
| The town's own past Octobers | 4.44 |
| Gradient boosting (scikit-learn, same features) | 4.33 |
| Regional most-seen | 3.65 |
Town by town against the town's own past Octobers, TabPFN's card was better in 23 towns, the same in 14 and worse in 11.
What it does not do. I built this for small towns, and in the 16 towns with the least October history it does not win. Gradient boosting found 2.19 photographed squares there and TabPFN 1.88, both ahead of last October's list at 1.19. Hawkesbury, the town I walked, is one of the places TabPFN lost: 3 squares against 6. Where the data is thinnest, no method finds more than about 2 of 16, because almost nobody is out there taking pictures. The grader also has a bias I cannot remove: it rewards guessing what people photograph, which leans towards big, common, daytime things near paths.
The card says what it cannot know. Under every card, in the product rather than a README, it states its own score: "When I ran the same method on last October, people photographed 3 of the 16 things on this town's card. The other 13 went unphotographed, which is not the same as absent." Every photo on the card is an openly licensed iNaturalist photo, credited by name.
Then I took it outside. The brief asked us to use it and say how it went. On Tuesday 6 October, from 10:18 to 10:54, I walked Hawkesbury's card at Confederation Park, under the big Franco-Ontarian flag. My phone stayed in my pocket except to tap a square, take a photo, and fly the drone for the video.
In about half an hour I confirmed 2 of the 16: dozens of Canada geese on the lawn at 10:52, and a mallard drake in the shallows a minute later. The ring-billed gulls on the shore are marked probable, not confirmed, because the ring on the bill is not visible in my photos. I also found things the card did not have: a huge old cottonwood, a spruce, and a few large white geese mixed in with the Canada geese.
I posted the photos to iNaturalist that afternoon. Within hours, the goose and the mallard reached Research Grade, identified independently by another observer. The gull is still waiting for a second opinion, which is exactly what "probable" meant. So the two squares I ticked were not graded by me or by the model, but by another person looking at my photos.
Two of sixteen is not a great score, and it is one morning, not a measurement. For scale: across all of last October, everyone on iNaturalist together photographed 3 of the squares on the card the model made for this town. One person in 36 minutes found 2.
Why Does Open Innovation Matter?
A card for every small town has to be free to make. The backtest scored 14,400 candidate rows, and every card scores 300 species per town. Locally that cost about eleven minutes of laptop GPU for the whole test and nothing per card. Behind a metered API, the experiment that tells me whether the card works at all would have been the expensive part, and the cheap move would have been to skip it.
Open let me test the model against plain alternatives on equal terms. Because the weights run on my own machine, I could run TabPFN and scikit-learn's gradient boosting on the same rows, the same features and the same held-out month, and report where the open-weight model loses as well as where it wins. That table is only possible when I control both sides.
Open data made the grading honest. The training data and the answer key are both public iNaturalist records under open licences. Anyone can re-pull October 2025 and check my 23, 14 and 11. And because iNaturalist is open, the loop closes: my three observations are now part of the data the next card learns from.
The ranking never touches someone else's server. The model sees counts per town, not where you are. The only outside calls are to iNaturalist's public API for those counts.
To be fair about the edges: TabPFN's weights are free but gated. You accept Prior Labs' license once and get a token before they download, and the license is theirs, not MIT. And the 8 GB on my laptop GPU meant TabPFN saw a 4,000-row sample of the 85,974 training rows, not all of them.
Prize Categories
Best Use of TabPFN




Top comments (0)