learnergy 2.0.0__tar.gz → 2.0.2__tar.gz

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.
Files changed (74) hide show
  1. learnergy-2.0.2/AGENTS.md +5 -0
  2. learnergy-2.0.2/CONVENTIONS.md +75 -0
  3. learnergy-2.0.2/MANIFEST.in +1 -0
  4. {learnergy-2.0.0 → learnergy-2.0.2}/PKG-INFO +32 -4
  5. {learnergy-2.0.0 → learnergy-2.0.2}/README.md +31 -3
  6. learnergy-2.0.2/learnergy/__init__.py +6 -0
  7. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/core/__init__.py +3 -0
  8. learnergy-2.0.2/learnergy/core/dataset.py +68 -0
  9. learnergy-2.0.2/learnergy/core/model.py +74 -0
  10. learnergy-2.0.2/learnergy/math/__init__.py +4 -0
  11. learnergy-2.0.2/learnergy/math/metrics.py +39 -0
  12. learnergy-2.0.2/learnergy/math/scale.py +27 -0
  13. learnergy-2.0.2/learnergy/models/__init__.py +4 -0
  14. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/bernoulli/__init__.py +3 -0
  15. learnergy-2.0.2/learnergy/models/bernoulli/conv_rbm.py +346 -0
  16. learnergy-2.0.2/learnergy/models/bernoulli/discriminative_rbm.py +400 -0
  17. learnergy-2.0.2/learnergy/models/bernoulli/dropout_rbm.py +164 -0
  18. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/bernoulli/e_dropout_rbm.py +61 -77
  19. learnergy-2.0.2/learnergy/models/bernoulli/rbm.py +357 -0
  20. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/deep/__init__.py +3 -0
  21. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/deep/conv_dbn.py +95 -42
  22. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/deep/dbn.py +94 -38
  23. learnergy-2.0.2/learnergy/models/deep/residual_dbn.py +167 -0
  24. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/extra/__init__.py +3 -0
  25. learnergy-2.0.2/learnergy/models/extra/sigmoid_rbm.py +63 -0
  26. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/models/gaussian/__init__.py +3 -0
  27. learnergy-2.0.2/learnergy/models/gaussian/_normalization.py +13 -0
  28. learnergy-2.0.2/learnergy/models/gaussian/gaussian_conv_rbm.py +195 -0
  29. learnergy-2.0.2/learnergy/models/gaussian/gaussian_rbm.py +506 -0
  30. learnergy-2.0.2/learnergy/utils/__init__.py +4 -0
  31. learnergy-2.0.2/learnergy/utils/constants.py +6 -0
  32. learnergy-2.0.2/learnergy/utils/exception.py +99 -0
  33. learnergy-2.0.2/learnergy/utils/logging.py +67 -0
  34. learnergy-2.0.2/learnergy/visual/__init__.py +4 -0
  35. learnergy-2.0.2/learnergy/visual/convergence.py +65 -0
  36. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy/visual/image.py +43 -14
  37. learnergy-2.0.2/learnergy/visual/tensor.py +66 -0
  38. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy.egg-info/PKG-INFO +32 -4
  39. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy.egg-info/SOURCES.txt +4 -0
  40. {learnergy-2.0.0 → learnergy-2.0.2}/pyproject.toml +3 -2
  41. {learnergy-2.0.0 → learnergy-2.0.2}/tests/test_bernoulli.py +65 -3
  42. {learnergy-2.0.0 → learnergy-2.0.2}/tests/test_core.py +9 -1
  43. {learnergy-2.0.0 → learnergy-2.0.2}/tests/test_deep.py +51 -3
  44. learnergy-2.0.2/tests/test_gaussian.py +215 -0
  45. learnergy-2.0.2/tests/test_utilities.py +144 -0
  46. learnergy-2.0.0/learnergy/__init__.py +0 -5
  47. learnergy-2.0.0/learnergy/core/dataset.py +0 -48
  48. learnergy-2.0.0/learnergy/core/model.py +0 -58
  49. learnergy-2.0.0/learnergy/math/__init__.py +0 -1
  50. learnergy-2.0.0/learnergy/math/metrics.py +0 -21
  51. learnergy-2.0.0/learnergy/math/scale.py +0 -14
  52. learnergy-2.0.0/learnergy/models/__init__.py +0 -1
  53. learnergy-2.0.0/learnergy/models/bernoulli/conv_rbm.py +0 -359
  54. learnergy-2.0.0/learnergy/models/bernoulli/discriminative_rbm.py +0 -404
  55. learnergy-2.0.0/learnergy/models/bernoulli/dropout_rbm.py +0 -191
  56. learnergy-2.0.0/learnergy/models/bernoulli/rbm.py +0 -364
  57. learnergy-2.0.0/learnergy/models/deep/residual_dbn.py +0 -130
  58. learnergy-2.0.0/learnergy/models/extra/sigmoid_rbm.py +0 -34
  59. learnergy-2.0.0/learnergy/models/gaussian/gaussian_conv_rbm.py +0 -131
  60. learnergy-2.0.0/learnergy/models/gaussian/gaussian_rbm.py +0 -567
  61. learnergy-2.0.0/learnergy/utils/__init__.py +0 -1
  62. learnergy-2.0.0/learnergy/utils/constants.py +0 -3
  63. learnergy-2.0.0/learnergy/utils/exception.py +0 -40
  64. learnergy-2.0.0/learnergy/utils/logging.py +0 -37
  65. learnergy-2.0.0/learnergy/visual/__init__.py +0 -1
  66. learnergy-2.0.0/learnergy/visual/convergence.py +0 -41
  67. learnergy-2.0.0/learnergy/visual/tensor.py +0 -32
  68. learnergy-2.0.0/tests/test_gaussian.py +0 -73
  69. learnergy-2.0.0/tests/test_utilities.py +0 -75
  70. {learnergy-2.0.0 → learnergy-2.0.2}/LICENSE +0 -0
  71. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy.egg-info/dependency_links.txt +0 -0
  72. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy.egg-info/requires.txt +0 -0
  73. {learnergy-2.0.0 → learnergy-2.0.2}/learnergy.egg-info/top_level.txt +0 -0
  74. {learnergy-2.0.0 → learnergy-2.0.2}/setup.cfg +0 -0
@@ -0,0 +1,5 @@
1
+ # Contributor and agent guidance
2
+
3
+ Read and follow [CONVENTIONS.md](CONVENTIONS.md) before changing this repository.
4
+ Preserve public behavior and checkpoint compatibility unless the task explicitly changes them.
5
+ Use the existing validation tools and keep unrelated or concurrent work intact.
@@ -0,0 +1,75 @@
1
+ # Learnergy conventions
2
+
3
+ Learnergy adopts the applicable code-style rules from cpmux's phitrain-derived conventions.
4
+ These rules govern new code and convention updates without authorizing unrelated algorithm or API changes.
5
+
6
+ ## Compatibility and scope
7
+
8
+ - Keep the current Python 3.11 minimum. Use the requested modern Python idioms where they are compatible with it.
9
+ - Preserve public imports, model names, constructor options, return values, normalization policies, and checkpoint state.
10
+ - Keep Learnergy's domain-oriented package layout and public package exports. cpmux's empty package initializers,
11
+ CLI architecture, Pydantic choices, and test-layout migration are not part of this adoption.
12
+ - Tests remain grouped by the existing model families. Runtime validation rules do not prohibit test assertions.
13
+
14
+ ## Code style
15
+
16
+ - Use `X | None`, builtin generics such as `list[str]`, and ABCs from `collections.abc`.
17
+ Import only typing-specific constructs such as `Any` and `Literal` from `typing`. (R2)
18
+ - Start every Python file with the project header:
19
+
20
+ ```python
21
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
22
+ # Licensed under the Apache License, Version 2.0.
23
+ ```
24
+
25
+ - Keep imports top-level, absolute, and grouped as standard library, third-party, then Learnergy imports.
26
+ - Use double-quoted strings. Code formatting and readable prose use a 120-character limit. (R9)
27
+ - Public functions, regular classes, and explicit constructors have Google-style docstrings.
28
+ Use a single-sentence summary and one-line `Args:`, `Returns:`, and `Raises:` entries as applicable.
29
+ Do not put semicolons or `defaults to ...` tails in entries. (R3, R13)
30
+ - A regular class has a one-sentence class summary. Constructor arguments belong on `__init__`, not the class.
31
+ Preserve mathematical references and substantive behavioral notes in module or operation documentation.
32
+ - Multiline docstrings have one blank line before the closing triple quotes and one blank line after them
33
+ before code or fields. Keep class and module summaries on one line when they need no other content,
34
+ matching cpmux's examples and Black's normalization.
35
+ - Private helpers have no docstrings. Framework-dispatched overrides such as `forward`, `__getitem__`, and
36
+ `__len__` have no docstrings. Document their relevant contracts in public sampling methods, constructors,
37
+ module documentation, or the user guide instead.
38
+ - Data classes without an explicit constructor document each field on one line in an `Attributes:` section.
39
+ This rule does not require introducing data classes into existing models.
40
+ - Public contracts describe tensor shapes, tuple element order, mutation, history, normalization, gradient
41
+ boundaries, and failure behavior where relevant. An annotation is not runtime validation.
42
+ - Obtain library loggers with `get_logger(__name__)` from `learnergy.utils.logging`.
43
+ Do not use `print()` in library code. Application examples may print their results.
44
+ - Warning and error diagnostics identify a backticked offender and end with a period, for example
45
+ `` f"`name={value}` could not be loaded." ``. Info and debug messages stay plain. (R14)
46
+ - Raised messages use `` "`name` <verb phrase>[, but got <value>]." ``.
47
+ Use `is None` and `is True` prose rather than comparison operators in messages. (R1)
48
+ - Validate with `if` and a specific raised exception, never a runtime `assert`. Do not use bare `except:`.
49
+ - Comments explain why rather than narrating the next statement. Prefer no comment or one line, with a
50
+ three-line maximum, no banners, and no trailing period. Copyright and license notices are exempt. (R8)
51
+ - Separate logical phases with one blank line in function bodies of at least 12 lines. (R11)
52
+ - Inline new single-use implementation details. Extract a helper, constant, or configurable parameter when
53
+ a second call-site establishes reuse. Do not delete published APIs or required callbacks by counting only
54
+ their internal call-sites. (R16)
55
+
56
+ ## Tests and review
57
+
58
+ - Test functions and fixtures are plain functions without docstrings. Test functions have no type annotations.
59
+ - Use bare assertions without failure-message strings. Names should describe the observable behavior.
60
+ - Preserve seeded behavior when claiming a behavior-preserving refactor. Treat deliberate numerical changes
61
+ as separate, explicit changes rather than hiding them in a style pass.
62
+ - Regression tests compare actual model output with an independently justified expectation and should fail
63
+ for the defect they claim to prevent.
64
+
65
+ ## Tooling
66
+
67
+ Use the existing pinned Black, isort, and flake8 tools at line length 120.
68
+ The supported interpreter range, dependencies, and build backend do not change as part of this style adoption.
69
+
70
+ ```text
71
+ uv sync --locked --extra docs
72
+ uv run pre-commit run --all-files
73
+ uv run pytest
74
+ uv run python -m sphinx -W -b html docs build
75
+ ```
@@ -0,0 +1 @@
1
+ include AGENTS.md CONVENTIONS.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: learnergy
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Energy-based machine learners built with PyTorch
5
5
  Author-email: Mateus Roder <mateus.roder@unesp.br>, Gustavo de Rosa <gustavo.rosa@unesp.br>
6
6
  License-Expression: Apache-2.0
@@ -49,15 +49,22 @@ image-quality metrics, and visualization helpers.
49
49
 
50
50
  ## Installation
51
51
 
52
- Learnergy requires Python 3.11 or newer.
52
+ Learnergy requires Python 3.11 or newer. Add it to a project managed by uv with:
53
53
 
54
54
  ```bash
55
- pip install learnergy
55
+ uv add learnergy
56
+ ```
57
+
58
+ Add the optional torchvision dependency to run the examples:
59
+
60
+ ```bash
61
+ uv add "learnergy[examples]"
56
62
  ```
57
63
 
58
- Install the optional torchvision dependency to run the examples:
64
+ For a consumer installation in an existing Python environment, pip is also supported:
59
65
 
60
66
  ```bash
67
+ pip install learnergy
61
68
  pip install "learnergy[examples]"
62
69
  ```
63
70
 
@@ -112,8 +119,29 @@ plots, image mosaics, and tensor rendering.
112
119
  See [`examples/applications`](examples/applications) for complete training and
113
120
  classification programs.
114
121
 
122
+ ### Numerical behavior
123
+
124
+ When enabled, Gaussian normalization uses statistics from the current batch,
125
+ not stored training statistics. Batches of two or more samples use sample
126
+ standard deviation; a singleton batch is centered to zero. Representations
127
+ therefore depend on batch composition. Disable the corresponding normalization
128
+ flags when supplying externally standardized features.
129
+
130
+ `VarianceGaussianRBM.sigma` is a learnable scale: the effective visible variance
131
+ is `sigma**2` plus a dtype-dependent epsilon. Its `visible_sampling` method
132
+ returns conditional means followed by sampled states, and Gibbs sampling uses
133
+ those states.
134
+
135
+ Gaussian convolutional representations support gradient-based fine-tuning.
136
+ Use `torch.no_grad()` when extracting frozen features without an autograd graph.
137
+
138
+ The corrected variance-Gaussian sampling and stabilized likelihood calculations
139
+ can change training trajectories, including with a fixed random seed.
140
+
115
141
  ## Development
116
142
 
143
+ Follow [the coding conventions](CONVENTIONS.md) when changing the library or its examples.
144
+
117
145
  The repository uses [uv](https://docs.astral.sh/uv/) for reproducible
118
146
  environments and packaging:
119
147
 
@@ -12,15 +12,22 @@ image-quality metrics, and visualization helpers.
12
12
 
13
13
  ## Installation
14
14
 
15
- Learnergy requires Python 3.11 or newer.
15
+ Learnergy requires Python 3.11 or newer. Add it to a project managed by uv with:
16
16
 
17
17
  ```bash
18
- pip install learnergy
18
+ uv add learnergy
19
+ ```
20
+
21
+ Add the optional torchvision dependency to run the examples:
22
+
23
+ ```bash
24
+ uv add "learnergy[examples]"
19
25
  ```
20
26
 
21
- Install the optional torchvision dependency to run the examples:
27
+ For a consumer installation in an existing Python environment, pip is also supported:
22
28
 
23
29
  ```bash
30
+ pip install learnergy
24
31
  pip install "learnergy[examples]"
25
32
  ```
26
33
 
@@ -75,8 +82,29 @@ plots, image mosaics, and tensor rendering.
75
82
  See [`examples/applications`](examples/applications) for complete training and
76
83
  classification programs.
77
84
 
85
+ ### Numerical behavior
86
+
87
+ When enabled, Gaussian normalization uses statistics from the current batch,
88
+ not stored training statistics. Batches of two or more samples use sample
89
+ standard deviation; a singleton batch is centered to zero. Representations
90
+ therefore depend on batch composition. Disable the corresponding normalization
91
+ flags when supplying externally standardized features.
92
+
93
+ `VarianceGaussianRBM.sigma` is a learnable scale: the effective visible variance
94
+ is `sigma**2` plus a dtype-dependent epsilon. Its `visible_sampling` method
95
+ returns conditional means followed by sampled states, and Gibbs sampling uses
96
+ those states.
97
+
98
+ Gaussian convolutional representations support gradient-based fine-tuning.
99
+ Use `torch.no_grad()` when extracting frozen features without an autograd graph.
100
+
101
+ The corrected variance-Gaussian sampling and stabilized likelihood calculations
102
+ can change training trajectories, including with a fixed random seed.
103
+
78
104
  ## Development
79
105
 
106
+ Follow [the coding conventions](CONVENTIONS.md) when changing the library or its examples.
107
+
80
108
  The repository uses [uv](https://docs.astral.sh/uv/) for reproducible
81
109
  environments and packaging:
82
110
 
@@ -0,0 +1,6 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """Provide energy-based learning models built with PyTorch."""
5
+
6
+ __version__ = "2.0.2"
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
1
4
  """Core model primitives."""
2
5
 
3
6
  from learnergy.core.dataset import Dataset
@@ -0,0 +1,68 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """Adapt array-backed samples to the PyTorch dataset interface."""
5
+
6
+ from collections.abc import Callable
7
+ from typing import Any
8
+
9
+ import torch
10
+
11
+ import learnergy.utils.exception as e
12
+ from learnergy.core.model import _validated_property
13
+ from learnergy.utils.logging import get_logger
14
+
15
+ logger = get_logger(__name__)
16
+
17
+
18
+ class Dataset(torch.utils.data.Dataset):
19
+ """Expose samples and targets with an optional sample transform."""
20
+
21
+ data = _validated_property("data", doc="Backing sample collection, retained without copying.")
22
+ targets = _validated_property("targets", doc="Targets indexed alongside the sample collection.")
23
+ transform = _validated_property(
24
+ "transform",
25
+ lambda _, value: value is None or callable(value),
26
+ e.TypeError,
27
+ "`transform` should be callable or None.",
28
+ doc="Optional transformation applied when a sample is accessed.",
29
+ )
30
+
31
+ def __init__(
32
+ self,
33
+ data: Any,
34
+ targets: Any,
35
+ transform: Callable[[Any], Any] | None = None,
36
+ show_log: bool = True,
37
+ ) -> None:
38
+ """Store sample and target references for indexed access.
39
+
40
+ Data is not copied and transforms are applied on access rather than during initialization.
41
+
42
+ Args:
43
+ data: Indexable sample collection.
44
+ targets: Indexable target collection aligned with the samples.
45
+ transform: Optional callable that transforms an individual sample.
46
+ show_log: Whether to log dataset creation.
47
+
48
+ Raises:
49
+ TypeError: The transform is neither callable nor None.
50
+
51
+ """
52
+
53
+ self.data = data
54
+ self.targets = targets
55
+ self.transform = transform
56
+
57
+ if show_log:
58
+ logger.info("Creating class: Dataset.")
59
+ logger.info("Class created.")
60
+
61
+ def __getitem__(self, idx: int) -> tuple[Any, Any]:
62
+ sample = self.data[idx]
63
+ if self.transform:
64
+ sample = self.transform(sample)
65
+ return sample, self.targets[idx]
66
+
67
+ def __len__(self) -> int:
68
+ return len(self.data)
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """Provide shared model state and validated attributes."""
5
+
6
+ from collections.abc import Callable
7
+ from typing import Any
8
+
9
+ import torch
10
+
11
+ import learnergy.utils.exception as e
12
+
13
+
14
+ def _validated_property(
15
+ name: str,
16
+ validator: Callable[[Any, Any], bool] | None = None,
17
+ error: type[Exception] = ValueError,
18
+ message: str = "`value` is invalid.",
19
+ *,
20
+ doc: str | None = None,
21
+ ) -> property:
22
+ storage_name = f"_{name}"
23
+
24
+ def _get(instance: Any) -> Any:
25
+ return getattr(instance, storage_name)
26
+
27
+ def _set(instance: Any, value: Any) -> None:
28
+ if validator is not None and not validator(instance, value):
29
+ raise error(message)
30
+
31
+ setattr(instance, storage_name, value)
32
+
33
+ return property(_get, _set, doc=doc)
34
+
35
+
36
+ class Model(torch.nn.Module):
37
+ """Provide device selection and metric history for energy-based models."""
38
+
39
+ device = _validated_property(
40
+ "device",
41
+ lambda _, value: value in ("cpu", "cuda"),
42
+ e.TypeError,
43
+ "`device` should be `cpu` or `cuda`.",
44
+ doc="Computation device selected during initialization.",
45
+ )
46
+ history = _validated_property("history", doc="Recorded values grouped into lists by metric name.")
47
+
48
+ def __init__(self, use_gpu: bool = False) -> None:
49
+ """Initialize device selection and an empty metric history.
50
+
51
+ Initialization sets PyTorch's process-wide default floating-point dtype to float32.
52
+
53
+ Args:
54
+ use_gpu: Whether to select CUDA when it is available.
55
+
56
+ """
57
+
58
+ super().__init__()
59
+ torch.set_default_dtype(torch.float32)
60
+ self.device = "cuda" if use_gpu and torch.cuda.is_available() else "cpu"
61
+ self.history = {}
62
+
63
+ def dump(self, **kwargs: Any) -> None:
64
+ """Append values to their per-metric history lists.
65
+
66
+ Existing history is retained and values are stored without conversion or copying.
67
+
68
+ Args:
69
+ **kwargs: Values keyed by the metric names to update.
70
+
71
+ """
72
+
73
+ for k, v in kwargs.items():
74
+ self.history.setdefault(k, []).append(v)
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """Mathematical helpers."""
@@ -0,0 +1,39 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """Calculate image similarity metrics."""
5
+
6
+ import torch
7
+ from skimage.metrics import structural_similarity
8
+
9
+
10
+ def calculate_ssim(v: torch.Tensor, x: torch.Tensor) -> float:
11
+ """Calculate the mean structural similarity of reconstructed images.
12
+
13
+ Tensors are detached and copied to CPU as needed before comparison.
14
+ Each original image supplies its own intensity range to the SSIM calculation.
15
+
16
+ Args:
17
+ v: Reconstructed images, with each image flattened or shaped like its original.
18
+ x: Original grayscale images with shape (batch, height, width).
19
+
20
+ Returns:
21
+ Mean SSIM over the paired images.
22
+
23
+ Raises:
24
+ ValueError: Batch lengths, image shapes, or SSIM window requirements are incompatible.
25
+
26
+ """
27
+
28
+ originals = x.detach().cpu().numpy()
29
+ reconstructed = v.detach().cpu().numpy()
30
+ height, width = originals.shape[1:3]
31
+
32
+ return sum(
33
+ structural_similarity(
34
+ original,
35
+ rebuilt.reshape(height, width),
36
+ data_range=original.max() - original.min(),
37
+ )
38
+ for original, rebuilt in zip(originals, reconstructed, strict=True)
39
+ ) / len(reconstructed)
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """Normalize numerical arrays."""
5
+
6
+ import numpy as np
7
+
8
+ from learnergy.utils.constants import EPSILON
9
+
10
+
11
+ def unitary_scale(x: np.ndarray) -> np.ndarray:
12
+ """Return a float32 copy scaled by its value range.
13
+
14
+ The input is not modified and finite constant arrays become zero arrays.
15
+
16
+ Args:
17
+ x: Numeric array to scale.
18
+
19
+ Returns:
20
+ Float32 array of the same shape, normalized with an epsilon guard.
21
+
22
+ """
23
+
24
+ scaled = x.astype("float32")
25
+ scaled -= scaled.min()
26
+ scaled /= scaled.max() + EPSILON
27
+ return scaled
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
4
+ """A package contaning subpackages of models for all common learnergy modules."""
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2020-2026 Mateus Roder and Gustavo de Rosa.
2
+ # Licensed under the Apache License, Version 2.0.
3
+
1
4
  """Bernoulli-valued RBM variants."""
2
5
 
3
6
  from learnergy.models.bernoulli.conv_rbm import ConvRBM