|
1 | | -from typing import Type, TypedDict, TypeVar |
| 1 | +from typing import Any, Type, TypedDict, TypeVar |
2 | 2 |
|
3 | 3 | from typing_extensions import TypedDict as TE_TypedDict |
4 | 4 |
|
@@ -97,3 +97,60 @@ def overwrite_defaults( |
97 | 97 | :param new_defaults: A dict with the new default hyperparameters. |
98 | 98 | """ |
99 | 99 | _OVERWRITTEN_DEFAULTS[hypers_cls] = new_defaults |
| 100 | + |
| 101 | + |
| 102 | +def get_hypers_diff( |
| 103 | + old_hypers: dict, |
| 104 | + new_hypers: dict, |
| 105 | +) -> dict[str, tuple[Any, Any]]: |
| 106 | + """Get the difference between two hypers dictionaries. |
| 107 | +
|
| 108 | + :param old_hypers: The old hyperparameters. |
| 109 | + :param new_hypers: The new hyperparameters. |
| 110 | +
|
| 111 | + :return: A dict with the hyperparameters that are different in the new |
| 112 | + hypers compared to the old hypers. It is assumed that every key in |
| 113 | + the new hypers is also present in the old hypers. |
| 114 | + """ |
| 115 | + diff = {} |
| 116 | + for key, new_value in new_hypers.items(): |
| 117 | + old_value = old_hypers[key] |
| 118 | + if old_value != new_value: |
| 119 | + diff[key] = (old_value, new_value) |
| 120 | + return diff |
| 121 | + |
| 122 | + |
| 123 | +def raise_hypers_mismatch( |
| 124 | + hypers_diff: dict[str, tuple[Any, Any]], |
| 125 | +) -> None: |
| 126 | + """Raise an error if the hypers diff is not empty. |
| 127 | + |
| 128 | + The hypers diff can be computed using :func:`get_hypers_diff`. |
| 129 | + """ |
| 130 | + if hypers_diff: |
| 131 | + n_mismatches = len(hypers_diff) |
| 132 | + raise ValueError( |
| 133 | + f"Found {n_mismatches} mismatch{(n_mismatches != 1) * 'es'} in model hyperparameters.\n" |
| 134 | + f"Mismatched hypers: {list(hypers_diff.keys())}\n" |
| 135 | + "\n-------- Mismatches --------\n\n" |
| 136 | + + "\n".join( |
| 137 | + f"[Mismatch {i + 1}] {key}\n Previous: {old}\n New: {new}" |
| 138 | + for i, (key, (old, new)) in enumerate(hypers_diff.items()) |
| 139 | + ) |
| 140 | + ) |
| 141 | + |
| 142 | + |
| 143 | +def raise_if_hypers_mismatch( |
| 144 | + old_hypers: dict, |
| 145 | + new_hypers: dict, |
| 146 | +) -> None: |
| 147 | + """Raise an error if the new hypers do not match the old hypers. |
| 148 | +
|
| 149 | + :param old_hypers: The old hyperparameters. |
| 150 | + :param new_hypers: The new hyperparameters. |
| 151 | + """ |
| 152 | + # Gather mismatchs |
| 153 | + mismatches = get_hypers_diff(old_hypers, new_hypers) |
| 154 | + |
| 155 | + if mismatches: |
| 156 | + raise_hypers_mismatch(mismatches) |
0 commit comments