netloader 3.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ """
2
+ Collects all architectures
3
+ """
4
+ from warnings import warn
5
+
6
+ from netloader.architectures import (
7
+ BaseArchitecture,
8
+ UtilityMixin,
9
+ Autoencoder,
10
+ Decoder,
11
+ Encoder,
12
+ load_arch,
13
+ )
14
+
15
+ BaseNetwork = BaseArchitecture
16
+ load_net = load_arch
17
+
18
+
19
+ warn(
20
+ 'Importing architectures from netloader.networks is deprecated, please use '
21
+ 'netloader.architectures',
22
+ DeprecationWarning,
23
+ stacklevel=2,
24
+ )
25
+
26
+ __all__ = [
27
+ 'UtilityMixin',
28
+ 'BaseNetwork',
29
+ 'Autoencoder',
30
+ 'Decoder',
31
+ 'Encoder',
32
+ 'load_net',
33
+ ]
34
+
35
+ _optional_imports: dict[str, set[str]] = {'flow': {'NormFlow', 'NormFlowEncoder'}}
36
+
37
+ try:
38
+ from netloader.architectures.flows import NormFlow, NormFlowEncoder
39
+ __all__.extend(['NormFlow', 'NormFlowEncoder'])
40
+ except (ModuleNotFoundError, ImportError):
41
+ pass
42
+
43
+
44
+ def __getattr__(name):
45
+ if name not in __all__ and name in _optional_imports['flow']:
46
+ raise ImportError(f'Cannot import {name}, normalising flow architectures require the '
47
+ f'package Zuko')
48
+ raise AttributeError(f"module {__name__} has no attribute {name}")
@@ -0,0 +1,409 @@
1
+ """
2
+ Scheduler classes.
3
+ """
4
+ from typing import Any
5
+ from abc import ABC, abstractmethod
6
+
7
+ import torch
8
+ import numpy as np
9
+
10
+
11
+ class BaseScheduler(ABC):
12
+ """
13
+ Abstract base class for schedulers.
14
+ """
15
+ def __init__(self) -> None:
16
+ # Adds all scheduler classes to list of safe PyTorch classes when loading saved architectures
17
+ torch.serialization.add_safe_globals([self.__class__])
18
+
19
+ @abstractmethod
20
+ def __call__(self) -> float:
21
+ """
22
+ Returns the current value of the scheduler.
23
+ """
24
+
25
+ @abstractmethod
26
+ def __getstate__(self) -> dict[str, Any]:
27
+ """
28
+ Returns the state of the scheduler.
29
+
30
+ Returns
31
+ -------
32
+ dict[str, Any]
33
+ State of the scheduler
34
+ """
35
+
36
+ @abstractmethod
37
+ def __setstate__(self, state: dict[str, Any]) -> None:
38
+ """
39
+ Sets the state of the scheduler.
40
+
41
+ Parameters
42
+ ----------
43
+ state : dict[str, Any]
44
+ State of the scheduler
45
+ """
46
+
47
+ def __repr__(self) -> str:
48
+ """
49
+ Returns the string representation of the scheduler.
50
+
51
+ Returns
52
+ -------
53
+ str
54
+ String representation of the scheduler
55
+ """
56
+ return (f'{self.__class__.__name__}(' +
57
+ (f'{self.extra_repr()})' if self.extra_repr() else ')'))
58
+
59
+ @abstractmethod
60
+ def step(self, epoch: int | float) -> None:
61
+ """
62
+ Steps the scheduler.
63
+
64
+ Parameters
65
+ ----------
66
+ epoch : int | float
67
+ Current epoch
68
+ """
69
+
70
+ def extra_repr(self) -> str:
71
+ """
72
+ Additional string representation of the scheduler.
73
+
74
+ Returns
75
+ -------
76
+ str
77
+ Additional string representation of the scheduler
78
+ """
79
+ return ''
80
+
81
+ def get_step(self, epoch: int | float) -> float:
82
+ """
83
+ Returns the current value of the scheduler for the given epoch.
84
+
85
+ Parameters
86
+ ----------
87
+ epoch : int | float
88
+ Current epoch
89
+
90
+ Returns
91
+ -------
92
+ float
93
+ Current value of the scheduler for the given epoch
94
+ """
95
+ self.step(epoch)
96
+ return self()
97
+
98
+
99
+ class BaseFuncScheduler(BaseScheduler, ABC):
100
+ """
101
+ Abstract base class for simple function schedulers.
102
+
103
+ Attributes
104
+ ----------
105
+ max_epochs : int
106
+ Maximum number of epochs
107
+ warmup : int
108
+ Number of warmup epochs
109
+ initial_val : float
110
+ Initial value of the scheduler
111
+ final_val : float
112
+ Final value of the scheduler
113
+ """
114
+ max_epochs: int
115
+ warmup: int
116
+ final_val: float
117
+ initial_val: float
118
+ _value: float
119
+
120
+ def __init__(
121
+ self,
122
+ max_epochs: int,
123
+ *,
124
+ warmup_epochs: int = 0,
125
+ final_value: float = 1,
126
+ initial_value: float = 0) -> None:
127
+ """
128
+ Parameters
129
+ ----------
130
+ max_epochs : int
131
+ Maximum number of epochs
132
+ warmup_epochs : int, Optional
133
+ Number of warmup epochs, default = 0
134
+ final_value : float, Optional
135
+ Maximum value of the scheduler, default = 1
136
+ initial_value : float, Optional
137
+ Minimum value of the scheduler, default = 0
138
+ """
139
+ super().__init__()
140
+ self.max_epochs = max_epochs
141
+ self.warmup = warmup_epochs
142
+ self.final_val = final_value
143
+ self.initial_val = initial_value
144
+ self._value = self.final_val
145
+ self.step(0)
146
+
147
+ if self.max_epochs < warmup_epochs:
148
+ raise ValueError(f'max_epochs ({self.max_epochs}) should be larger than warmup_epochs '
149
+ f'({self.warmup})')
150
+
151
+ def __call__(self) -> float:
152
+ return self._value
153
+
154
+ def __getstate__(self) -> dict[str, Any]:
155
+ return {
156
+ 'max_epochs': self.max_epochs,
157
+ 'warmup': self.warmup,
158
+ 'final_val': self.final_val,
159
+ 'initial_val': self.initial_val,
160
+ }
161
+
162
+ def __setstate__(self, state: dict[str, Any]) -> None:
163
+ self.__dict__.update(state)
164
+ self._value = self.final_val
165
+ self.step(0)
166
+
167
+ def extra_repr(self) -> str:
168
+ return (f'max_epochs={self.max_epochs}, warmup_epochs={self.warmup}, '
169
+ f'final_value={self.final_val}, initial_value={self.initial_val}')
170
+
171
+ class LinearScheduler(BaseFuncScheduler):
172
+ """
173
+ Linear scheduler.
174
+
175
+ Attributes
176
+ ----------
177
+ max_epochs : int
178
+ Maximum number of epochs
179
+ warmup : int
180
+ Number of warmup epochs
181
+ initial_val : float
182
+ Initial value of the scheduler
183
+ final_val : float
184
+ Final value of the scheduler
185
+ """
186
+ def step(self, epoch: int | float) -> None:
187
+ progress: float
188
+
189
+ if epoch >= self.max_epochs:
190
+ self._value = self.final_val
191
+ elif epoch <= self.warmup:
192
+ self._value = self.initial_val
193
+ else:
194
+ progress = (epoch - self.warmup) / (self.max_epochs - self.warmup)
195
+ self._value = progress * (self.final_val - self.initial_val) + self.initial_val
196
+
197
+
198
+ class SigmoidScheduler(BaseFuncScheduler):
199
+ """
200
+ Sigmoid scheduler.
201
+
202
+ Attributes
203
+ ----------
204
+ max_epochs : int
205
+ Maximum number of epochs
206
+ warmup : int
207
+ Number of warmup epochs
208
+ initial_val : float
209
+ Initial value of the scheduler
210
+ final_val : float
211
+ Final value of the scheduler
212
+ compression : float
213
+ Compression factor for the sigmoid function, higher values result in a steeper curve
214
+ """
215
+ compression: float = 10
216
+
217
+ def __init__(
218
+ self,
219
+ max_epochs: int,
220
+ *,
221
+ warmup_epochs: int = 0,
222
+ final_value: float = 1,
223
+ initial_value: float = 0,
224
+ compression: float = 0) -> None:
225
+ """
226
+ Parameters
227
+ ----------
228
+ max_epochs : int
229
+ Maximum number of epochs
230
+ warmup_epochs : int, Optional
231
+ Number of warmup epochs, default = 0
232
+ final_value : float, Optional
233
+ Maximum value of the scheduler, default = 1
234
+ initial_value : float, Optional
235
+ Minimum value of the scheduler, default = 0
236
+ compression : float, Optional
237
+ Compression factor for the tanh function, higher values result in a steeper curve,
238
+ default = 10
239
+ """
240
+ super().__init__(
241
+ max_epochs,
242
+ warmup_epochs=warmup_epochs,
243
+ final_value=final_value,
244
+ initial_value=initial_value,
245
+ )
246
+ self.compression = compression or self.compression
247
+
248
+ def __getstate__(self) -> dict[str, Any]:
249
+ return super().__getstate__() | {'compression': self.compression}
250
+
251
+ def __setstate__(self, state: dict[str, Any]) -> None:
252
+ super().__setstate__(state)
253
+ self.compression = state['compression']
254
+
255
+ def extra_repr(self) -> str:
256
+ return f'{super().extra_repr()}, compression={self.compression}'
257
+
258
+ def step(self, epoch: int | float) -> None:
259
+ progress: float
260
+
261
+ if epoch >= self.max_epochs:
262
+ self._value = self.final_val
263
+ elif epoch <= self.warmup:
264
+ self._value = self.initial_val
265
+ else:
266
+ progress = 1 / (1 + np.exp(
267
+ -self.compression * ((epoch - self.warmup) / (self.max_epochs - self.warmup) - 0.5)
268
+ ))
269
+ self._value = progress * (self.final_val - self.initial_val) + self.initial_val
270
+
271
+
272
+ class StepScheduler(BaseScheduler):
273
+ """
274
+ Step scheduler.
275
+
276
+ Attributes
277
+ ----------
278
+ warmup : int
279
+ Number of warmup epochs
280
+ max_steps : int
281
+ Maximum number of steps
282
+ step_size : int
283
+ Number of epochs between each step
284
+ gamma : float
285
+ Multiplicative factor of the step
286
+ initial_val : float
287
+ Initial value of the scheduler
288
+ """
289
+ def __init__(
290
+ self,
291
+ warmup: int,
292
+ max_steps: int,
293
+ step_size: int,
294
+ gamma: float,
295
+ initial_value: float = 1) -> None:
296
+ """
297
+ Parameters
298
+ ----------
299
+ warmup : int
300
+ Number of warmup epochs
301
+ max_steps : int
302
+ Maximum number of steps
303
+ step_size : int
304
+ Number of epochs between each step
305
+ gamma : float
306
+ Multiplicative factor of the step
307
+ initial_value : float
308
+ Initial value of the scheduler, default = 1
309
+ """
310
+ super().__init__()
311
+ self.warmup: int = warmup
312
+ self.max_steps: int = max_steps
313
+ self.step_size: int = step_size
314
+ self.gamma: float = gamma
315
+ self.initial_val: float = initial_value
316
+ self._value: float = self.initial_val
317
+
318
+ def __call__(self) -> float:
319
+ return self._value
320
+
321
+ def __getstate__(self) -> dict[str, Any]:
322
+ return {
323
+ 'warmup': self.warmup,
324
+ 'max_steps': self.max_steps,
325
+ 'step_size': self.step_size,
326
+ 'gamma': self.gamma,
327
+ 'initial_val': self.initial_val,
328
+ }
329
+
330
+ def __setstate__(self, state: dict[str, Any]) -> None:
331
+ self.__dict__.update(state)
332
+ self._value = self.initial_val
333
+
334
+ def extra_repr(self) -> str:
335
+ return (f'warmup={self.warmup}, max_steps={self.max_steps}, step_size={self.step_size}, '
336
+ f'initial_value={self.initial_val}')
337
+
338
+ def step(self, epoch: int | float) -> None:
339
+ steps: int = min(max(int((epoch - self.warmup) // self.step_size), 0), self.max_steps)
340
+
341
+ if not steps:
342
+ self._value = self.initial_val
343
+ return
344
+
345
+ self._value = self.initial_val * (self.gamma ** steps)
346
+
347
+
348
+ class TanhScheduler(SigmoidScheduler):
349
+ """
350
+ Tanh scheduler.
351
+
352
+ Attributes
353
+ ----------
354
+ max_epochs : int
355
+ Maximum number of epochs
356
+ warmup : int
357
+ Number of warmup epochs
358
+ initial_val : float
359
+ Initial value of the scheduler
360
+ final_val : float
361
+ Final value of the scheduler
362
+ compression : float
363
+ Compression factor for the tanh function, higher values result in a steeper curve
364
+ """
365
+ compression: float = 5
366
+
367
+ def __init__(
368
+ self,
369
+ max_epochs: int,
370
+ *,
371
+ warmup_epochs: int = 0,
372
+ final_value: float = 1,
373
+ initial_value: float = 0,
374
+ compression: float = 0) -> None:
375
+ """
376
+ Parameters
377
+ ----------
378
+ max_epochs : int
379
+ Maximum number of epochs
380
+ warmup_epochs : int, Optional
381
+ Number of warmup epochs, default = 0
382
+ final_value : float, Optional
383
+ Maximum value of the scheduler, default = 1
384
+ initial_value : float, Optional
385
+ Minimum value of the scheduler, default = 0
386
+ compression : float, Optional
387
+ Compression factor for the sigmoid function, higher values result in a steeper curve,
388
+ default = 5
389
+ """
390
+ super().__init__(
391
+ max_epochs,
392
+ warmup_epochs=warmup_epochs,
393
+ final_value=final_value,
394
+ initial_value=initial_value,
395
+ compression=compression,
396
+ )
397
+
398
+ def step(self, epoch: int | float) -> None:
399
+ progress: float
400
+
401
+ if epoch >= self.max_epochs:
402
+ self._value = self.final_val
403
+ elif epoch <= self.warmup:
404
+ self._value = self.initial_val
405
+ else:
406
+ progress = 2 / (1 + np.exp(
407
+ -self.compression * (epoch - self.warmup) / (self.max_epochs - self.warmup)
408
+ )) - 1
409
+ self._value = progress * (self.final_val - self.initial_val) + self.initial_val