gmml 2026.9.dev0__tar.gz → 2026.11.dev0__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 (33) hide show
  1. gmml-2026.11.dev0/PKG-INFO +184 -0
  2. gmml-2026.11.dev0/README.md +152 -0
  3. gmml-2026.11.dev0/gmml/__init__.py +46 -0
  4. gmml-2026.11.dev0/gmml/codebook.py +657 -0
  5. gmml-2026.11.dev0/gmml/functional.py +1188 -0
  6. gmml-2026.11.dev0/gmml/layer.py +783 -0
  7. gmml-2026.9.dev0/gmml/util.py → gmml-2026.11.dev0/gmml/utils.py +8 -15
  8. gmml-2026.11.dev0/gmml/validation.py +790 -0
  9. gmml-2026.11.dev0/gmml.egg-info/PKG-INFO +184 -0
  10. {gmml-2026.9.dev0 → gmml-2026.11.dev0}/gmml.egg-info/SOURCES.txt +5 -5
  11. gmml-2026.11.dev0/gmml.egg-info/requires.txt +10 -0
  12. gmml-2026.11.dev0/pyproject.toml +71 -0
  13. gmml-2026.11.dev0/tests/test_functional.py +2818 -0
  14. gmml-2026.11.dev0/tests/test_layer.py +232 -0
  15. gmml-2026.9.dev0/test/test_util.py → gmml-2026.11.dev0/tests/test_utils.py +71 -51
  16. gmml-2026.11.dev0/tests/test_validation.py +1904 -0
  17. gmml-2026.9.dev0/PKG-INFO +0 -93
  18. gmml-2026.9.dev0/README.md +0 -79
  19. gmml-2026.9.dev0/gmml/__init__.py +0 -13
  20. gmml-2026.9.dev0/gmml/codebook.py +0 -300
  21. gmml-2026.9.dev0/gmml/functional.py +0 -636
  22. gmml-2026.9.dev0/gmml/layer.py +0 -343
  23. gmml-2026.9.dev0/gmml/loss.py +0 -86
  24. gmml-2026.9.dev0/gmml/validation.py +0 -672
  25. gmml-2026.9.dev0/gmml.egg-info/PKG-INFO +0 -93
  26. gmml-2026.9.dev0/gmml.egg-info/requires.txt +0 -2
  27. gmml-2026.9.dev0/pyproject.toml +0 -30
  28. gmml-2026.9.dev0/test/test_functional.py +0 -1855
  29. gmml-2026.9.dev0/test/test_validation.py +0 -1681
  30. {gmml-2026.9.dev0 → gmml-2026.11.dev0}/LICENSE +0 -0
  31. {gmml-2026.9.dev0 → gmml-2026.11.dev0}/gmml.egg-info/dependency_links.txt +0 -0
  32. {gmml-2026.9.dev0 → gmml-2026.11.dev0}/gmml.egg-info/top_level.txt +0 -0
  33. {gmml-2026.9.dev0 → gmml-2026.11.dev0}/setup.cfg +0 -0
@@ -0,0 +1,184 @@
1
+ Metadata-Version: 2.4
2
+ Name: gmml
3
+ Version: 2026.11.dev0
4
+ Summary: PyTorch implementation of a Gaussian mixture modeling layer
5
+ Author: algmarques
6
+ Maintainer: algmarques
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/amtcf/gmml
9
+ Project-URL: Repository, https://github.com/amtcf/gmml.git
10
+ Project-URL: Issues, https://github.com/amtcf/gmml/issues
11
+ Keywords: pytorch,gaussian mixture model,neural network layer
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Programming Language :: Python :: 3.15
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
24
+ Requires-Python: >=3.12
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: torch>=2.8.0; python_version < "3.14"
28
+ Requires-Dist: torch>=2.9.0; python_version == "3.14"
29
+ Requires-Dist: torch>=2.15.0; python_version >= "3.15"
30
+ Requires-Dist: numpy>=2.3.3
31
+ Dynamic: license-file
32
+
33
+ # Gaussian Mixture Modeling Layer
34
+
35
+ This package contains a PyTorch implementation of a
36
+ **Gaussian mixture modeling layer**.
37
+
38
+ A **Gaussian mixture modeling layer** maps $d$-dimensional input vectors
39
+ onto categorical probability distributions. Such distributions measure the
40
+ likelihood of the input vectors belonging to each component of a Gaussian
41
+ mixture model. The underlying Gaussian mixture distribution is parametrized
42
+ by a collection of: mean-vectors (`means`), Cholesky factors (`*_factors`),
43
+ and a logits vector (`norm_logits`). The logits vector defines the relative
44
+ importance of each Gaussian component within the mixture, and the collection
45
+ of Cholesky factors (`*_factors`) - each resulting from the Cholesky
46
+ decomposition of the precision matrices of the Gaussian components - defines
47
+ the shape of the Gaussians. Under such parametrization, the computational
48
+ complexity of the functional form of the forward and backward calls to this
49
+ layer is reduced, leading to more efficient evaluations. The forward and
50
+ backward calls of Gaussian mixture modeling layer parametrized by a general
51
+ Cholesky factor (`full_factors`) have a computational complexity of
52
+ $O(n \times d ^ 2)$, where $n$ is the number of components of the underlying
53
+ Gaussian mixture distribution. Moreover, its functional form is differentiable
54
+ in all of its inputs and parameters, hence it is autograd compatible.
55
+
56
+ The package provides four layers, which differ in how the Cholesky factors
57
+ of the precision matrices are constrained:
58
+
59
+ - `FullGMMLayer`: general upper-triangular factors (`full_factors`),
60
+ - `DiagGMMLayer`: diagonal factors (`diag_factors`),
61
+ - `IsoGMMLayer`: isometric factors, one scale per component
62
+ (`iso_factors`),
63
+ - `SharedIsoGMMLayer`: a single isometric factor shared by all components.
64
+
65
+ Every layer takes the number of components and the dimensionality, plus
66
+ the optional `equi_weighted` (default `False`), which keeps all mixture
67
+ weights equal by fixing the logits to zero, and the usual `device` and
68
+ `dtype` arguments.
69
+
70
+ A **Gaussian mixture modeling layer** can be instantiated in the following way:
71
+
72
+ ```python
73
+ from torch import rand
74
+
75
+ from gmml import FullGMMLayer
76
+
77
+ dim = 3
78
+ num_components = 7
79
+ batch_size = 4
80
+
81
+ gmm_layer = FullGMMLayer(num_components, dim)
82
+
83
+ inpt = rand(batch_size, dim)
84
+ probs = gmm_layer(inpt)
85
+ ```
86
+
87
+ The **Gaussian mixture modeling layer** fits the input data by maximizing the
88
+ log-likelihood, inducing a gradient on both its inputs and parameters.
89
+
90
+ ```python
91
+ from torch import rand
92
+
93
+ from gmml import FullGMMLayer
94
+
95
+ dim = 3
96
+ num_components = 7
97
+ batch_size = 4
98
+
99
+ gmm_layer = FullGMMLayer(num_components, dim)
100
+
101
+ inpt = rand(batch_size, dim)
102
+ loss = - gmm_layer.get_log_likelihoods(inpt).mean()
103
+ loss.backward()
104
+ ```
105
+
106
+ The `gmml.functional` namespace contains implementations of differentiable
107
+ procedures relevant to general Gaussian mixture modeling, including: joint
108
+ probability and pair-wise Kullback-Leibler divergence determinations,
109
+ differentiable sampling, and joint entropy upper-bounding.
110
+
111
+ ## Numerical accuracy of the diagonal and isometric layers
112
+
113
+ To save memory and time, `DiagGMMLayer`, `IsoGMMLayer` and
114
+ `SharedIsoGMMLayer` (and `get_diag_log_joint_probs`,
115
+ `get_iso_log_joint_probs`) evaluate the squared Mahalanobis distance between
116
+ an input $x$ and a component mean $\mu$ by expanding it,
117
+
118
+ $$
119
+ \sum_{k = 1}^{d} \gamma_k ^ 2 (x_k - \mu_k) ^ 2
120
+ = \sum_{k = 1}^{d} \gamma_k ^ 2 x_k ^ 2
121
+ - 2 \sum_{k = 1}^{d} \gamma_k ^ 2 x_k \mu_k
122
+ + \sum_{k = 1}^{d} \gamma_k ^ 2 \mu_k ^ 2 ,
123
+ $$
124
+
125
+ where $\gamma$ is the diagonal (or isometric) Cholesky factor. The right-hand
126
+ side is computed with matrix products, so memory drops from
127
+ $O(b \times n \times d)$ to $O(b \times n)$ for a batch of $b$ inputs and $n$
128
+ components. In exchange, the three terms on the right can be much larger than
129
+ the distance itself, and subtracting them cancels most of their significant
130
+ digits. The rounding error in the distance is of the order of
131
+
132
+ $$
133
+ \varepsilon \sum_{k = 1}^{d} \gamma_k ^ 2 \left(x_k ^ 2 + \mu_k ^ 2\right) ,
134
+ $$
135
+
136
+ where $\varepsilon \approx 6 \times 10 ^ {-8}$ in `float32` and
137
+ $\varepsilon \approx 10 ^ {-16}$ in `float64`. The error depends on the size of
138
+ $x$ and $\mu$, not on the size of the distance itself. Inputs and means are
139
+ centered on the average of the means before expanding, which helps when the
140
+ components are clustered away from the origin, but not when the components
141
+ are spread far apart.
142
+
143
+ The error is negligible for standardized inputs and moderate factors. It
144
+ becomes significant when an input lies close to a component mean that is
145
+ far from the other components, and that component is tight (large
146
+ $\gamma$), which is the typical state of a well-fitted mixture on unscaled
147
+ data. For example, in `float32` with $d = 32$, means of norm about $600$ and
148
+ $\gamma \approx 30$, the log-probability of the component containing the
149
+ input was measured to be off by about $10 ^ 2$, against $10 ^ {-5}$ when
150
+ differences $x - \mu$ are formed explicitly. When moderate scales are not
151
+ guaranteed:
152
+
153
+ - standardize (or normalize) the inputs before the layer,
154
+ - use `float64` (`dtype=torch.float64`), or
155
+ - use `FullGMMLayer`, which forms the differences $x - \mu$ explicitly and is
156
+ not affected (it uses $O(b \times n \times d)$ memory).
157
+
158
+ The KL divergences, entropy bounds and sampling functions are not affected.
159
+
160
+ ## Installation
161
+
162
+ To install this package:
163
+
164
+ ```bash
165
+ pip install gmml
166
+ ```
167
+
168
+ To install it from a clone of the repository:
169
+
170
+ ```bash
171
+ pip install .
172
+ ```
173
+
174
+ ## Testing
175
+
176
+ The test suite runs against the dependency versions pinned in
177
+ `requirements.txt`, which also pins the linter (`ruff`):
178
+
179
+ ```bash
180
+ python -m venv .test
181
+ .test/bin/pip install -r requirements.txt
182
+ .test/bin/pip install .
183
+ .test/bin/python -Bm unittest
184
+ ```
@@ -0,0 +1,152 @@
1
+ # Gaussian Mixture Modeling Layer
2
+
3
+ This package contains a PyTorch implementation of a
4
+ **Gaussian mixture modeling layer**.
5
+
6
+ A **Gaussian mixture modeling layer** maps $d$-dimensional input vectors
7
+ onto categorical probability distributions. Such distributions measure the
8
+ likelihood of the input vectors belonging to each component of a Gaussian
9
+ mixture model. The underlying Gaussian mixture distribution is parametrized
10
+ by a collection of: mean-vectors (`means`), Cholesky factors (`*_factors`),
11
+ and a logits vector (`norm_logits`). The logits vector defines the relative
12
+ importance of each Gaussian component within the mixture, and the collection
13
+ of Cholesky factors (`*_factors`) - each resulting from the Cholesky
14
+ decomposition of the precision matrices of the Gaussian components - defines
15
+ the shape of the Gaussians. Under such parametrization, the computational
16
+ complexity of the functional form of the forward and backward calls to this
17
+ layer is reduced, leading to more efficient evaluations. The forward and
18
+ backward calls of Gaussian mixture modeling layer parametrized by a general
19
+ Cholesky factor (`full_factors`) have a computational complexity of
20
+ $O(n \times d ^ 2)$, where $n$ is the number of components of the underlying
21
+ Gaussian mixture distribution. Moreover, its functional form is differentiable
22
+ in all of its inputs and parameters, hence it is autograd compatible.
23
+
24
+ The package provides four layers, which differ in how the Cholesky factors
25
+ of the precision matrices are constrained:
26
+
27
+ - `FullGMMLayer`: general upper-triangular factors (`full_factors`),
28
+ - `DiagGMMLayer`: diagonal factors (`diag_factors`),
29
+ - `IsoGMMLayer`: isometric factors, one scale per component
30
+ (`iso_factors`),
31
+ - `SharedIsoGMMLayer`: a single isometric factor shared by all components.
32
+
33
+ Every layer takes the number of components and the dimensionality, plus
34
+ the optional `equi_weighted` (default `False`), which keeps all mixture
35
+ weights equal by fixing the logits to zero, and the usual `device` and
36
+ `dtype` arguments.
37
+
38
+ A **Gaussian mixture modeling layer** can be instantiated in the following way:
39
+
40
+ ```python
41
+ from torch import rand
42
+
43
+ from gmml import FullGMMLayer
44
+
45
+ dim = 3
46
+ num_components = 7
47
+ batch_size = 4
48
+
49
+ gmm_layer = FullGMMLayer(num_components, dim)
50
+
51
+ inpt = rand(batch_size, dim)
52
+ probs = gmm_layer(inpt)
53
+ ```
54
+
55
+ The **Gaussian mixture modeling layer** fits the input data by maximizing the
56
+ log-likelihood, inducing a gradient on both its inputs and parameters.
57
+
58
+ ```python
59
+ from torch import rand
60
+
61
+ from gmml import FullGMMLayer
62
+
63
+ dim = 3
64
+ num_components = 7
65
+ batch_size = 4
66
+
67
+ gmm_layer = FullGMMLayer(num_components, dim)
68
+
69
+ inpt = rand(batch_size, dim)
70
+ loss = - gmm_layer.get_log_likelihoods(inpt).mean()
71
+ loss.backward()
72
+ ```
73
+
74
+ The `gmml.functional` namespace contains implementations of differentiable
75
+ procedures relevant to general Gaussian mixture modeling, including: joint
76
+ probability and pair-wise Kullback-Leibler divergence determinations,
77
+ differentiable sampling, and joint entropy upper-bounding.
78
+
79
+ ## Numerical accuracy of the diagonal and isometric layers
80
+
81
+ To save memory and time, `DiagGMMLayer`, `IsoGMMLayer` and
82
+ `SharedIsoGMMLayer` (and `get_diag_log_joint_probs`,
83
+ `get_iso_log_joint_probs`) evaluate the squared Mahalanobis distance between
84
+ an input $x$ and a component mean $\mu$ by expanding it,
85
+
86
+ $$
87
+ \sum_{k = 1}^{d} \gamma_k ^ 2 (x_k - \mu_k) ^ 2
88
+ = \sum_{k = 1}^{d} \gamma_k ^ 2 x_k ^ 2
89
+ - 2 \sum_{k = 1}^{d} \gamma_k ^ 2 x_k \mu_k
90
+ + \sum_{k = 1}^{d} \gamma_k ^ 2 \mu_k ^ 2 ,
91
+ $$
92
+
93
+ where $\gamma$ is the diagonal (or isometric) Cholesky factor. The right-hand
94
+ side is computed with matrix products, so memory drops from
95
+ $O(b \times n \times d)$ to $O(b \times n)$ for a batch of $b$ inputs and $n$
96
+ components. In exchange, the three terms on the right can be much larger than
97
+ the distance itself, and subtracting them cancels most of their significant
98
+ digits. The rounding error in the distance is of the order of
99
+
100
+ $$
101
+ \varepsilon \sum_{k = 1}^{d} \gamma_k ^ 2 \left(x_k ^ 2 + \mu_k ^ 2\right) ,
102
+ $$
103
+
104
+ where $\varepsilon \approx 6 \times 10 ^ {-8}$ in `float32` and
105
+ $\varepsilon \approx 10 ^ {-16}$ in `float64`. The error depends on the size of
106
+ $x$ and $\mu$, not on the size of the distance itself. Inputs and means are
107
+ centered on the average of the means before expanding, which helps when the
108
+ components are clustered away from the origin, but not when the components
109
+ are spread far apart.
110
+
111
+ The error is negligible for standardized inputs and moderate factors. It
112
+ becomes significant when an input lies close to a component mean that is
113
+ far from the other components, and that component is tight (large
114
+ $\gamma$), which is the typical state of a well-fitted mixture on unscaled
115
+ data. For example, in `float32` with $d = 32$, means of norm about $600$ and
116
+ $\gamma \approx 30$, the log-probability of the component containing the
117
+ input was measured to be off by about $10 ^ 2$, against $10 ^ {-5}$ when
118
+ differences $x - \mu$ are formed explicitly. When moderate scales are not
119
+ guaranteed:
120
+
121
+ - standardize (or normalize) the inputs before the layer,
122
+ - use `float64` (`dtype=torch.float64`), or
123
+ - use `FullGMMLayer`, which forms the differences $x - \mu$ explicitly and is
124
+ not affected (it uses $O(b \times n \times d)$ memory).
125
+
126
+ The KL divergences, entropy bounds and sampling functions are not affected.
127
+
128
+ ## Installation
129
+
130
+ To install this package:
131
+
132
+ ```bash
133
+ pip install gmml
134
+ ```
135
+
136
+ To install it from a clone of the repository:
137
+
138
+ ```bash
139
+ pip install .
140
+ ```
141
+
142
+ ## Testing
143
+
144
+ The test suite runs against the dependency versions pinned in
145
+ `requirements.txt`, which also pins the linter (`ruff`):
146
+
147
+ ```bash
148
+ python -m venv .test
149
+ .test/bin/pip install -r requirements.txt
150
+ .test/bin/pip install .
151
+ .test/bin/python -Bm unittest
152
+ ```
@@ -0,0 +1,46 @@
1
+ """
2
+ Public package exports for gmml.
3
+ """
4
+
5
+ __all__ = [
6
+ "FullGMMLayer",
7
+ "DiagGMMLayer",
8
+ "IsoGMMLayer",
9
+ "SharedIsoGMMLayer",
10
+ "get_full_kl_divs",
11
+ "get_full_log_joint_probs",
12
+ "get_full_samples",
13
+ "get_full_joint_entropy_upper_bound",
14
+ "get_diag_kl_divs",
15
+ "get_diag_log_joint_probs",
16
+ "get_diag_samples",
17
+ "get_diag_joint_entropy_upper_bound",
18
+ "get_iso_kl_divs",
19
+ "get_iso_log_joint_probs",
20
+ "get_iso_samples",
21
+ "get_iso_joint_entropy_upper_bound",
22
+ "sample_standard_multivariate_normal",
23
+ ]
24
+
25
+
26
+ from gmml.functional import (
27
+ get_diag_joint_entropy_upper_bound,
28
+ get_diag_kl_divs,
29
+ get_diag_log_joint_probs,
30
+ get_diag_samples,
31
+ get_full_joint_entropy_upper_bound,
32
+ get_full_kl_divs,
33
+ get_full_log_joint_probs,
34
+ get_full_samples,
35
+ get_iso_joint_entropy_upper_bound,
36
+ get_iso_kl_divs,
37
+ get_iso_log_joint_probs,
38
+ get_iso_samples,
39
+ )
40
+ from gmml.layer import (
41
+ DiagGMMLayer,
42
+ FullGMMLayer,
43
+ IsoGMMLayer,
44
+ SharedIsoGMMLayer,
45
+ )
46
+ from gmml.utils import sample_standard_multivariate_normal