How the model learns, and how to feed it well
What the app does now
The counter learns from your corrections: every photo you mark Done goes into a training set, and a new model version goes live only if it beats the one in use.
Erythrocytes are always counted by the original AviBloodCount model (Vogelbacher et al.), which is already good at them. Leukocytes come from your own model once one is in use; until then, from AviBloodCount too.
- Upload photos. AviBloodCount marks them.
- Check each one and press Done, with every leukocyte marked and typed.
- After about 25–30 checked photos from a few slides, Train now on the Training tab. Your first own version, v1, goes into use only if it finds and types leukocytes better than AviBloodCount did on those photos.
- From then on, new photos are pre-marked by your model; checking them and training again improves it. Each new version must beat the one in use.
Training photos holds the upload box and a list with one line per photo: tap a column to sort, filter by status, slide and sample, search, and tap a line for its counts and buttons. Check › on a line opens that photo for checking, and Done — next then goes on through the list as filtered and sorted; Check these one by one starts at its first unchecked photo. In the correction view, ‹ and › step to the previous or next photo without marking it Done. A checked photo shows only your marks and counts. Try the model takes photos that only the models count, kept out of the training photos, samples, CSV and training: each shows the original Marburg model's marks, the model in use's, and your check if it is a photo you have checked, side by side as pictures of the same field. To training photos moves one to the list to check. Samples adds up photos that share a sample name. Model holds the model card. A bar at the top of every page shows what is going on: uploading 120 of 400, counting 5 of 15 with the time left, or a training run with its step and finish time.
What happens inside
Three models work on every photo: one for erythrocytes, two for leukocytes. Only the two leukocyte models learn from you.
When you upload a photo
- Erythrocytes: the original AviBloodCount model (from the University of Marburg) finds them. It shrinks the photo to the scale it was trained on and marks every red cell it is sure of.
- Leukocytes, step 1, the finder: a small detector looks at the whole photo, shrunk to 640 pixels, and marks everything that might be a leukocyte. It only answers "leukocyte here, how sure", not which type.
- Leukocytes, step 2, the typer: each find is cut out of the full-size photo and shown to a second model, which decides heterophil, lymphocyte, eosinophil, … or "not a leukocyte". It needs the full size because heterophils and eosinophils differ by the shape of their granules, which shrinking erases.
- A find is counted when the finder is fairly sure and the typer doesn't veto it. Fainter finds are shown dashed, as a hint for you to decide; they are not counted until you do. A type the typer is unsure of gets a ?.
Your corrections teach the two models: a mark you add teaches the finder what it missed (leukocyte, erythrocyte or thrombocyte), a leukocyte type you change teaches the typer, a mark you remove teaches the typer what to veto.
Planned runs
On the Training tab, Planned runs lines up trainings one after another, each with its own settings: a normal training or a freeze run, its number of seeds, and either "when the trainer is free" or "not before" a date and time. When one ends, the next starts within 10 minutes, also at night. They run strictly in order; Stop ends only the one running, and Remove takes one off the list. The times shown are estimates from the last training.
When it trains
A training is a fair exam first, and only then a new model:
- Five practice rounds. The photos are split into five parts, by slide once there are five or more slides. Each round, the models learn from four parts and are then tested on the fifth, which they never saw. After five rounds every photo has been tested once by a model that didn't learn from it. These are the "test 1 of 5" … steps on the Training tab.
- The real model. It learns from all photos (from 60 photos on, one fifth always stays out as the test instead). Each model goes through the photos many times over: 60 rounds for the finder, 25 for the typer. Every training starts again from the same general-purpose starting point (models pretrained on everyday photos), not from the previous version: mistakes can't pile up from version to version, and any version can be rebuilt from the photos it learned from. Training is reproducible: the same photos on the same machine give the same model (see Seeds and the freeze run).
- The comparison. The new version and the one in use are both scored on the same photos that neither of them learned from. Only if the new one scores higher does it go into use; otherwise it is kept, unused.
- Recounting. If it went into use, photos you haven't checked yet are counted again with it. Photos you checked keep your corrections.
The score is F1, and a leukocyte only counts as right when it is found and given your type. That leukocyte score decides whether a new version goes into use. Erythrocytes and thrombocytes get their own F1 beside it, and the erythrocytes are compared with AviBloodCount's model on the photos it pre-marked.
From 17 October 2026 the finder learns all three kinds of cell from your marks. AviBloodCount's model (built on detectron2) is never retrained; it only pre-marks new photos for you to correct, and counts until a version of ours is in use.
Why these models
The erythrocyte model is from 2021 and runs on older software (detectron2). On the 60 photos you checked before the fresh start it agreed with you on about 98 % of erythrocytes: you kept 7,615 of its marks, added 165 it missed and removed or retyped about 125. Over 1530 photos, though, it called 660 lymphocytes erythrocytes, and it knows no thrombocytes; so our finder now learns all cells, and the release notes show both models' erythrocyte scores.
On leukocytes the same model found only 20 of 46 on your first photos. That is why the app has its own two leukocyte models, built on current tools (YOLO11 and ResNet18), small enough to train in under an hour on this machine's graphics card. Today, what limits them is not the type of model but how many leukocytes they have seen: about 200 in the first round, and only 1 monocyte. More checked photos from more slides will help far more than a bigger model.
Why slides matter
A model only learns what it is shown. In the first round, before the fresh start, v1 learned from 25 photos of one kind of slide and found 0 of 31 leukocytes on the first photos of a new slide.
The first 25 photos were sparse, with about 68 erythrocytes per photo. The new slide's photos (1.1b to 2.3b) are crowded, with about 183 erythrocytes per photo, and paler. To a person a leukocyte is obviously still a leukocyte. To the model, which has never seen a crowded field, it is not.
Slides will keep differing in density, cell size and colour (stain batch, smear thickness, camera, light). So the question that matters is not "does it work on the slides it learned from?" but "does it work on a slide it has never seen?" Two things answer it: training on many different slides, and testing on slides kept out of training.
The fix was showing it the new slide. v3 learned from some "b" photos and was then tested on 7 others that neither v3 nor v2 had seen: v3 found 31 of 35 leukocytes and typed all 31 right, with 12 false marks; v2 found none.
How to collect and check photos
Six habits give the model the most to learn from per photo checked.
- Mix slides early. Five photos from each of ten slides teach more than fifty photos from one slide. Every new slide shows new colours, densities and cell sizes.
- Record which slide each photo is from. Without it, testing cannot keep whole slides out, and the scores look better than real use. Type it in the Slide box when uploading, or press Set slide on a photo. For many photos at once: the No slide filter, a search, Select all, then Set slide.
- Keep a few slides aside as test slides. Check them like any other, but never train on them, so every model version is measured on the same unseen slides. Tick them on the Model card under Test slides, before training (see If you want to publish).
- Done means every leukocyte is marked. A leukocyte left unmarked on a Done photo teaches the model "this is not a leukocyte".
- Mark thrombocytes with T. They are probably what the model mistakes for leukocytes most often, and each one teaches it the difference.
- Collect rare types on purpose. The model needs about 10 marked eosinophils, monocytes or basophils before it can learn that type at all. When one turns up, photograph that field.
Reading the Leukocyte model card
The card is on the Model tab. Every number on it compares a model with the leukocytes you marked, and only on photos that model did not learn from. A new version is compared with the one in use on the same photos, ones neither of them learned from.
| Column | Means |
|---|---|
| Found | Leukocytes you marked that the model also marked |
| Right | Found and given your type; the % is of all the leukocytes you marked |
| Missed | You marked it, the model did not |
| False | The model marked something you removed |
| Row | Measured on |
|---|---|
| vN vs the one in use | The same photos, ones neither version learned from: this comparison decides whether a new version goes into use |
| vN in use | New photos it pre-marked after going live, which you then checked: the most honest score, because they are your real work |
| vN, its whole test | Your earlier photos held out from its training (under 60 photos, each photo is scored by a model trained without it) |
| Original | The photos the original AviBloodCount model pre-marked |
Training happens only when you start it on the Training tab, or at the times you set there (see When to train). While it runs, the bar at the top of every page says so, with the step and when it should be done. It trains on the graphics card, about 3–5 times faster than before: well under an hour for 100 photos, about 2 hours at 400. Photos uploaded meanwhile are counted a little slower.
A new version replaces the one in use only if it scores better, so pressing Done can never make the counter worse.
What to study
Six ideas explain almost everything above; each is a common term in machine-learning textbooks and courses.
| Term | In one line | Why it matters here |
|---|---|---|
| Training / validation / test split | Learn on one set, tune on a second, judge once on a third that was never used | Test slides must stay out of training, or the score flatters the model |
| Generalisation and domain shift | How well a model does on data unlike what it learned from | A new slide is a shift; v1's 0 of 31 is a textbook case |
| Cross-validation (grouped) | Train k times, each time testing on a different part; "grouped" keeps a whole group (a slide) on one side | What the trainer does under 60 photos; from 60 it holds a fixed part out. It should group by slide |
| Class imbalance | Some classes are far rarer than others | Eosinophils at 0–4 % need deliberate collecting and extra weight |
| Data augmentation | Showing altered copies (rotated, recoloured, rescaled) to cover variation | Helps with stain and size differences between slides, but no substitute for real slides |
| Precision, recall, F1 | Share of marks that are right; share of cells found; their balance | The card's Found, Missed and False; the trainer compares versions by F1 |
If you want to publish
The way the app learns is sound for building a good counter: it tests only on photos a model never saw, by slide, and a new version goes into use only if it does better. Numbers for a paper need five more things.
- Pre-marks pull your judgement. Accepting a wrong mark is easier than noticing a missing one (automation bias). Scan every photo for unmarked leukocytes. For the test photos, the cleanest is to mark them from scratch, without the model's marks.
- Keep whole slides, or better whole birds, as the test. Photos from the same slide or the same bird look alike, so a test on them flatters the model. Give every photo its slide; put the bird in the slide name or the sample field. Decide the test slides before training and tick them on the Model card (Test slides): their photos are then never learned from, and every new version is scored on them in its own table, On the test slides. That score doesn't decide which version is used, so it stays unbiased. Untick a slide and its photos are learned from again at the next training.
- A second person. With one annotator, your labels are the truth by definition. Let a second person type the cells on a subset, and report how often you two agree (inter-rater agreement, Cohen's kappa). The model can't be expected to agree with you more than another expert does.
- Measure what you report. The biological result is the count per sample, for example the heterophil:lymphocyte ratio, not F1 per cell. Compare the app's ratio with your own manual count on held-out samples (correlation, and a Bland–Altman plot for the bias).
- Choosing the best of many versions on the same test flatters the winner a little. The honest number is a version's score on new photos it pre-marked after it went live: the vN in use row on the Model card. For a paper, freeze one version and test it once on the test slides: the freeze run below does exactly that.
Also state how the erythrocytes were counted: by AviBloodCount (Vogelbacher et al.), unchanged. On the 60 photos checked before the fresh start it agreed with your corrections on about 98 % of erythrocytes.
Terms to look up: human-in-the-loop annotation, automation bias, grouped cross-validation, inter-rater reliability, Bland–Altman analysis.
Seeds and the freeze run
A model starts from random numbers (its seed), and the photos are shown in a random order. Two trainings on the same photos with different seeds give slightly different models and scores. Each training here uses a fixed seed and reproducible calculations, so the same photos on the same machine give the same model. One seed could still be lucky or unlucky, though.
- Seeds (Training tab, under When to train): with 3 or 5, the whole training, test rounds included, is repeated with that many seeds. The score is then shown as average ± spread (mean ± SD) on the Model card and in Last trainings. A small spread means the result doesn't depend on luck. The model used is the first seed's, and the first seed's score decides whether it goes into use, as with one seed. It takes 3 or 5 times as long.
- Freeze run (Training tab, For the paper): when you have checked the photos you want to learn from
and ticked the test slides, start one. It trains with 5 seeds (3 or 10 if you choose), puts the new version in use
and keeps it there, ❄ frozen, until you press Unfreeze. Then every photo for the paper is counted by
the same model. Meanwhile trainings still run and are kept, but not used, and Use this is locked.
The frozen version's files (Model card, Switch version → files) include a
meta.jsonwith the software versions, settings, graphics card, seeds and the list of photos it learned from and was tested on: what a methods section needs.
For the paper, report the frozen version's score on the test slides as mean ± SD over the seeds, and say that the numbers come from that one version.
Slides in the app
Both changes planned here are in place since 7 October:
- A slide field on every photo, settable on photos already uploaded too. It goes with the photo into the training set, the CSV and the search, and comes back when a photo is uploaded again.
- Testing by slide: once photos come from 5 or more slides, a slide's photos are always together, all in training or all in the test. Photos without a slide fall back to a guess from the file name. A new version is compared with the one in use on the same unseen photos.
Keep checking photos as you do, and give each one its slide. Every Done photo is kept, backed up nightly, and used in the next training.
When to train: the Training tab
Nothing trains on its own. The Training tab has the card for this app's counter.
- Train now starts a training within about 10 minutes: the trainer looks for work every 10 minutes. The card then shows the step or round it is on, whether it uses the graphics card, and when it should be done.
- Stop ends a training. Nothing changes: the model in use stays, and what the stopped run learned is thrown away. Before it has started, the button says Cancel.
- When to train: Only when I press Train now, Every day, or On these days (tap the days), at a time you choose. Press Save. A time already past today counts from tomorrow.
- Skip a scheduled time when there's nothing new: with this ticked, a scheduled training is left out if you haven't checked a photo since the last one.
- Seeds: 1, 3 or 5; see Seeds and the freeze run. Saved with Save.
- For the paper: the freeze run and Unfreeze; same section.
- Last trainings lists each run: when, how long, on which device, and what came of it.
Only one training uses the graphics card at a time: a shared-model training (next chapter) running at the same time waits up to 30 minutes and then trains on the CPU, more slowly. Photos uploaded while a training has the card are counted on the CPU too.
The shared system: CVAT and MLflow
Optional: for your own work you don't need this chapter. Checking photos here and the Bird's counter card on the Training tab are all the counter needs.
For labelling and training together with other labs there are two standard tools next to this app. CVAT is where photos are labelled; MLflow keeps every training run and the resulting model versions. This app stays your daily counter; the shared model doesn't change its counts.
| Tool | Address | What for |
|---|---|---|
| CVAT | cvat.peluan.com | Upload photos, let the model pre-label them, correct the boxes |
| MLflow | mlflow.peluan.com | See how each training scored; choose which version pre-labels in CVAT |
The photos checked here before the fresh start are in CVAT: project House sparrow blood smears, 60 photos in 6 tasks.
1. Sign in and choose the organisation
- Open cvat.peluan.com and sign in with your user name or e-mail. Change the password first: your name at the top right → Change password. MLflow has a separate login of its own; changing one doesn't change the other.
- Your name at the top right → Organization → house-sparrow. CVAT starts in your personal workspace, which is empty; a project link opened from there says "permission denied". CVAT remembers the choice.
2. Add photos: one task per slide
- Projects → House sparrow blood smears → + → Create a new task.
- Name it after the slide (for example Slide 7). The labels come from the project.
- Select files: drop that slide's photos, then Submit & Open.
Keep one slide per task. Testing holds out whole tasks (always the same one in five), so a slide is either learned from or tested on, never both — the same reason as in Why slides matter.
3. Let the model pre-label
- On the task's page, Actions → Automatic annotation.
- Model: blood-cells. The labels match by name. Press Annotate; a bar shows the progress, a few seconds per photo.
4. Correct and finish
- Open the task's job. Each cell is a box; the list on the right shows them all.
- Wrong type: select the box and change its label on the right. Wrong place or size: drag the box or its corners. Not a cell: select it and press Delete. Missing cell: the rectangle tool on the left, pick the label, then two clicks for opposite corners.
- Save often (Ctrl+S). When the whole job is checked: Menu → Finish the job.
5. Train, and read the result
- The shared model's training is started by whoever runs the server (it's no longer on the Training tab): ask for one. It learns from every task of the project. On the graphics card a training takes about 50 minutes for 60 photos; on the CPU about 3½ hours.
- When it ends, the run is in MLflow with
wbc_f1, the same score as this app's model card (F1 on the held-out slides). - In MLflow: Experiments → blood-cells lists every run. Useful columns:
wbc_f1(the score),wbc_found,wbc_missed,wbc_false, andmetrics/mAP50(B)(boxes for all cell types, erythrocytes included).
6. Choose which version pre-labels
- MLflow → Models → blood-cells → the version you want → Aliases → add production. Moving the alias from another version is the same.
- Within a minute, CVAT's Automatic annotation uses it. Without any alias, the newest version is used.
Other labs get their own organisation in CVAT and see only their own projects; ask Lukas for an account.