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,201 @@
1
+ """
2
+ Loss function classes for safe saving
3
+ """
4
+ from typing import Callable, Any
5
+
6
+ import torch
7
+ from torch import nn, Tensor
8
+
9
+
10
+ class BaseLoss(nn.Module):
11
+ """
12
+ A base class for loss functions.
13
+
14
+ This class is used to add all loss function classes to the list of safe PyTorch classes when
15
+ loading saved architectures.
16
+ """
17
+ def __init__(self, loss_func: type, *args: Any, **kwargs: Any) -> None:
18
+ """
19
+ Parameters
20
+ ----------
21
+ loss_func : type
22
+ Loss function class to be used
23
+
24
+ *args
25
+ Optional arguments to be passed to loss_func
26
+ **kwargs
27
+ Optional keyword arguments to be passed to loss_func
28
+ """
29
+ super().__init__()
30
+ self._args: tuple[Any, ...] = args
31
+ self._kwargs: dict[str, Any] = kwargs
32
+ self._loss_func: Callable = loss_func(*self._args, **self._kwargs)
33
+
34
+ # Adds all loss classes to list of safe PyTorch classes when loading saved architectures
35
+ torch.serialization.add_safe_globals([self.__class__])
36
+
37
+ def __repr__(self) -> str:
38
+ """
39
+ Returns a string representation of the loss function.
40
+
41
+ Returns
42
+ -------
43
+ str
44
+ String representation of the loss function
45
+ """
46
+ key: str
47
+ args: str
48
+ extra_repr: str
49
+ val: Any
50
+
51
+ args = ', '.join(repr(val) for val in self._args)
52
+ args += ', '.join(f'{key}={repr(val)}' for key, val in self._kwargs.items())
53
+ args += (', ' if args else '') + extra_repr if (extra_repr := self.extra_repr()) else ''
54
+ return f'{self.__class__.__name__}({args})'
55
+
56
+ def __getstate__(self) -> dict[str, Any]:
57
+ """
58
+ Returns a dictionary containing the state of the loss function for pickling.
59
+
60
+ Returns
61
+ -------
62
+ dict[str, Any]
63
+ Dictionary containing the state of the loss function
64
+ """
65
+ return {'args': self._args, 'kwargs': self._kwargs}
66
+
67
+ def __setstate__(self, state: dict[str, Any]) -> None:
68
+ """
69
+ Sets the state of the loss function for pickling.
70
+
71
+ Parameters
72
+ ----------
73
+ state : dict[str, Any]
74
+ Dictionary containing the state of the loss function
75
+ """
76
+ super().__init__()
77
+ self._args = state['args']
78
+ self._kwargs = state['kwargs']
79
+
80
+ def forward(self, output: Tensor, target: Tensor) -> Tensor:
81
+ """
82
+ Forward pass of the loss function.
83
+
84
+ Parameters
85
+ ----------
86
+ output : Tensor
87
+ Output from the network with shape (N,...), where N is the number of elements
88
+ N predictions from the network
89
+ target : Tensor
90
+ Target values with shape (N,...)
91
+
92
+ Returns
93
+ -------
94
+ Tensor
95
+ Loss value with shape (1)
96
+ """
97
+ return self._loss_func(output, target)
98
+
99
+
100
+ class GeneralLoss(BaseLoss):
101
+ """
102
+ A general loss function that can be used with any torch.nn loss function class.
103
+ """
104
+ def __init__(self, loss_func: str, *args: Any, **kwargs: Any) -> None:
105
+ """
106
+ Parameters
107
+ ----------
108
+ loss_func : str
109
+ Loss function name from torch.nn
110
+ *args
111
+ Optional arguments to be passed to loss_func
112
+ **kwargs
113
+ Optional keyword arguments to be passed to loss_func
114
+ """
115
+ self._name: str = loss_func
116
+ super().__init__(getattr(nn, self._name), *args, **kwargs)
117
+
118
+ def __getstate__(self) -> dict[str, Any]:
119
+ return super().__getstate__() | {'name': self._name}
120
+
121
+ def __setstate__(self, state: dict[str, Any]) -> None:
122
+ super().__setstate__(state)
123
+ self._name = state['name']
124
+ self._loss_func = getattr(nn, self._name)(*self._args, **self._kwargs)
125
+
126
+ def extra_repr(self) -> str:
127
+ return f'loss_func={repr(self._name)}'
128
+
129
+
130
+ class CrossEntropyLoss(GeneralLoss):
131
+ """
132
+ Cross entropy loss function.
133
+ """
134
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
135
+ """
136
+ Parameters
137
+ ----------
138
+ *args
139
+ Optional arguments to be passed to CrossEntropyLoss
140
+ **kwargs
141
+ Optional keyword arguments to be passed to CrossEntropyLoss
142
+ """
143
+ super().__init__('CrossEntropyLoss', *args, **kwargs)
144
+
145
+
146
+ class GaussianNLLLoss(GeneralLoss):
147
+ """
148
+ Gaussian negative log likelihood loss function.
149
+ """
150
+ def __init__(self, *args: Any, dim: int = 1, **kwargs: Any) -> None:
151
+ """
152
+ Parameters
153
+ ----------
154
+ dim : int, Optional
155
+ Dimension of the target that contains the mean and uncertainty, default = 1
156
+ *args
157
+ Optional arguments to be passed to GaussianNLLLoss
158
+ **kwargs
159
+ Optional keyword arguments to be passed to GaussianNLLLoss
160
+ """
161
+ super().__init__('GaussianNLLLoss', *args, **kwargs)
162
+ self._dim: int = dim
163
+
164
+ def __getstate__(self) -> dict[str, Any]:
165
+ return super().__getstate__() | {'dim': self._dim}
166
+
167
+ def __setstate__(self, state: dict[str, Any]) -> None:
168
+ super().__setstate__(state)
169
+ self._dim = state['dim']
170
+
171
+ def extra_repr(self) -> str:
172
+ return f'dim={self._dim}'
173
+
174
+ def forward(self, output: Tensor, target: Tensor) -> Tensor:
175
+ if target.shape[self._dim] != 2 or output.shape[self._dim] != 1:
176
+ raise ValueError(f'Target shape must be 2 and output shape must be 1 at dim '
177
+ f'{self._dim}, got target shape {target.shape} and output shape '
178
+ f'{output.shape}')
179
+
180
+ idx: list[list[int] | slice] = [slice(None)] * target.dim()
181
+ idx[self._dim] = [0, 1]
182
+ return self._loss_func(output[*idx][0], target[*idx][0], target[*idx][1] ** 2)
183
+
184
+
185
+ class MSELoss(GeneralLoss):
186
+ """
187
+ Mean Squared Error (MSE) loss function.
188
+ """
189
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
190
+ """
191
+ Parameters
192
+ ----------
193
+ *args
194
+ Optional arguments to be passed to MSELoss
195
+ **kwargs
196
+ Optional keyword arguments to be passed to MSELoss
197
+ """
198
+ super().__init__('MSELoss', *args, **kwargs)
199
+
200
+
201
+ __all__ = ['BaseLoss', 'CrossEntropyLoss', 'GaussianNLLLoss', GeneralLoss, 'MSELoss']
@@ -0,0 +1,22 @@
1
+ """
2
+ Collects all classes in the models module
3
+ """
4
+ from netloader.models.misc import MultiNetwork
5
+ from netloader.models.convnext import (
6
+ ConvNeXt,
7
+ ConvNeXtTiny,
8
+ ConvNeXtBase,
9
+ ConvNeXtSmall,
10
+ ConvNeXtLarge,
11
+ ConvNeXtXLarge,
12
+ )
13
+
14
+ __all__ = [
15
+ 'ConvNeXt',
16
+ 'ConvNeXtTiny',
17
+ 'ConvNeXtBase',
18
+ 'MultiNetwork',
19
+ 'ConvNeXtSmall',
20
+ 'ConvNeXtLarge',
21
+ 'ConvNeXtXLarge',
22
+ ]