Repository navigation
Description
Describe the bug
Second-pass umbrella from the same full-package review as #409–#424: remaining verified findings that didn't fit the earlier issues.
TaskModel.train_featuresis never initialized in__init__(deeptab/training/lightning_module.py— only assigned insetup(stage="fit")at line 284). The guards at lines 449, 504, 538 read... and self.train_features is not None, which presumes aNonedefault — instead they raiseAttributeError: 'TaskModel' object has no attribute 'train_features'on any TabR/ModernNCA TaskModel that runsvalidate/predictwithout a prior in-processfit(e.g. restored from a checkpoint). Fix:self.train_features = self.train_targets = Nonein__init__._validate_fit_inputschecks phantom distribution-family keys (deeptab/models/base.py:99-103): it gates on"inversegaussian"and"binomial", neither of which exists inDISTRIBUTION_REGISTRY(deeptab/distributions/registry.py:19-34— the real key is"inversegamma", and there is no binomial family). Consequently the strictly-positive target check never fires forinversegamma(orlognormal, which also needs it), and the binary check is dead code.- Generic-family CRPS fallback derives sigma from the test labels (
deeptab/metrics/distributional.py:231):sig=np.std(y_true - loc)uses the ground truth to set the predictive spread, making scores incomparable across test sets; with perfect predictionssig=0degenerates insideproperscoring. The fallback should use a model-predicted scale or be explicit (e.g. report MAE like the ImportError branch). sparsemaxmutates its input in place (deeptab/nn/blocks/common.py:86,input_ -= max_val). Via ODST (deeptab/nn/blocks/node.py:321-322) the input is thefeature_selection_logitsParameter itself, so the stored parameter values get shifted by-maxon first use — output is shift-invariant so predictions stay correct, but weight decay operates on corrupted values and checkpoints differ from what was trained. Fix:input_ = input_ - max_val.MambaOriginal.allocate_inference_cacheiterates a nonexistent attribute (deeptab/nn/blocks/mamba.py:729-733): loopsself.layers, but the class defines onlyfwd_layers/bckwd_layers→ guaranteedAttributeErrorif ever called.- TabTransformer crashes on datasets with zero numerical features (
deeptab/architectures/tabtransformer.py:135):torch.cat(num_features, dim=1)on an empty list raisesRuntimeError: torch.cat(): expected a non-empty list of Tensors— an all-categorical dataset (TabTransformer's home turf) needs a guard. fit(rebuild=False)silently discards loss/sampler settings:SklearnBaseClassifier.fitrecomputesloss_fct/samplerfromclass_weight/balanced_sampler/sample_weight(classifier_base.py:297-299), but the fit mixin passes them only into_build_model(...), which is skipped whenrebuild=False(_mixins/fit.py:445-469) — the freshly requested class weights/sampling are ignored without warning.
To Reproduce
Each item lists its file/line; representative snippets:
# (1)
from deeptab.training.lightning_module import TaskModel
# restore a TabR TaskModel from checkpoint, then trainer.validate(...) -> AttributeError
# (2)
from deeptab.distributions.registry import DISTRIBUTION_REGISTRY
print("inversegaussian" in DISTRIBUTION_REGISTRY, "binomial" in DISTRIBUTION_REGISTRY) # False False
# (5)
from deeptab.nn.blocks.mamba import MambaOriginal # has fwd_layers/bckwd_layers, no .layersExpected behavior
Guards should compare against initialized attributes; validation key sets should match the registry; metrics must not read the ground truth to parameterize themselves; functional ops must not mutate parameters in place; public methods should reference existing attributes; architectures should validate unsupported feature combinations at build time; ignored fit arguments should raise or warn.
Screenshots
n/a
Desktop (please complete the following information):
- OS: macOS (Darwin 25.5.0, arm64)
- Python version: 3.11.15
- deeptab Version: 2.0.0 (main @ 4e6a359)
Additional context
Doc-only nits noticed on the way (not bugs, listing for a docs sweep rather than separate tickets): MLPConfig docstring documents a nonexistent skip_layers field; several config docstrings contain "default=field(default_factory=list" copy-paste artifacts; NormalDistribution's second parameter is named "variance" but is used as the std/scale in dist.Normal(mean, variance) — consistent internally, but the name invites mis-setting by users.
Activity
mkumar73 commentedon Oct 9, 2026
We have fixed all seven findings in issue #426 and updated the regression tests and documentation.
it will be shipped with `v2.1.0'
fix: correct model state, validation, scoring, and training behavior (#…