from_dict

from_dict(config, *, source=None, check_paths=True)

Validate a dict into a spec, raising ConfigError with every problem at once.

task is required. It was briefly defaulted to segmentation so that files written before detection existed kept working, and that default is gone: a configuration that does not say what it is asking for means whatever the version reading it decides, and more tasks are coming.

The default also cost the wrong person. A detection configuration with no task was validated as segmentation and reported classes and anchors_per_grid as extra fields, never naming the tag - precisely the confusion a discriminator exists to prevent.

Parameters

Name Type Description Default
config dict[str, Any] The configuration, with task, data and models at the top level. The keys are the ones written in the YAML, because this is what reads the YAML. required
source str | None A name for the configuration in error messages - a file path, usually. from_yaml passes the path; pass something when the dict came from somewhere a reader could go and look. None
check_paths bool Whether the paths in data must exist. True wherever a run is about to happen, so a typo is caught before anything is read; False to validate the shape of a configuration on a machine that does not hold the data - a test, a schema check, or a specification being written. True

Returns

Name Type Description
PlatypusSpec A SegmentationSpec or a DetectionSpec, whichever task names. Both are
PlatypusSpec PlatypusSpec, so anything needing only a name, a seed or a rank takes either.

Raises

Name Type Description
ConfigError With every problem listed rather than the first. A configuration with four mistakes should take one run to fix, not four.

spec = from_dict( … { … “task”: “semantic_segmentation”, … “data”: { … “train_path”: “train/”, … “validation_path”: “valid/”, … “colormap”: [[0, 0, 0], [255, 255, 255]], … }, … “models”: [ … {“name”: “unet”, “architecture”: “u_net”, “input_shape”: [256, 256]} … ], … }, … check_paths=False, … ) spec.task.value, spec.rank, len(spec.models) (‘semantic_segmentation’, 2, 1)

Defaults come from the engine, so a short configuration is a complete one:

spec.models[0].blocks, spec.models[0].filters, spec.models[0].loss.name (4, 16, ‘cce’)

A missing task is refused by name rather than guessed at:

from_dict({“data”: {}, “models”: []}, check_paths=False) Traceback (most recent call last): pyplatypus.errors.ConfigError: …