Skip to content

minrecord.base

minrecord.base

Contain the base class to record values.

minrecord.base.BaseRecord

Bases: ABC, Generic[T]

Define the base class to implement a record.

The record tracks the value added as well as the step when the value is added. The goal of this class is to track the recent record because the loggers (e.g. MLFlow or Tensorboard) do not allow to get the last value or the best value. The record keeps in memory a recent record of pairs (step, value) where step is the index of the step when the value was added. The length of the recent record depends on the concrete implementation.

To implement your own record, you will need to define the following methods:

- ``add_value``
- ``get_last_value``
- ``get_most_recent``
- ``is_comparable``
- ``is_empty``
- ``update``
- ``load_state_dict``
- ``state_dict``

If it is a comparable record, you will need to implement the following methods too:

- ``_get_best_value``
- ``_has_improved``

You may also need to extend the config_dict method.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.add_value(value=2, step=0)
>>> record.add_value(value=1.2, step=1)
>>> record.get_last_value()
1.2

minrecord.base.BaseRecord.name abstractmethod property

name: str

The name of the record.

minrecord.base.BaseRecord.add_value abstractmethod

add_value(value: T, step: float | None = None) -> None

Add a new value to the record.

Parameters:

Name Type Description Default
value T

The value to add to the record.

required
step float | None

The step value to record. None means there is no step to track.

None
Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.add_value(value=2)
>>> record.add_value(value=42, step=1)
>>> record
Record(name=loss, max_size=10, size=2)

minrecord.base.BaseRecord.clone abstractmethod

clone() -> BaseRecord[T]

Clone the current record.

Returns:

Type Description
BaseRecord[T]

A copy of the current record.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record_cloned = record.clone()
>>> record_cloned
Record(name=loss, max_size=10, size=0)

minrecord.base.BaseRecord.config_dict

config_dict() -> dict[str, Any]

Get the config of the record.

The config dictionary should contain all the values necessary to instantiate a record with the same parameters with the factory method. It is expected to contain values like the full name of the class and the arguments of the constructor. This dictionary should not contain the state values. It is possible to get the state values with the state_dict method.

Returns:

Type Description
dict[str, Any]

The config of the record.

Example
>>> from minrecord import BaseRecord, Record
>>> config = Record("loss").config_dict()
>>> record = BaseRecord.factory(**config)  # Note that the state is not copied.
>>> record
Record(name=loss, max_size=10, size=0)

minrecord.base.BaseRecord.equal abstractmethod

equal(other: Any) -> bool

Indicate if two records are equal or not.

Parameters:

Name Type Description Default
other Any

The object to compare.

required

Returns:

Type Description
bool

True if the records are equal, False otherwise.

Example
>>> from minrecord import Record
>>> record1 = Record("loss")
>>> record2 = Record("accuracy")
>>> record3 = Record("loss")
>>> record1.equal(record2)
False
>>> record1.equal(record1)
True

minrecord.base.BaseRecord.from_dict classmethod

from_dict(data: dict[str, Any]) -> BaseRecord[T]

Instantiate a record from a dictionary.

Parameters:

Name Type Description Default
data dict[str, Any]

The dictionary that is used to instantiate the record. The dictionary is expected to contain the parameters to create instantiate the record and the state of the record.

required

Returns:

Type Description
BaseRecord[T]

The instantiated record.

Example
>>> from minrecord import BaseRecord
>>> from objectory import OBJECT_TARGET
>>> record = BaseRecord.from_dict(
...     {
...         "config": {
...             OBJECT_TARGET: "minrecord.Record",
...             "name": "loss",
...             "max_size": 7,
...         },
...         "state": {"record": ((0, 1), (1, 5))},
...     }
... )
>>> record
Record(name=loss, max_size=7, size=2)

minrecord.base.BaseRecord.get_best_value

get_best_value() -> T

Get the best value of this record.

It is possible to get the best value only if it is a comparable record i.e. it is possible to compare the values in the record.

Returns:

Type Description
T

The best value of this record.

Raises:

Type Description
NotAComparableRecord

if it is not a comparable record.

EmptyRecordError

if the record is empty

Example
>>> from minrecord import MaxScalarRecord
>>> record = MaxScalarRecord("accuracy")
>>> record.add_value(value=2, step=0)
>>> record.add_value(value=4, step=1)
>>> record.get_best_value()
4

minrecord.base.BaseRecord.get_last_value abstractmethod

get_last_value() -> T

Get the last value.

Returns:

Type Description
T

The last value added in the record.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.add_value(value=2, step=0)
>>> record.add_value(value=1.2, step=1)
>>> record.get_last_value()
1.2
>>> record.add_value(value=0.8, step=1)
>>> record.get_last_value()
0.8

minrecord.base.BaseRecord.get_most_recent abstractmethod

get_most_recent() -> tuple[tuple[float | None, T], ...]

Get the tuple of recent values and their associated steps.

The last value in the tuple is the last value added to the record. The length of the recent record depends on the concrete implementation.

Returns:

Type Description
tuple[tuple[float | None, T], ...]

A tuple of the recent values in the record.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.add_value(value=2)
>>> record.add_value(value=1.2, step=1)
>>> record.add_value(value=0.8, step=2)
>>> record.get_most_recent()
((None, 2), (1, 1.2), (2, 0.8))

minrecord.base.BaseRecord.has_improved

has_improved() -> bool

Indicate if the last value is the best value.

It is possible to use this method only if it is a comparable record i.e. it is possible to compare the values in the record.

Returns:

Type Description
bool

True if the last value is the best value, otherwise False.

Raises:

Type Description
NotAComparableRecord

if it is not a comparable record.

EmptyRecordError

if the record is empty

Example
>>> from minrecord import MaxScalarRecord
>>> record = MaxScalarRecord("accuracy")
>>> record.add_value(value=2, step=0)
>>> record.add_value(value=4, step=1)
>>> record.has_improved()
True

minrecord.base.BaseRecord.is_comparable abstractmethod

is_comparable() -> bool

Indicate if it is possible to compare the values in the record.

Note that it is possible to compute the best value only for records that are comparable.

Returns:

Type Description
bool

True if it is possible to compare the values in the record, otherwise False.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.is_comparable()
False

minrecord.base.BaseRecord.is_empty abstractmethod

is_empty() -> bool

Indicate if the record is empty or not.

Returns:

Type Description
bool

True if the record is empty, otherwise False.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.is_empty()
True

minrecord.base.BaseRecord.load_state_dict abstractmethod

load_state_dict(state_dict: dict[str, Any]) -> None

Set up the record from a dictionary containing the state values.

Parameters:

Name Type Description Default
state_dict dict[str, Any]

A dictionary containing state keys with values.

required
Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.load_state_dict({"record": ((0, 42.0),)})
>>> record.get_last_value()
42.0

minrecord.base.BaseRecord.state_dict abstractmethod

state_dict() -> dict[str, Any]

Get a dictionary containing the state values of the record.

Returns:

Type Description
dict[str, Any]

The state values in a dict.

Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.add_value(42.0, step=0)
>>> state = record.state_dict()
>>> state
{'record': ((0, 42.0),)}

minrecord.base.BaseRecord.to_dict

to_dict() -> dict[str, Any]

Export the current record to a dictionary.

This method exports all the information to re-create the record with the same state. The returned dictionary can be used as input of the from_dict method to resume the record.

Returns:

Type Description
dict[str, Any]

A dictionary with the config and the state of the record.

Example
>>> from minrecord import BaseRecord, Record
>>> record_dict = Record("loss").to_dict()
>>> record = BaseRecord.from_dict(record_dict)
>>> record
Record(name=loss, max_size=10, size=0)

minrecord.base.BaseRecord.update abstractmethod

update(elements: Iterable[tuple[float | None, T]]) -> None

Update the record by adding the elements.

Parameters:

Name Type Description Default
elements Iterable[tuple[float | None, T]]

The elements to add to the record. Each tuple has the following structure (step, value). The step can be None if there is no step.

required
Example
>>> from minrecord import Record
>>> record = Record("loss")
>>> record.update([(0, 42), (1, 45)])
>>> record
Record(name=loss, max_size=10, size=2)

minrecord.base.EmptyRecordError

Bases: Exception

Raise an error if the record is empty.

minrecord.base.NotAComparableRecordError

Bases: Exception

Raise an error if it is not possible to compare the values in the record.