aidevelopementtoolkit.torch_utils.schedulers

AbstractScheduler

Bases: ABC

Abstract base class for all schedulers.

This class defines the common interface that every scheduler must implement. A scheduler is responsible for returning a scalar value (e.g. weight, learning rate, coefficient) as a function of the current epoch.

Notes
  • All derived classes must implement the get_weight method.
  • Input validation should be handled inside each concrete implementation.
  • This class does not enforce a specific scheduling strategy.
Source code in aidevelopementtoolkit/torch_utils/schedulers.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class AbstractScheduler(ABC):
    """Abstract base class for all schedulers.

    This class defines the common interface that every scheduler must implement.
    A scheduler is responsible for returning a scalar value (e.g. weight,
    learning rate, coefficient) as a function of the current epoch.

    Notes
    -----
    - All derived classes must implement the `get_weight` method.
    - Input validation should be handled inside each concrete implementation.
    - This class does not enforce a specific scheduling strategy.
    """

    @abstractmethod
    def get_weight(self, current_epoch: int) -> float:
        """Returns the scheduled value for a given epoch.

        Parameters
        ----------
        current_epoch : int
            The current epoch for which the scheduler value is requested.

        Returns
        -------
        float
            The scheduled value at `current_epoch`.
        """
        logger.error(
            "Not implemented error: The method `get_weight` must be "
            "implemented in the derived scheduler class.",
            NotImplementedError,
        )

    @staticmethod
    def get_scheduler(class_name: str, scheduler_kwargs: Dict[str, Any]) -> "AbstractScheduler":
        """Returns an instance of the specified scheduler class.

        Parameters
        ----------
        class_name : str
            The name of the scheduler class to instantiate.

        scheduler_kwargs : Dict[str, Any]
            The keyword arguments to pass to the scheduler class constructor.

        Returns
        -------
        AbstractScheduler
            An instance of the specified scheduler class.
        """
        scheduler_class = globals().get(class_name)
        if (
            not isinstance(scheduler_class, type)
            or scheduler_class is AbstractScheduler
            or not issubclass(scheduler_class, AbstractScheduler)
            or scheduler_class.__module__ != __name__
        ):
            logger.error(
                f"Value error: '{class_name}' is not a concrete scheduler class "
                "defined in this module.",
                ValueError,
            )

        return scheduler_class(**scheduler_kwargs)

get_weight(current_epoch: int) -> float abstractmethod

Returns the scheduled value for a given epoch.

Parameters:
  • current_epoch (int) –

    The current epoch for which the scheduler value is requested.

Returns:
  • float –

    The scheduled value at current_epoch.

Source code in aidevelopementtoolkit/torch_utils/schedulers.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@abstractmethod
def get_weight(self, current_epoch: int) -> float:
    """Returns the scheduled value for a given epoch.

    Parameters
    ----------
    current_epoch : int
        The current epoch for which the scheduler value is requested.

    Returns
    -------
    float
        The scheduled value at `current_epoch`.
    """
    logger.error(
        "Not implemented error: The method `get_weight` must be "
        "implemented in the derived scheduler class.",
        NotImplementedError,
    )

get_scheduler(class_name: str, scheduler_kwargs: Dict[str, Any]) -> AbstractScheduler staticmethod

Returns an instance of the specified scheduler class.

Parameters:
  • class_name (str) –

    The name of the scheduler class to instantiate.

  • scheduler_kwargs (Dict[str, Any]) –

    The keyword arguments to pass to the scheduler class constructor.

Returns:
Source code in aidevelopementtoolkit/torch_utils/schedulers.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@staticmethod
def get_scheduler(class_name: str, scheduler_kwargs: Dict[str, Any]) -> "AbstractScheduler":
    """Returns an instance of the specified scheduler class.

    Parameters
    ----------
    class_name : str
        The name of the scheduler class to instantiate.

    scheduler_kwargs : Dict[str, Any]
        The keyword arguments to pass to the scheduler class constructor.

    Returns
    -------
    AbstractScheduler
        An instance of the specified scheduler class.
    """
    scheduler_class = globals().get(class_name)
    if (
        not isinstance(scheduler_class, type)
        or scheduler_class is AbstractScheduler
        or not issubclass(scheduler_class, AbstractScheduler)
        or scheduler_class.__module__ != __name__
    ):
        logger.error(
            f"Value error: '{class_name}' is not a concrete scheduler class "
            "defined in this module.",
            ValueError,
        )

    return scheduler_class(**scheduler_kwargs)

ConstantScheduler

Bases: AbstractScheduler

This class implements a constant scheduler.

The scheduler always returns a constant value, regardless of the epoch.

Parameters:
  • value (float) –

    The constant value returned by the scheduler at all epochs.

Source code in aidevelopementtoolkit/torch_utils/schedulers.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
class ConstantScheduler(AbstractScheduler):
    """This class implements a constant scheduler.

    The scheduler always returns a constant value, regardless of the epoch.

    Parameters
    ----------
    value : float
        The constant value returned by the scheduler at all epochs.
    """

    def __init__(self, value: float):
        self.value = value


    def get_weight(self, current_epoch: int) -> float:
        """Returns the constant value for any given epoch.

        Parameters
        ----------
        current_epoch : int
            The current epoch for which the scheduler value is requested.

        Returns
        -------
        float
            The constant value at `current_epoch`.

        """
        if current_epoch < 0:
            logger.error(
                "Value error: The `current_epoch` must be a non-negative integer, "
                f"given `current_epoch`={current_epoch}"
            )

        return self.value

get_weight(current_epoch: int) -> float

Returns the constant value for any given epoch.

Parameters:
  • current_epoch (int) –

    The current epoch for which the scheduler value is requested.

Returns:
  • float –

    The constant value at current_epoch.

Source code in aidevelopementtoolkit/torch_utils/schedulers.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def get_weight(self, current_epoch: int) -> float:
    """Returns the constant value for any given epoch.

    Parameters
    ----------
    current_epoch : int
        The current epoch for which the scheduler value is requested.

    Returns
    -------
    float
        The constant value at `current_epoch`.

    """
    if current_epoch < 0:
        logger.error(
            "Value error: The `current_epoch` must be a non-negative integer, "
            f"given `current_epoch`={current_epoch}"
        )

    return self.value

LinearScheduler

Bases: AbstractScheduler

This class implements a linear scheduler.

The scheduler linearly interpolates a value between start_value and end_value from starting_epoch to ending_epoch (inclusive).

Parameters:
  • start_value (float) –

    Initial value returned by the scheduler before (and at) starting_epoch.

  • end_value (float) –

    Final value returned by the scheduler after (and at) ending_epoch.

  • starting_epoch (int) –

    Epoch at which the linear interpolation starts.

  • ending_epoch (int) –

    Epoch at which the linear interpolation ends.

Notes
  • For current_epoch <= starting_epoch, the scheduler returns start_value.
  • For current_epoch >= ending_epoch, the scheduler returns end_value.
  • For epochs in-between, it returns a linearly interpolated value.
Source code in aidevelopementtoolkit/torch_utils/schedulers.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
class LinearScheduler(AbstractScheduler):
    """This class implements a linear scheduler.

    The scheduler linearly interpolates a value between `start_value` and
    `end_value` from `starting_epoch` to `ending_epoch` (inclusive).

    Parameters
    ----------
    start_value : float
        Initial value returned by the scheduler before (and at) `starting_epoch`.

    end_value : float
        Final value returned by the scheduler after (and at) `ending_epoch`.

    starting_epoch : int
        Epoch at which the linear interpolation starts.

    ending_epoch : int
        Epoch at which the linear interpolation ends.

    Notes
    -----
    - For `current_epoch <= starting_epoch`, the scheduler returns `start_value`.
    - For `current_epoch >= ending_epoch`, the scheduler returns `end_value`.
    - For epochs in-between, it returns a linearly interpolated value.
    """

    def __init__(
            self,
            start_value: float,
            end_value: float,
            starting_epoch: int,
            ending_epoch: int,
        ):

        if ending_epoch < starting_epoch:
            logger.error(
                "Value error: The `ending_epoch` must be >= than `starting_epoch`, "
                f"given `starting_epoch`={starting_epoch} and `ending_epoch`={ending_epoch}"
            )

        self.start_value = start_value
        self.end_value = end_value
        self.starting_epoch = starting_epoch
        self.ending_epoch = ending_epoch


    def get_weight(self, current_epoch: int) -> float:
        """Returns the scheduled value for a given epoch.

        Parameters
        ----------
        current_epoch : int
            The current epoch for which the scheduler value is requested.

        Returns
        -------
        float
            The scheduled value at `current_epoch`, following a linear schedule
            between `start_value` and `end_value`.

        """
        if current_epoch < 0:
            logger.error(
                "Value error: The `current_epoch` must be a non-negative integer, "
                f"given `current_epoch`={current_epoch}"
            )

        # Before schedule starts
        if current_epoch <= self.starting_epoch:
            return float(self.start_value)

        # After schedule ends
        if current_epoch >= self.ending_epoch:
            return float(self.end_value)

        # Linear interpolation in-between
        progress = (current_epoch - self.starting_epoch) / (self.ending_epoch - self.starting_epoch)
        return float(self.start_value + progress * (self.end_value - self.start_value))

get_weight(current_epoch: int) -> float

Returns the scheduled value for a given epoch.

Parameters:
  • current_epoch (int) –

    The current epoch for which the scheduler value is requested.

Returns:
  • float –

    The scheduled value at current_epoch, following a linear schedule between start_value and end_value.

Source code in aidevelopementtoolkit/torch_utils/schedulers.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
def get_weight(self, current_epoch: int) -> float:
    """Returns the scheduled value for a given epoch.

    Parameters
    ----------
    current_epoch : int
        The current epoch for which the scheduler value is requested.

    Returns
    -------
    float
        The scheduled value at `current_epoch`, following a linear schedule
        between `start_value` and `end_value`.

    """
    if current_epoch < 0:
        logger.error(
            "Value error: The `current_epoch` must be a non-negative integer, "
            f"given `current_epoch`={current_epoch}"
        )

    # Before schedule starts
    if current_epoch <= self.starting_epoch:
        return float(self.start_value)

    # After schedule ends
    if current_epoch >= self.ending_epoch:
        return float(self.end_value)

    # Linear interpolation in-between
    progress = (current_epoch - self.starting_epoch) / (self.ending_epoch - self.starting_epoch)
    return float(self.start_value + progress * (self.end_value - self.start_value))

CosineScheduler

Bases: AbstractScheduler

This class implements a cosine scheduler.

The scheduler follows a half-cosine curve between start_value and end_value from starting_epoch to ending_epoch (inclusive).

Parameters:
  • start_value (float) –

    Initial value returned before (and at) starting_epoch.

  • end_value (float) –

    Final value returned after (and at) ending_epoch.

  • starting_epoch (int) –

    Epoch at which the cosine interpolation starts.

  • ending_epoch (int) –

    Epoch at which the cosine interpolation ends.

Notes
  • For current_epoch <= starting_epoch, the scheduler returns start_value.
  • For current_epoch >= ending_epoch, the scheduler returns end_value.
  • For epochs in-between, it returns a half-cosine interpolation between the start and end values.
Source code in aidevelopementtoolkit/torch_utils/schedulers.py
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
class CosineScheduler(AbstractScheduler):
    """This class implements a cosine scheduler.

    The scheduler follows a half-cosine curve between `start_value` and
    `end_value` from `starting_epoch` to `ending_epoch` (inclusive).

    Parameters
    ----------
    start_value : float
        Initial value returned before (and at) `starting_epoch`.

    end_value : float
        Final value returned after (and at) `ending_epoch`.

    starting_epoch : int
        Epoch at which the cosine interpolation starts.

    ending_epoch : int
        Epoch at which the cosine interpolation ends.

    Notes
    -----
    - For `current_epoch <= starting_epoch`, the scheduler returns `start_value`.
    - For `current_epoch >= ending_epoch`, the scheduler returns `end_value`.
    - For epochs in-between, it returns a half-cosine interpolation between the
      start and end values.
    """

    def __init__(
            self,
            start_value: float,
            end_value: float,
            starting_epoch: int,
            ending_epoch: int,
        ):

        if ending_epoch < starting_epoch:
            logger.error(
                "Value error: The `ending_epoch` must be >= than `starting_epoch`, "
                f"given `starting_epoch`={starting_epoch} and `ending_epoch`={ending_epoch}"
            )

        self.start_value = start_value
        self.end_value = end_value
        self.starting_epoch = starting_epoch
        self.ending_epoch = ending_epoch

    def get_weight(self, current_epoch: int) -> float:
        """Return the scheduled value for a given epoch.

        Parameters
        ----------
        current_epoch : int
            The current epoch for which the scheduler value is requested.

        Returns
        -------
        float
            The scheduled value at `current_epoch`, following a cosine schedule
            between `start_value` and `end_value`.
        """
        if current_epoch < 0:
            logger.error(
                "Value error: The `current_epoch` must be a non-negative integer, "
                f"given `current_epoch`={current_epoch}"
            )

        if current_epoch <= self.starting_epoch:
            return float(self.start_value)

        if current_epoch >= self.ending_epoch:
            return float(self.end_value)

        progress = (current_epoch - self.starting_epoch) / (self.ending_epoch - self.starting_epoch)
        cosine_decay = (1 + cos(pi * progress)) / 2
        return float(self.end_value + (self.start_value - self.end_value) * cosine_decay)

get_weight(current_epoch: int) -> float

Return the scheduled value for a given epoch.

Parameters:
  • current_epoch (int) –

    The current epoch for which the scheduler value is requested.

Returns:
  • float –

    The scheduled value at current_epoch, following a cosine schedule between start_value and end_value.

Source code in aidevelopementtoolkit/torch_utils/schedulers.py
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
def get_weight(self, current_epoch: int) -> float:
    """Return the scheduled value for a given epoch.

    Parameters
    ----------
    current_epoch : int
        The current epoch for which the scheduler value is requested.

    Returns
    -------
    float
        The scheduled value at `current_epoch`, following a cosine schedule
        between `start_value` and `end_value`.
    """
    if current_epoch < 0:
        logger.error(
            "Value error: The `current_epoch` must be a non-negative integer, "
            f"given `current_epoch`={current_epoch}"
        )

    if current_epoch <= self.starting_epoch:
        return float(self.start_value)

    if current_epoch >= self.ending_epoch:
        return float(self.end_value)

    progress = (current_epoch - self.starting_epoch) / (self.ending_epoch - self.starting_epoch)
    cosine_decay = (1 + cos(pi * progress)) / 2
    return float(self.end_value + (self.start_value - self.end_value) * cosine_decay)