Visitar URL original
Omit `dataloader_kwargs` from `TrainSettingsConfig` if unset to ensure forward compatibility by deruyter92 · Pull Request #3576 · DeepLabCut/DeepLabCut · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions deeplabcut/core/config/base_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ def to_commented_map(self) -> CommentedMap:
dumped = self.to_dict(normalize=True)
data = CommentedMap()
for name, info in type(self).model_fields.items():
if name not in dumped: # excluded by a custom serializer
continue
extra = info.json_schema_extra
if isinstance(extra, dict) and (comment := extra.get("comment")):
data.yaml_set_comment_before_after_key(name, before=comment)
Expand Down
8 changes: 5 additions & 3 deletions deeplabcut/pose_estimation_pytorch/config/training.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from typing import Any

from pydantic import field_validator
from pydantic import Field, field_validator

from deeplabcut.core.config import DLCBaseConfig
from deeplabcut.core.config.validation import reject_reserved_keys
Expand All @@ -38,7 +38,8 @@ class TrainSettingsConfig(DLCBaseConfig):
dataloader_pin_memory: Whether to pin memory in data loader
dataloader_kwargs: Additional keyword arguments for the training
``torch.utils.data.DataLoader`` (e.g. ``persistent_workers``). Arguments
that DeepLabCut sets itself are reserved and cannot be given here.
that DeepLabCut sets itself are reserved and cannot be given here. Omitted
from the serialized config when empty.
display_iters: Display interval for training progress
epochs: Number of training epochs
seed: Random seed for reproducibility
Expand All @@ -48,7 +49,8 @@ class TrainSettingsConfig(DLCBaseConfig):
batch_size: int = 8
dataloader_workers: int = 0
dataloader_pin_memory: bool = False
dataloader_kwargs: dict[str, Any] | None = None
# Omitted when empty to keep saved configs loadable by older DeepLabCut versions
dataloader_kwargs: dict[str, Any] | None = Field(default=None, exclude_if=lambda v: not v)
display_iters: int = 500
epochs: int = 200
seed: int = 42
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dependencies = [
"pandas[hdf5,performance]>=2.2,<3",
"pillow>=7.1",
"pycocotools",
"pydantic>=2,<3",
"pydantic>=2.12,<3",
"pyyaml",
"ruamel-yaml>=0.15",
"scikit-image>=0.17",
Expand Down
10 changes: 10 additions & 0 deletions tests/pose_estimation_pytorch/config/test_train_settings_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,13 @@ def test_dataloader_kwargs_rejects_options_with_a_config_field(key: str, hint: s
def test_dataloader_kwargs_rejects_options_managed_by_deeplabcut(key: str) -> None:
with pytest.raises(ValidationError, match=f"dataloader_kwargs cannot include reserved options: '{key}'"):
TrainSettingsConfig.from_dict({"dataloader_kwargs": {key: False}})


@pytest.mark.parametrize("value", [None, {}])
def test_empty_dataloader_kwargs_is_omitted_when_saving(tmp_path, value) -> None:
cfg = TrainSettingsConfig(dataloader_kwargs=value)
assert "dataloader_kwargs" not in cfg.to_dict()
assert "dataloader_kwargs" not in cfg.to_commented_map()
cfg.to_yaml(tmp_path / "cfg.yaml")
assert "dataloader_kwargs" not in (tmp_path / "cfg.yaml").read_text()
assert TrainSettingsConfig.from_yaml(tmp_path / "cfg.yaml").dataloader_kwargs is None
Loading
Loading