ML Collections is a library of Python collections designed for ML usecases.
—
Core ConfigDict and FrozenConfigDict classes that provide the foundation of ML Collections. These classes offer dict-like structures with ML-specific enhancements including dot-based access, type safety, locking mechanisms, and serialization capabilities designed for machine learning experiment configurations.
Create mutable configuration dictionaries with optional type safety and initialization from existing dictionaries or keyword arguments.
class ConfigDict:
def __init__(
self,
initial_dictionary=None,
type_safe=True,
convert_dict=True,
*,
allow_dotted_keys=False,
sort_keys=True
):
"""
Create a new ConfigDict.
Args:
initial_dictionary (dict, optional): Initial values to populate the ConfigDict
type_safe (bool): Enable type safety enforcement (default: True)
convert_dict (bool): Convert nested dicts to ConfigDict (default: True)
allow_dotted_keys (bool): Allow keys with dots (default: False)
sort_keys (bool): Sort keys in string representation (default: True)
"""
@property
def is_type_safe(self) -> bool:
"""Returns True if type safe."""
@property
def allow_dotted_keys(self) -> bool:
"""Returns True if keys can contain dots."""
@property
def convert_dict(self) -> bool:
"""Returns True if auto-converting dicts to ConfigDict."""
@property
def is_locked(self) -> bool:
"""Returns True if object is locked."""
def create(**kwargs) -> ConfigDict:
"""
Factory function to create ConfigDict with keyword arguments.
Args:
**kwargs: Key-value pairs to initialize the ConfigDict
Returns:
ConfigDict: New ConfigDict instance with provided values
"""Usage example:
from ml_collections import ConfigDict
from ml_collections.config_dict import create
# Create empty ConfigDict
config = ConfigDict()
# Create from dictionary
config = ConfigDict({'learning_rate': 0.001, 'batch_size': 32})
# Create using factory function
config = create(
model='resnet50',
optimizer='adam',
learning_rate=0.001
)Access and modify configuration fields using both dot notation and dictionary-style access with automatic type checking.
# ConfigDict supports both dot notation and dictionary access
config.field_name = value # Dot notation assignment
value = config.field_name # Dot notation access
config['field_name'] = value # Dictionary-style assignment
value = config['field_name'] # Dictionary-style accessPrevent accidental configuration changes during execution while maintaining the ability to modify existing field values.
def lock(self) -> ConfigDict:
"""
Lock the ConfigDict to prevent addition or deletion of fields.
Existing field values can still be modified.
Returns:
ConfigDict: Returns self for method chaining
"""
def unlock(self) -> None:
"""
Unlock the ConfigDict to allow addition and deletion of fields.
"""
def unlocked(self):
"""
Context manager for temporarily unlocking the ConfigDict.
Returns:
Context manager that unlocks on entry and re-locks on exit
"""Usage example:
config = ConfigDict({'learning_rate': 0.001})
config.lock()
# This works - modifying existing field
config.learning_rate = 0.01
# This raises MutabilityError - adding new field to locked ConfigDict
try:
config.new_field = 'value'
except MutabilityError:
print("Cannot add new fields to locked ConfigDict")
# Temporarily unlock for modifications
with config.unlocked():
config.new_field = 'value' # This worksGet references to fields for creating dynamic relationships and lazy computation chains.
def get_ref(self, key: str) -> FieldReference:
"""
Get a FieldReference to a field for lazy computation.
Args:
key (str): Field name to reference
Returns:
FieldReference: Reference object for the field
"""
def get_oneway_ref(self, key: str) -> FieldReference:
"""
Get a one-way FieldReference that doesn't create bidirectional dependency.
Args:
key (str): Field name to reference
Returns:
FieldReference: One-way reference object for the field
"""Standard dictionary operations with ConfigDict-specific enhancements and iteration methods.
def get(self, key: str, default=None):
"""
Standard dict get with default value.
Args:
key (str): Key to retrieve
default: Default value if key not found
Returns:
Value at key or default
"""
def keys(self):
"""Returns sorted list of keys."""
def values(self, preserve_field_references: bool = False):
"""
Returns list of values.
Args:
preserve_field_references (bool): Whether to preserve FieldReference objects
Returns:
list: List of values
"""
def items(self, preserve_field_references: bool = False):
"""
Returns key-value pairs.
Args:
preserve_field_references (bool): Whether to preserve FieldReference objects
Returns:
list: List of (key, value) tuples
"""
def iterkeys(self):
"""Iterator over keys."""
def itervalues(self, preserve_field_references: bool = False):
"""
Iterator over values.
Args:
preserve_field_references (bool): Whether to preserve FieldReference objects
"""
def iteritems(self, preserve_field_references: bool = False):
"""
Iterator over key-value pairs.
Args:
preserve_field_references (bool): Whether to preserve FieldReference objects
"""Methods for type safety and type information retrieval.
def get_type(self, key: str):
"""
Returns type of field associated with key.
Args:
key (str): Field name
Returns:
type: Type of the field
"""
def ignore_type(self):
"""
Context manager to temporarily disable type safety.
Returns:
Context manager that disables type checking on entry and re-enables on exit
"""Advanced update methods for bulk configuration changes.
def update(self, *other, **kwargs):
"""
Recursive update from dict-like objects.
Args:
*other: Dict-like objects to update from
**kwargs: Additional key-value pairs
"""
def update_from_flattened_dict(self, flattened_dict: dict, strip_prefix: str = ''):
"""
Update from flattened dictionary with dot-separated keys.
Args:
flattened_dict (dict): Dictionary with dot-separated keys
strip_prefix (str): Prefix to strip from keys
"""Convert ConfigDict to various serialization formats.
def to_yaml(self, **kwargs) -> str:
"""
Returns YAML representation.
Args:
**kwargs: Arguments passed to yaml.dump
Returns:
str: YAML string representation
"""
def to_json(self, json_encoder_cls=None, **kwargs) -> str:
"""
Returns JSON representation.
Args:
json_encoder_cls: Custom JSON encoder class
**kwargs: Arguments passed to json.dumps
Returns:
str: JSON string representation
"""
def to_json_best_effort(self, **kwargs) -> str:
"""
Best effort JSON serialization handling non-serializable objects.
Args:
**kwargs: Arguments passed to json.dumps
Returns:
str: JSON string representation
"""
def to_dict(self, visit_map=None, preserve_field_references: bool = False) -> dict:
"""
Convert to regular dictionary.
Args:
visit_map: Mapping to track visited objects (for cycle detection)
preserve_field_references (bool): Whether to preserve FieldReference objects
Returns:
dict: Regular Python dictionary
"""Utility methods for copying, comparison, and resolving references within ConfigDict structures.
def copy_and_resolve_references(self) -> ConfigDict:
"""
Create a copy with all FieldReferences resolved to actual values.
Returns:
ConfigDict: New ConfigDict with resolved references
"""
def eq_as_configdict(self, other) -> bool:
"""
Equality comparison treating both objects as ConfigDict.
Args:
other: Object to compare with
Returns:
bool: True if objects are equal as ConfigDict
"""Create immutable, hashable versions of configurations for reproducibility and caching in ML workflows.
class FrozenConfigDict:
def __init__(self, initial_dictionary=None):
"""
Create an immutable, hashable ConfigDict.
Args:
initial_dictionary (dict or ConfigDict): Initial values
"""
def as_configdict(self) -> ConfigDict:
"""
Convert FrozenConfigDict back to mutable ConfigDict.
Returns:
ConfigDict: Mutable copy of this FrozenConfigDict
"""
def eq_as_configdict(self, other) -> bool:
"""
Equality comparison treating both objects as ConfigDict.
Args:
other: Object to compare with
Returns:
bool: True if objects are equal as ConfigDict
"""Usage example:
from ml_collections import ConfigDict, FrozenConfigDict
# Create mutable config
config = ConfigDict({
'model': 'resnet50',
'learning_rate': 0.001,
'optimizer': {'name': 'adam', 'beta1': 0.9}
})
# Create immutable version
frozen_config = FrozenConfigDict(config)
# Frozen configs are hashable and can be used as dictionary keys
model_cache = {frozen_config: trained_model}
# Convert back to mutable when needed
mutable_copy = frozen_config.as_configdict()
mutable_copy.learning_rate = 0.01 # This works
# Original frozen config is unchanged
print(frozen_config.learning_rate) # Still 0.001Perform bulk operations on nested configuration structures.
def recursive_rename(config, rename_fn):
"""
Recursively rename fields in configuration structures.
Args:
config: ConfigDict or FrozenConfigDict to rename fields in
rename_fn: Function that takes old field name and returns new name
Returns:
Same type as input config with renamed fields
"""class MutabilityError(AttributeError):
"""Raised when attempting to modify locked or immutable structures."""
class JSONDecodeError(ValueError):
"""Raised when JSON decoding fails."""
class CustomJSONEncoder:
"""JSON encoder for ML Collections objects."""Install with Tessl CLI
npx tessl i tessl/pypi-ml-collections