Releases: KamitaniLab/bdpy
BdPy 0.26 Release
bdpy 0.26
Highlights
- Supports Python 3.6 – 3.11.
- This is the last release to support Python 3.6 – 3.9.
Future releases will follow the upstream Python support schedule. - Starting with this version, we use
uvfor development, which ensures that the lock file generated frompyproject.tomlis resolved as a universal lock file. - This release includes 4 breaking changes — see the Breaking Changes section for migration guidance.
Breaking Changes
AffineDomain removed in favor of StandardizedDomain / ScaledDomain (#100)
AffineDomain now raises RuntimeError immediately upon instantiation. Use StandardizedDomain and ScaledDomain from bdpy.dl.torch.domain.image_domain instead.
Note: The new classes have different semantics from
AffineDomain. A direct parameter swap is not always correct. Refer to the example andBdPyVGGDomaininbdpy/dl/torch/domain/image_domain.pyas a concrete migration reference.
Before:
from bdpy.dl.torch.domain.image_domain import AffineDomain
# AffineDomain.receive: images_in_domain = images_in_[0,1] * scale - center
domain = AffineDomain(center=mean_pixels, scale=255.)After:
from bdpy.dl.torch.domain.image_domain import (
ScaledDomain, StandardizedDomain, ComposedDomain,
)
# Equivalent: first scale to [0, 255], then subtract mean
domain = ComposedDomain([
ScaledDomain(255.),
StandardizedDomain(center=mean_pixels, scale=1.),
])ImageDataset now returns CHW float64 arrays (#105)
ImageDataset.__getitem__ previously returned images in HWC (uint8) format. It now returns CHW (float64) arrays with pixel values normalized to [0, 1].
Additionally, when stimulus_names=None, names are now returned in alphabetically sorted (deterministic) order.
Before:
dataset = ImageDataset(root_path="images/")
img, name = dataset[0]
# img.shape == (H, W, 3), dtype=uint8, values in [0, 255]
# Typical downstream pre-processing:
img_chw = img.transpose(2, 0, 1).astype(float) / 255.0After:
dataset = ImageDataset(root_path="images/")
img, name = dataset[0]
# img.shape == (3, H, W), dtype=float64, values in [0.0, 1.0]
# No manual transposition or normalization needed:
img_chw = img # ready to useIf your downstream code was manually transposing / normalizing, remove those operations.
FeatureInversionTask takes optimizer/scheduler factories (#101)
The constructor arguments optimizer (a torch.optim.Optimizer instance) and scheduler (a LRScheduler instance) have been replaced by optimizer_factory and scheduler_factory (callables). The optimizer and scheduler are now recreated on every reset_states() call, fixing incorrect optimizer state accumulation across multiple task runs.
Before:
from bdpy.recon.torch.task import FeatureInversionTask
optimizer = torch.optim.Adam(
list(generator.parameters()) + list(latent.parameters()), lr=1e-3
)
task = FeatureInversionTask(
encoder, generator, latent, critic,
optimizer=optimizer,
num_iterations=200,
)After:
from bdpy.recon.torch.task import FeatureInversionTask
from bdpy.recon.torch.modules import build_optimizer_factory
optimizer_factory = build_optimizer_factory(torch.optim.Adam, lr=1e-3)
task = FeatureInversionTask(
encoder, generator, latent, critic,
optimizer_factory=optimizer_factory,
num_iterations=200,
)For schedulers, use build_scheduler_factory in the same way:
from bdpy.recon.torch.modules import build_scheduler_factory
from torch.optim.lr_scheduler import StepLR
scheduler_factory = build_scheduler_factory(StepLR, step_size=100, gamma=0.1)
task = FeatureInversionTask(
..., optimizer_factory=optimizer_factory, scheduler_factory=scheduler_factory,
)model_factory key renamed: "referencenet" → "reference_net" (#98)
Before:
model = model_factory("referencenet")After:
model = model_factory("reference_net")New Features
- Added
StandardizedDomainandScaledDomaintobdpy.dl.torch.domain.image_domain
as the recommended replacements for the removedAffineDomain. (#100) - Added
build_optimizer_factoryandbuild_scheduler_factoryfactory helpers to
bdpy.recon.torch.modules.optimizer(importable frombdpy.recon.torch.modules). (#101)
Bug Fixes
- Fixed missing
typing_extensionsimport in the callback module. (#99) ImageDataset.stimulus_namesnow returns names in alphabetically sorted, deterministic order. (#105)bdpy/mri/roi.py: ROI file glob results are now sorted for deterministic ordering. (14a369d)bdpy/ml/learning.py: Addedtyping_extensionsfallback forTypedDict/Protocol
on Python < 3.8. (#112)
CI / Build
- Updated all GitHub Actions to latest versions; migrated from the archived
chartboost/ruff-actiontoastral-sh/ruff-action@v4. (#118) - Migrated Ruff lint config to the new
[tool.ruff.lint]format; enabledI(import sort)
and NumPy docstring convention rules. (#109) - Separated Python 3.6 / 3.7 CI into dedicated jobs in
test_old.ymlon the
maintenance/legacybranch. (#112) - Pinned
pytest-github-actions-annotate-failures==0.2.0to fix intermittent CI failures. (#103) - Migrated dev-dependency declarations from
[tool.rye]to PEP 735[dependency-groups]
with[tool.uv]; Starting with this version, we useuvfor development, which ensures that the lock file generated frompyproject.tomlis resolved as a universal lock file. (#112)
Contributors
Thanks to everyone who contributed to this release!
- @ganow — #99, #100, #101, #103, #105, #109, #118
- @micchu — #98, 14a369d
- @HirokiYasuda03 — #112 (first-time contributor)
Full Changelog: 0.25.1...0.26