Make the background channel optional for classification#619
Open
aymuos15 wants to merge 14 commits into
Open
Conversation
Member
Contributor
Author
|
Ah thanks a lot! Will accordingly update the description then. |
Contributor
Author
…nal-352 # Conflicts: # cellfinder/core/classify/classify.py
for more information, see https://pre-commit.ci
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Closes #352
Summary
#352 asks for the background channel to be optional, so the classifier can run on the signal channel alone. This PR makes the whole classification path work with signal only:
background_array=Noneflows from the public API to a single-channel model, andcellfinder_trainbuilds a model matching the data's channel count.The data layer already supported this (
CuboidArrayDataset→num_channels=1, #493); this PR fills the plumbing around it: the entry points and model building that still assumed two channels. It is backend only, with no napari/GUI changes (see Follow-ups).Scope
Two-channel behaviour is unchanged, and detection is unaffected (it already runs on the signal channel only, so single-channel mode changes nothing there).
Single-channel model
The
resnet50_1chregistry slot is added as a placeholder (filename set, hashNone); it isn't downloadable yet. A following commit (hence the initial draft) will update it with the trained single-channel model once training is complete. A model/data channel mismatch already raises a clear error.Feasibility (preliminary)
Quick 1-ch vs 2-ch check on the standard cellfinder training data (
serial2p, 107,555 labelled cubes, the same set @IgorTatarnikov used), mimicking his #352 experiments (resnet9 / 2 epochs here; the faithful follow-up is a resnet50 matching his default 50-layer setup), held-out test set (10,756 cubes):The two initial epochs follow a similar loss/accuracy trend to his #352 curves.
What changed
Core API: accept a missing background
core/main.py:background_arrayis nowOptional(may beNone); docstring documents single-channel mode.core/classify/classify.py: thebackground_array.ndim != 3guard only fires when a background is actually provided.Build a model that matches the channels
core/classify/tools.py:get_modelgains anum_channelsargument and buildsshape=(50, 50, 20, num_channels). Defaults to2, so existing callers are unaffected.core/classify/classify.py: passes the dataset'snum_channelsintoget_model, then validates the built/loaded model's input channels match the data and raises a clearValueErroron mismatch.Training
core/train/train_yaml.py:run()derives the channel count from the data (len(filenames_train[0])) and builds the model to match. A YAML entry withbg_channel: -1already produces single-channel data; now the model is built to fit it. No new CLI flag needed.Model registry
core/download/download.py: registersresnet50_1ch(resnet50_1ch.h5, hashNone) inmodel_filenames/model_hashes/model_type.Tests
test_classify/test_tools.py:get_modelbuilds 1- and 2-channel models with the right input shape.test_classify/test_classify.py: a model whose channel count differs from the data raises a clearValueError.test_unit/test_main.py:main(background_array=None, ...)reaches detection.test_unit/test_download.py: registry dicts stay consistent andresnet50_1chis registered.test_integration/test_train.py+training_single_channel.yaml: training withbg_channel: -1runs and saves a model with 1 input channel.Testing
Verified locally (Python 3.11,
KERAS_BACKEND=torch):test_classifysuite: All pass.test_tools,test_main,test_download): pass.(…, 1)-channel model.ruff checkclean on all changed files.Follow-ups
napari/curation.py) demands both layers and writesbg_channel: 1, so single-channel training-data curation via the GUI isn't supported. The Python API andcellfinder_train(bg_channel: -1) do support single-channel.