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,46 @@
1
+ """
2
+ Utility functions for PyTorch-Network-Loader
3
+ """
4
+ from netloader.utils.utils import (
5
+ Shapes,
6
+ ascii_plot,
7
+ check_params,
8
+ compare_versions,
9
+ deep_merge,
10
+ dict_list_append,
11
+ dict_list_convert,
12
+ get_device,
13
+ label_change,
14
+ list_dict_convert,
15
+ progress_bar,
16
+ safe_globals,
17
+ save_name,
18
+ suppress_logger_warnings,
19
+ )
20
+ from netloader.utils.types import ArrayT
21
+ from netloader.utils import configs, types, utils
22
+ from netloader.utils.configs import BaseConfig, Config, NetConfig
23
+
24
+ __all__ = [
25
+ 'ArrayT',
26
+ 'BaseConfig',
27
+ 'Config',
28
+ 'NetConfig',
29
+ 'Shapes',
30
+ 'ascii_plot',
31
+ 'check_params',
32
+ 'compare_versions',
33
+ 'deep_merge',
34
+ 'dict_list_append',
35
+ 'dict_list_convert',
36
+ 'get_device',
37
+ 'label_change',
38
+ 'list_dict_convert',
39
+ 'progress_bar',
40
+ 'safe_globals',
41
+ 'save_name',
42
+ 'suppress_logger_warnings',
43
+ 'configs',
44
+ 'types',
45
+ 'utils',
46
+ ]
@@ -0,0 +1,241 @@
1
+ """
2
+ Configuration dataclasses for the network and layers.
3
+ """
4
+ import logging as log
5
+ from dataclasses import dataclass, field
6
+ from typing import TypeVar, Any, Literal, get_type_hints
7
+
8
+ from netloader import layers
9
+
10
+
11
+ ConfigT = TypeVar('ConfigT', bound='BaseConfig')
12
+
13
+
14
+ @dataclass
15
+ class BaseConfig:
16
+ """
17
+ Base dataclass to hold configuration parameters.
18
+ """
19
+ _changed_fields: set[str] = field(default_factory=set, init=False, repr=False)
20
+
21
+ def __getattr__(self, item: str) -> Any:
22
+ """
23
+ Gets an attribute of the dataclass.
24
+
25
+ Parameters
26
+ ----------
27
+ item : str
28
+ Key of the attribute
29
+
30
+ Returns
31
+ -------
32
+ Any
33
+ Value of the attribute
34
+ """
35
+ item = item.replace('-', '_')
36
+ return super().__getattribute__(item)
37
+
38
+ def __setattr__(self, key: str, value: Any) -> None:
39
+ """
40
+ Sets an attribute of the dataclass.
41
+
42
+ Parameters
43
+ ----------
44
+ key : str
45
+ Key of the attribute
46
+ value : Any
47
+ Value to set
48
+ """
49
+ if key.startswith('_'):
50
+ return super().__setattr__(key, value)
51
+
52
+ key = key.replace('-', '_')
53
+ hint: type = get_type_hints(type(self))[key]
54
+
55
+ if getattr(hint, '__origin__', None) is Literal:
56
+ self._check_literal(key, value, getattr(hint, '__args__', ()))
57
+
58
+ if value != self.__dataclass_fields__[key].default:
59
+ self._changed_fields.add(key)
60
+ return super().__setattr__(key, value)
61
+
62
+ @staticmethod
63
+ def _check_literal(key: str, value: Any, options: tuple[Any, ...]) -> None:
64
+ """
65
+ Checks if a value is in a list of options.
66
+
67
+ Parameters
68
+ ----------
69
+ key : str
70
+ Key of the value
71
+ value : Any
72
+ Value to check
73
+ options : list[Any]
74
+ List of options
75
+ """
76
+ if value not in options:
77
+ raise ValueError(f'Invalid value for {key} ({value}), must be one of {options}')
78
+
79
+ @classmethod
80
+ def from_dict(cls: type[ConfigT], config: dict[str, Any], new_fields: bool = False) -> ConfigT:
81
+ """
82
+ Creates a BaseConfig object from a dictionary.
83
+
84
+ Parameters
85
+ ----------
86
+ config : dict[str, Any]
87
+ Configuration dictionary
88
+ new_fields : bool, Optional
89
+ Whether to allow new fields in the dictionary, default = False
90
+
91
+ Returns
92
+ -------
93
+ ConfigT
94
+ Configuration dataclass
95
+ """
96
+ instance: ConfigT = type.__call__(cls)
97
+ instance.merge_dict(config, new_fields=new_fields)
98
+ return instance
99
+
100
+ def get_changed_fields(self) -> set[str]:
101
+ """
102
+ Gets the set of changed fields in the dataclass.
103
+
104
+ Returns
105
+ -------
106
+ set[str]
107
+ Set of changed fields
108
+ """
109
+ return self._changed_fields
110
+
111
+ def merge(self: ConfigT, other: ConfigT, new_fields: bool = False) -> None:
112
+ """
113
+ Merges another dataclass into this one.
114
+
115
+ Parameters
116
+ ----------
117
+ other : ConfigT
118
+ Configuration dataclass to merge
119
+ new_fields : bool, Optional
120
+ Whether to allow new fields in the other dataclass, default = False
121
+ """
122
+ key: str
123
+
124
+ for key in other.get_changed_fields():
125
+ if not hasattr(self, key) and not new_fields:
126
+ raise AttributeError(f'Unknown config key ({key}) and new_fields is False')
127
+
128
+ if hasattr(self, key) and isinstance(getattr(self, key), BaseConfig):
129
+ getattr(self, key).merge(getattr(other, key), new_fields=new_fields)
130
+ else:
131
+ setattr(self, key, getattr(other, key))
132
+
133
+ def merge_dict(self, other: dict[str, Any], new_fields: bool = False) -> None:
134
+ """
135
+ Merges a dictionary into this dataclass.
136
+
137
+ Parameters
138
+ ----------
139
+ other : dict[str, Any]
140
+ Configuration dictionary to merge
141
+ new_fields : bool, Optional
142
+ Whether to allow new fields in the dictionary, default = False
143
+ """
144
+ key: str
145
+ value: Any
146
+
147
+ for key, value in other.items():
148
+ key.replace('-', '_')
149
+
150
+ if not hasattr(self, key) and not new_fields:
151
+ raise AttributeError(f'Unknown config key ({key}) and new_fields is False')
152
+
153
+ if hasattr(self, key) and isinstance(getattr(self, key), BaseConfig):
154
+ getattr(self, key).merge_dict(value, new_fields=new_fields)
155
+ else:
156
+ setattr(self, key, value)
157
+
158
+ def to_dict(self) -> dict[str, Any]:
159
+ """
160
+ Converts the dataclass to a dictionary.
161
+
162
+ Returns
163
+ -------
164
+ dict[str, Any]
165
+ Configuration dictionary
166
+ """
167
+ key: str
168
+ result: dict[str, Any] = {}
169
+ value: Any
170
+
171
+ for key, value in self.__dict__.items():
172
+ if key.startswith('_'):
173
+ continue
174
+ if isinstance(value, BaseConfig):
175
+ result[key] = value.to_dict()
176
+ else:
177
+ result[key] = value
178
+ return result
179
+
180
+
181
+ @dataclass
182
+ class NetConfig(BaseConfig):
183
+ """
184
+ Dataclass to hold global network configuration parameters.
185
+
186
+ Attributes
187
+ ----------
188
+ checkpoints : bool
189
+ Whether to capture intermediate outputs as checkpoints
190
+ paper : str
191
+ Reference to the paper describing the network
192
+ github : str
193
+ Link to the GitHub repository for the network
194
+ description : str
195
+ Description of the network
196
+ layers : dict[str, Any]
197
+ Dictionary of default layer configurations
198
+ """
199
+ checkpoints: bool = False
200
+ paper: str = ''
201
+ github: str = ''
202
+ description: str = ''
203
+ layers: dict[str, Any] = field(default_factory=dict)
204
+
205
+ def merge_dict(self, other: dict[str, Any], new_fields: bool = False) -> None:
206
+ key: str
207
+ value: Any
208
+
209
+ if 'layers' in other:
210
+ self.layers.update(other.pop('layers'))
211
+
212
+ for key, value in other.items():
213
+ if hasattr(layers, key) or key == 'Composite':
214
+ self.layers[key] = value
215
+ elif not hasattr(self, key) and not new_fields:
216
+ raise AttributeError(f'Unknown net config key ({key}) and new_fields is False')
217
+ elif hasattr(NetConfig, key) and isinstance(getattr(self, key), BaseConfig):
218
+ getattr(self, key).merge_dict(value, new_fields=new_fields)
219
+ elif hasattr(NetConfig, key):
220
+ setattr(self, key, value)
221
+ else:
222
+ log.getLogger(__name__).warning(f'Unknown net config key ({key})')
223
+
224
+
225
+ @dataclass
226
+ class Config(BaseConfig):
227
+ """
228
+ Dataclass to hold global network and layer configuration parameters.
229
+
230
+ Attributes
231
+ ----------
232
+ layers : list[dict[str, Any]]
233
+ List of layers
234
+ net : NetConfig
235
+ Network configuration
236
+ """
237
+ layers: list[dict[str, Any]] = field(default_factory=list)
238
+ net: NetConfig = field(default_factory=NetConfig)
239
+
240
+
241
+ __all__ = ['BaseConfig', 'NetConfig', 'Config', 'ConfigT']
@@ -0,0 +1,22 @@
1
+ """
2
+ Deprecated module for backwards compatibility
3
+ """
4
+ from warnings import warn
5
+
6
+ from netloader.transforms import (
7
+ BaseTransform,
8
+ Log,
9
+ MinClamp,
10
+ MultiTransform,
11
+ Normalise,
12
+ NumpyTensor,
13
+ )
14
+
15
+
16
+ warn(
17
+ 'Importing transforms from utils is deprecated, please use netloader.transforms',
18
+ DeprecationWarning,
19
+ stacklevel=2,
20
+ )
21
+
22
+ __all__ = ['BaseTransform', 'Log', 'MinClamp', 'MultiTransform', 'Normalise', 'NumpyTensor']
@@ -0,0 +1,130 @@
1
+ """
2
+ Type definitions.
3
+ """
4
+ from warnings import warn
5
+ from typing import Union, TypeVar, Any, Protocol, TypeAlias, ParamSpec, TYPE_CHECKING
6
+
7
+ from torch import Tensor
8
+ from numpy import ndarray
9
+
10
+ if TYPE_CHECKING:
11
+ from netloader.data import Data, DataList
12
+
13
+
14
+ ShapeLike: TypeAlias = list[int] | list[list[int]]
15
+ Param: TypeAlias = dict[str, Union[Tensor, 'Param']]
16
+ DataLike: TypeAlias = Union[ndarray, Tensor, 'Data[ArrayCT]']
17
+ ArrayLike: TypeAlias = ndarray | Tensor
18
+ TensorLike: TypeAlias = Union[Tensor, 'Data[Tensor]', 'DataList[Tensor | Data[Tensor]]']
19
+ NDArrayLike: TypeAlias = Union[ndarray, 'Data[ndarray]', 'DataList[ndarray | Data[ndarray]]']
20
+ DataListLike: TypeAlias = Union[DataLike, 'DataList[DataLike]']
21
+ TensorListLike: TypeAlias = Union[Tensor, 'DataList[Tensor]']
22
+ NDArrayListLike: TypeAlias = Union[ndarray, 'DataList[ndarray]']
23
+
24
+ T = TypeVar('T')
25
+ P = ParamSpec('P')
26
+ DataT = TypeVar('DataT', bound=DataLike)
27
+ ArrayT = TypeVar('ArrayT', bound=ArrayLike)
28
+ TensorT = TypeVar('TensorT', bound=TensorLike)
29
+ NDArrayT = TypeVar('NDArrayT', bound=NDArrayLike)
30
+ DataListT = TypeVar('DataListT', bound=DataListLike)
31
+ TensorListT = TypeVar('TensorListT', bound=TensorListLike)
32
+
33
+ LossCT = TypeVar('LossCT', float, dict[str, float])
34
+ DataCT = TypeVar('DataCT', ndarray, Tensor, 'Data[ndarray]', 'Data[Tensor]')
35
+ ArrayCT = TypeVar('ArrayCT', ndarray, Tensor)
36
+ TensorLossCT = TypeVar('TensorLossCT', Tensor, dict[str, Tensor])
37
+
38
+
39
+ class DatasetProtocol(Protocol[DataT]):
40
+ """
41
+ Protocol for datasets used in NetLoader
42
+
43
+ Attributes
44
+ ----------
45
+ extra : list[Any] | ndarray | None
46
+ Additional data for each sample in the dataset of length N with shape (N,...) and type Any
47
+ idxs : ndarray
48
+ Index for each sample in the dataset with shape (N) and type int
49
+ low_dim : ndarray | Tensor | None
50
+ Low dimensional data for each sample in the dataset with shape (N)
51
+ high_dim : ndarray | Tensor | object
52
+ High dimensional data for each sample in the dataset with shape (N), this is required
53
+ """
54
+ extra: list[Any] | ndarray | Tensor | None
55
+ idxs: ndarray
56
+ low_dim: DataT | None
57
+ high_dim: DataT | None
58
+
59
+ def __len__(self) -> int:
60
+ """
61
+ Returns the number of samples in the dataset
62
+
63
+ Returns
64
+ -------
65
+ int
66
+ Number of samples in the dataset
67
+ """
68
+
69
+ def __getitem__(self, idx: int) -> tuple[int, DataListT, DataListT, Any]:
70
+ """
71
+ Parameters
72
+ ----------
73
+ idx : int
74
+ Sample index
75
+
76
+ Returns
77
+ -------
78
+ tuple[int, DataListT, DataListT, Any]
79
+ Sample index, low dimensional data, high dimensional data, and extra data
80
+ """
81
+
82
+ def step(self, epoch: float) -> None:
83
+ """
84
+ Step the dataset for each training iteration.
85
+
86
+ Parameters
87
+ ----------
88
+ epoch : float
89
+ Current epoch number
90
+ """
91
+
92
+
93
+ DatasetT = TypeVar('DatasetT', bound=DatasetProtocol)
94
+
95
+
96
+ __all__ = [
97
+ 'DatasetProtocol',
98
+ 'Param',
99
+ 'DataLike',
100
+ 'ShapeLike',
101
+ 'ArrayLike',
102
+ 'TensorLike',
103
+ 'NDArrayLike',
104
+ 'DataListLike',
105
+ 'TensorListLike',
106
+ 'NDArrayListLike',
107
+ 'T',
108
+ 'P',
109
+ 'DataT',
110
+ 'ArrayT',
111
+ 'TensorT',
112
+ 'NDArrayT',
113
+ 'DatasetT',
114
+ 'DataListT',
115
+ 'TensorListT',
116
+ 'LossCT',
117
+ 'DataCT',
118
+ 'ArrayCT',
119
+ 'TensorLossCT',
120
+ ]
121
+
122
+ def __getattr__(name: str) -> Any:
123
+ if name == 'ArrayTC':
124
+ warn(
125
+ 'ArrayTC is deprecated, use ArrayCT instead',
126
+ DeprecationWarning,
127
+ stacklevel=2,
128
+ )
129
+ return ArrayCT
130
+ raise AttributeError(f"module {__name__} has no attribute {name}")