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.
- netloader/__init__.py +61 -0
- netloader/architectures/__init__.py +48 -0
- netloader/architectures/base.py +1350 -0
- netloader/architectures/encoder_decoder.py +630 -0
- netloader/architectures/flows.py +501 -0
- netloader/architectures/utils.py +179 -0
- netloader/data.py +1092 -0
- netloader/layers/__init__.py +88 -0
- netloader/layers/base.py +367 -0
- netloader/layers/blocks.py +145 -0
- netloader/layers/convolutional.py +1008 -0
- netloader/layers/flows.py +123 -0
- netloader/layers/linear.py +445 -0
- netloader/layers/misc.py +879 -0
- netloader/layers/multi_layer.py +470 -0
- netloader/layers/pooling.py +298 -0
- netloader/layers/recurrent.py +163 -0
- netloader/layers/utils.py +168 -0
- netloader/loss_funcs.py +201 -0
- netloader/models/__init__.py +22 -0
- netloader/models/convnext.py +582 -0
- netloader/models/misc.py +209 -0
- netloader/network.py +895 -0
- netloader/networks/__init__.py +48 -0
- netloader/schedulers.py +409 -0
- netloader/transforms.py +847 -0
- netloader/utils/__init__.py +46 -0
- netloader/utils/configs.py +241 -0
- netloader/utils/transforms.py +22 -0
- netloader/utils/types.py +130 -0
- netloader/utils/utils.py +677 -0
- netloader-3.11.0.dist-info/METADATA +59 -0
- netloader-3.11.0.dist-info/RECORD +36 -0
- netloader-3.11.0.dist-info/WHEEL +5 -0
- netloader-3.11.0.dist-info/licenses/LICENSE.txt +21 -0
- netloader-3.11.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Network layers that use the outputs from multiple layers.
|
|
3
|
+
"""
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
from typing import Any, cast
|
|
6
|
+
|
|
7
|
+
import torch
|
|
8
|
+
import numpy as np
|
|
9
|
+
from torch import Tensor
|
|
10
|
+
from numpy import ndarray
|
|
11
|
+
|
|
12
|
+
from netloader.utils.types import TensorListLike
|
|
13
|
+
from netloader.utils import Shapes, compare_versions
|
|
14
|
+
from netloader.layers.base import BaseMultiLayer, BaseLayer
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Concatenate(BaseMultiLayer):
|
|
18
|
+
"""
|
|
19
|
+
Constructs a concatenation layer to combine the outputs from two layers.
|
|
20
|
+
|
|
21
|
+
Attributes
|
|
22
|
+
----------
|
|
23
|
+
group : int
|
|
24
|
+
Layer group, if 0 it will always be used, else it will only be used if its group matches the
|
|
25
|
+
Networks
|
|
26
|
+
description : str
|
|
27
|
+
Description of the layer
|
|
28
|
+
"""
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
net_check: bool,
|
|
32
|
+
layer: int | list[int],
|
|
33
|
+
shapes: Shapes,
|
|
34
|
+
check_shapes: Shapes,
|
|
35
|
+
*,
|
|
36
|
+
checkpoint: bool = False,
|
|
37
|
+
dim: int = 0,
|
|
38
|
+
**kwargs: Any) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
net_check : bool
|
|
43
|
+
If layer index should be relative to checkpoint layers
|
|
44
|
+
layer : int | list[int]
|
|
45
|
+
Layer index(es) to concatenate the previous layer output with
|
|
46
|
+
shapes : Shapes
|
|
47
|
+
Shape of the outputs from each layer
|
|
48
|
+
check_shapes : Shapes
|
|
49
|
+
Shape of the outputs from each checkpoint
|
|
50
|
+
checkpoint : bool, Optional
|
|
51
|
+
If layer index should be relative to checkpoint layers or network layers, if checkpoints
|
|
52
|
+
in net is True, layer will always be relative to checkpoints, default = False
|
|
53
|
+
dim : int, Optional
|
|
54
|
+
Dimension to concatenate to, default = 0
|
|
55
|
+
**kwargs
|
|
56
|
+
Leftover parameters to pass to base layer for checking
|
|
57
|
+
"""
|
|
58
|
+
super().__init__(net_check, layer, shapes, check_shapes, checkpoint=checkpoint, **kwargs)
|
|
59
|
+
self._dim: int = dim
|
|
60
|
+
target: list[int]
|
|
61
|
+
shape: list[int] = self._shapes[0]
|
|
62
|
+
|
|
63
|
+
# If tensors can be concatenated along the specified dimension
|
|
64
|
+
for target in self._shapes[1:]:
|
|
65
|
+
if not self._check_concatenation(shape, target):
|
|
66
|
+
raise ValueError(f'Input shape ({shape}) does not match the target '
|
|
67
|
+
f'shape ({target}) from output shapes {self._shapes[1:]} in '
|
|
68
|
+
f"{'checkpoints' if self._checkpoint else 'layers'} "
|
|
69
|
+
f"{self._layer} for concatenation over dimension {self._dim}")
|
|
70
|
+
|
|
71
|
+
shape[self._dim] += target[self._dim]
|
|
72
|
+
|
|
73
|
+
shapes.append(shape)
|
|
74
|
+
|
|
75
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
76
|
+
return super().__getstate__() | {'dim': self._dim}
|
|
77
|
+
|
|
78
|
+
def _check_concatenation(self, shape1: list[int], shape2: list[int]) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
Checks if input shape and target shape are compatible for concatenation.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
shape1 : list[int]
|
|
85
|
+
First shape
|
|
86
|
+
shape2 : list[int]
|
|
87
|
+
Second shape
|
|
88
|
+
|
|
89
|
+
Returns
|
|
90
|
+
-------
|
|
91
|
+
bool
|
|
92
|
+
Whether the shapes are compatible for concatenation
|
|
93
|
+
"""
|
|
94
|
+
if ((shape2[:self._dim] + (shape2[self._dim + 1:] if self._dim != -1 else []) !=
|
|
95
|
+
shape1[:self._dim] + (shape1[self._dim + 1:] if self._dim != -1 else [])) or
|
|
96
|
+
(len(shape2) != len(shape1))):
|
|
97
|
+
return False
|
|
98
|
+
return True
|
|
99
|
+
|
|
100
|
+
def forward(
|
|
101
|
+
self,
|
|
102
|
+
x: TensorListLike,
|
|
103
|
+
outputs: list[TensorListLike],
|
|
104
|
+
checkpoints: list[TensorListLike],
|
|
105
|
+
*_: Any,
|
|
106
|
+
**__: Any) -> Tensor:
|
|
107
|
+
"""
|
|
108
|
+
Forward pass of the concatenation layer.
|
|
109
|
+
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
x : Tensor
|
|
113
|
+
Input tensor of shape (N,...) and type float, where N is the batch size
|
|
114
|
+
outputs : list[TensorListLike]
|
|
115
|
+
Output from each layer with tensors of shape (N,...) and type float
|
|
116
|
+
checkpoints : list[TensorListLike]
|
|
117
|
+
Output from each checkpoint with tensors of shape (N,...) and type float
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
Tensor
|
|
122
|
+
Output tensor of shape (N,...) and type float
|
|
123
|
+
"""
|
|
124
|
+
return torch.cat(
|
|
125
|
+
list(super().forward(x, outputs=outputs, checkpoints=checkpoints)),
|
|
126
|
+
dim=self._dim + 1 if self._dim >= 0 else self._dim,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def extra_repr(self) -> str:
|
|
130
|
+
"""
|
|
131
|
+
Displays layer parameters when printing the network.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
str
|
|
136
|
+
Layer parameters
|
|
137
|
+
"""
|
|
138
|
+
return f'{super().extra_repr()}, dim={self._dim}'
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class Pack(BaseMultiLayer):
|
|
142
|
+
"""
|
|
143
|
+
Constructs a packing layer to combine the output from the previous layer with the output from
|
|
144
|
+
a specified layer into a DataList.
|
|
145
|
+
|
|
146
|
+
Attributes
|
|
147
|
+
----------
|
|
148
|
+
group : int
|
|
149
|
+
Layer group, if 0 it will always be used, else it will only be used if its group matches the
|
|
150
|
+
Networks
|
|
151
|
+
description : str
|
|
152
|
+
Description of the layer
|
|
153
|
+
"""
|
|
154
|
+
def __init__(
|
|
155
|
+
self,
|
|
156
|
+
net_check: bool,
|
|
157
|
+
shapes: Shapes,
|
|
158
|
+
check_shapes: Shapes,
|
|
159
|
+
*,
|
|
160
|
+
checkpoint: bool = False,
|
|
161
|
+
layer: int | list[int] | None = None,
|
|
162
|
+
**kwargs: Any) -> None:
|
|
163
|
+
"""
|
|
164
|
+
Parameters
|
|
165
|
+
----------
|
|
166
|
+
net_check : bool
|
|
167
|
+
If layer index should be relative to checkpoint layers
|
|
168
|
+
shapes : Shapes
|
|
169
|
+
Shape of the outputs from each layer
|
|
170
|
+
check_shapes : Shapes
|
|
171
|
+
Shape of the outputs from each checkpoint
|
|
172
|
+
checkpoint : bool, Optional
|
|
173
|
+
If layer index should be relative to checkpoint layers, default = False
|
|
174
|
+
layer : int | None, Optional
|
|
175
|
+
Layer index to pack with the previous layer, if layer is None, then only the last layer
|
|
176
|
+
will be packed
|
|
177
|
+
**kwargs
|
|
178
|
+
Leftover parameters to pass to base layer for checking
|
|
179
|
+
"""
|
|
180
|
+
super().__init__(
|
|
181
|
+
net_check,
|
|
182
|
+
layer or 0,
|
|
183
|
+
shapes,
|
|
184
|
+
check_shapes,
|
|
185
|
+
checkpoint=checkpoint,
|
|
186
|
+
**kwargs,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
if layer is None:
|
|
190
|
+
self._layer = None
|
|
191
|
+
self._shapes = self._shape_flatten(deepcopy(shapes.get(-1, True)))
|
|
192
|
+
|
|
193
|
+
shapes.append(self._shapes)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class Shortcut(BaseMultiLayer):
|
|
197
|
+
"""
|
|
198
|
+
Constructs a shortcut layer to add the outputs from two layers.
|
|
199
|
+
|
|
200
|
+
Attributes
|
|
201
|
+
----------
|
|
202
|
+
group : int
|
|
203
|
+
Layer group, if 0 it will always be used, else it will only be used if its group matches the
|
|
204
|
+
Networks
|
|
205
|
+
description : str
|
|
206
|
+
Description of the layer
|
|
207
|
+
"""
|
|
208
|
+
def __init__(
|
|
209
|
+
self,
|
|
210
|
+
net_check: bool,
|
|
211
|
+
layer: int | list[int],
|
|
212
|
+
shapes: Shapes,
|
|
213
|
+
check_shapes: Shapes,
|
|
214
|
+
*,
|
|
215
|
+
checkpoint: bool = False,
|
|
216
|
+
**kwargs: Any) -> None:
|
|
217
|
+
"""
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
net_check : bool
|
|
221
|
+
If layer index should be relative to checkpoint layers
|
|
222
|
+
layer : int | list[int]
|
|
223
|
+
Layer index(es) to add the previous layer output with
|
|
224
|
+
shapes : Shapes
|
|
225
|
+
Shape of the outputs from each layer
|
|
226
|
+
check_shapes : Shapes
|
|
227
|
+
Shape of the outputs from each checkpoint
|
|
228
|
+
checkpoint : bool, Optional
|
|
229
|
+
If layer index should be relative to checkpoint layers or network layers, if checkpoints
|
|
230
|
+
in net is True, layer will always be relative to checkpoints, default = False
|
|
231
|
+
**kwargs
|
|
232
|
+
Leftover parameters to pass to base layer for checking
|
|
233
|
+
"""
|
|
234
|
+
super().__init__(net_check, layer, shapes, check_shapes, checkpoint=checkpoint, **kwargs)
|
|
235
|
+
idxs: ndarray
|
|
236
|
+
mask: ndarray
|
|
237
|
+
shapes_: ndarray = np.array(self._shapes)
|
|
238
|
+
shape: ndarray = shapes_[0]
|
|
239
|
+
|
|
240
|
+
mask = (shapes_[0] != 1) & (shapes_[1:] != 1)
|
|
241
|
+
self._check_addition(shapes_[0], shapes_[1:], mask)
|
|
242
|
+
|
|
243
|
+
# If input has any dimensions of length one, output will take the target dimension
|
|
244
|
+
if 1 in shape:
|
|
245
|
+
idxs = np.where(shape == 1)[0]
|
|
246
|
+
shape[idxs] = np.max(shapes_[:, idxs], axis=0)
|
|
247
|
+
|
|
248
|
+
shapes.append(shape.tolist())
|
|
249
|
+
|
|
250
|
+
def _check_addition(self, shape: ndarray, target: ndarray, mask: ndarray) -> None:
|
|
251
|
+
"""
|
|
252
|
+
Checks if input shape and target shape are compatible for addition.
|
|
253
|
+
|
|
254
|
+
Parameters
|
|
255
|
+
----------
|
|
256
|
+
shape : ndarray
|
|
257
|
+
Input shape
|
|
258
|
+
mask : ndarray
|
|
259
|
+
Mask for dimensions with size of one in both input and target
|
|
260
|
+
"""
|
|
261
|
+
if np.ndim(target) == 2 and all(
|
|
262
|
+
np.array_equal(shape[mask[i]], target[i, mask[i]]) for i in range(len(target))):
|
|
263
|
+
return
|
|
264
|
+
if np.ndim(target) == 1 and np.array_equal(shape[mask], target[mask]):
|
|
265
|
+
return
|
|
266
|
+
raise ValueError(f'Input shape {shape} is not compatible with target shape {target} in '
|
|
267
|
+
f"{'checkpoint' if self._checkpoint else 'layer'} "
|
|
268
|
+
f'{self._layer} for addition')
|
|
269
|
+
|
|
270
|
+
def forward(
|
|
271
|
+
self,
|
|
272
|
+
x: Tensor,
|
|
273
|
+
outputs: list[TensorListLike],
|
|
274
|
+
checkpoints: list[TensorListLike],
|
|
275
|
+
*_: Any,
|
|
276
|
+
**__: Any) -> Tensor:
|
|
277
|
+
"""
|
|
278
|
+
Forward pass of the shortcut layer
|
|
279
|
+
|
|
280
|
+
Parameters
|
|
281
|
+
----------
|
|
282
|
+
x : Tensor
|
|
283
|
+
Input tensor of shape (N,...) and type float, where N is the batch size
|
|
284
|
+
outputs : list[TensorListLike]
|
|
285
|
+
Output from each layer with tensors of shape (N,...) and type float
|
|
286
|
+
checkpoints : list[TensorListLike]
|
|
287
|
+
Output from each checkpoint with tensors of shape (N,...) and type float
|
|
288
|
+
|
|
289
|
+
Returns
|
|
290
|
+
-------
|
|
291
|
+
Tensor
|
|
292
|
+
Output tensor of shape (N,...) and type float
|
|
293
|
+
"""
|
|
294
|
+
return torch.add(*super().forward(
|
|
295
|
+
x,
|
|
296
|
+
outputs=outputs,
|
|
297
|
+
checkpoints=checkpoints,
|
|
298
|
+
).get_data())
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class Skip(BaseMultiLayer):
|
|
302
|
+
"""
|
|
303
|
+
Bypasses previous layers by retrieving the output from the defined layer.
|
|
304
|
+
|
|
305
|
+
Attributes
|
|
306
|
+
----------
|
|
307
|
+
group : int
|
|
308
|
+
Layer group, if 0 it will always be used, else it will only be used if its group matches the
|
|
309
|
+
Networks
|
|
310
|
+
description : str
|
|
311
|
+
Description of the layer
|
|
312
|
+
"""
|
|
313
|
+
def __init__(
|
|
314
|
+
self,
|
|
315
|
+
net_check: bool,
|
|
316
|
+
layer: int,
|
|
317
|
+
shapes: Shapes,
|
|
318
|
+
check_shapes: Shapes,
|
|
319
|
+
*,
|
|
320
|
+
checkpoint: bool = False,
|
|
321
|
+
**kwargs: Any) -> None:
|
|
322
|
+
"""
|
|
323
|
+
Parameters
|
|
324
|
+
----------
|
|
325
|
+
net_check : bool
|
|
326
|
+
If layer index should be relative to checkpoint layers
|
|
327
|
+
layer : int
|
|
328
|
+
Layer index to get the output from
|
|
329
|
+
shapes : Shapes
|
|
330
|
+
Shape of the outputs from each layer
|
|
331
|
+
check_shapes : Shapes
|
|
332
|
+
Shape of the outputs from each checkpoint
|
|
333
|
+
checkpoint : bool, Optional
|
|
334
|
+
If layer index should be relative to checkpoint layers or network layers, if checkpoints
|
|
335
|
+
in net is True, layer will always be relative to checkpoints, default = False
|
|
336
|
+
**kwargs
|
|
337
|
+
Leftover parameters to pass to base layer for checking
|
|
338
|
+
"""
|
|
339
|
+
assert isinstance(layer, int)
|
|
340
|
+
super().__init__(net_check, layer, shapes, check_shapes, checkpoint=checkpoint, **kwargs)
|
|
341
|
+
shapes.append(cast(list[int], self._target))
|
|
342
|
+
|
|
343
|
+
def forward(
|
|
344
|
+
self,
|
|
345
|
+
*_: Any,
|
|
346
|
+
outputs: list[TensorListLike],
|
|
347
|
+
checkpoints: list[TensorListLike],
|
|
348
|
+
**__: Any) -> TensorListLike:
|
|
349
|
+
"""
|
|
350
|
+
Forward pass of the skip layer.
|
|
351
|
+
|
|
352
|
+
Parameters
|
|
353
|
+
----------
|
|
354
|
+
outputs : list[TensorListLike]
|
|
355
|
+
Output from each layer with tensors of shape (N,...) and type float
|
|
356
|
+
checkpoints : list[TensorListLike]
|
|
357
|
+
Output from each checkpoint with tensors of shape (N,...) and type float
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
TensorListLike
|
|
362
|
+
Output with tensors of shape (N,...) and type float
|
|
363
|
+
"""
|
|
364
|
+
return (checkpoints if self._checkpoint else outputs)[self._layer]
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
class Unpack(BaseLayer):
|
|
368
|
+
"""
|
|
369
|
+
Enables a list of Tensors as input into the network, then selects which Tensor in the list to
|
|
370
|
+
output.
|
|
371
|
+
"""
|
|
372
|
+
def __init__(
|
|
373
|
+
self,
|
|
374
|
+
net_check: bool,
|
|
375
|
+
index: int,
|
|
376
|
+
shapes: Shapes,
|
|
377
|
+
check_shapes: Shapes,
|
|
378
|
+
*,
|
|
379
|
+
checkpoint: bool = False,
|
|
380
|
+
layer: int | None = None,
|
|
381
|
+
**kwargs: Any) -> None:
|
|
382
|
+
"""
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
net_check : bool
|
|
386
|
+
If layer index should be relative to checkpoint layers
|
|
387
|
+
index : int
|
|
388
|
+
Index of input Tensor list
|
|
389
|
+
shapes : Shapes
|
|
390
|
+
Shape of the outputs from each layer
|
|
391
|
+
check_shapes : Shapes
|
|
392
|
+
Shape of the outputs from each checkpoint
|
|
393
|
+
checkpoint : bool, Optional
|
|
394
|
+
If layer index should be relative to checkpoint layers or network layers, if checkpoints
|
|
395
|
+
in net is True, layer will always be relative to checkpoints, default = False
|
|
396
|
+
layer : int | None, Optional
|
|
397
|
+
Layer index to get the output from if checkpoint is True, default = None
|
|
398
|
+
**kwargs
|
|
399
|
+
Leftover parameters to pass to base layer for checking
|
|
400
|
+
"""
|
|
401
|
+
super().__init__(**kwargs)
|
|
402
|
+
self._checkpoint: bool = checkpoint or net_check
|
|
403
|
+
self._layer: int | None = layer \
|
|
404
|
+
if layer or compare_versions(self._ver, '3.11.0') else 0
|
|
405
|
+
self._idx: int = index
|
|
406
|
+
|
|
407
|
+
if self._layer is None:
|
|
408
|
+
shapes.append(shapes[(-1, self._idx)].copy())
|
|
409
|
+
else:
|
|
410
|
+
shapes.append(
|
|
411
|
+
(check_shapes if self._checkpoint else shapes)[(self._layer, self._idx)].copy(),
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
415
|
+
return super().__getstate__() | {
|
|
416
|
+
'checkpoint': self._checkpoint,
|
|
417
|
+
'layer': self._layer,
|
|
418
|
+
'index': self._idx,
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
def forward(
|
|
422
|
+
self,
|
|
423
|
+
x: TensorListLike,
|
|
424
|
+
outputs: list[TensorListLike],
|
|
425
|
+
checkpoints: list[TensorListLike],
|
|
426
|
+
**__: Any) -> Tensor:
|
|
427
|
+
"""
|
|
428
|
+
Forward pass of the unpack layer.
|
|
429
|
+
|
|
430
|
+
Parameters
|
|
431
|
+
----------
|
|
432
|
+
outputs : list[TensorListLike]
|
|
433
|
+
Output from each layer with tensors of shape (N,...) and type float, where N is the
|
|
434
|
+
batch size
|
|
435
|
+
checkpoints : list[TensorListLike]
|
|
436
|
+
Output from each checkpoint with tensors of shape (N,...) and type float, where N is the
|
|
437
|
+
batch size
|
|
438
|
+
|
|
439
|
+
Returns
|
|
440
|
+
-------
|
|
441
|
+
Tensor
|
|
442
|
+
Output tensor with shape (N,...) and type float
|
|
443
|
+
"""
|
|
444
|
+
if self._layer is None:
|
|
445
|
+
self._check_num_outputs(
|
|
446
|
+
x,
|
|
447
|
+
single=False,
|
|
448
|
+
)
|
|
449
|
+
return cast(Tensor, x.get(self._idx, True))
|
|
450
|
+
|
|
451
|
+
inputs: TensorListLike = (checkpoints if self._checkpoint else outputs)[self._layer]
|
|
452
|
+
self._check_num_outputs(
|
|
453
|
+
inputs,
|
|
454
|
+
single=False,
|
|
455
|
+
)
|
|
456
|
+
return cast(Tensor, inputs.get(self._idx, True))
|
|
457
|
+
|
|
458
|
+
def extra_repr(self) -> str:
|
|
459
|
+
"""
|
|
460
|
+
Displays layer parameters when printing the network
|
|
461
|
+
|
|
462
|
+
Returns
|
|
463
|
+
-------
|
|
464
|
+
str
|
|
465
|
+
Layer parameters
|
|
466
|
+
"""
|
|
467
|
+
return f'index={self._idx}, checkpoint={bool(self._checkpoint)}, layer={self._layer}'
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
__all__ = ['Concatenate', 'Pack', 'Shortcut', 'Skip', 'Unpack']
|