gmml 2026.2.dev0__tar.gz → 2026.8.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.
@@ -0,0 +1,93 @@
1
+ Metadata-Version: 2.4
2
+ Name: gmml
3
+ Version: 2026.8.dev0
4
+ Summary: Pytorch implementation of a Gaussian mixture modeling layer
5
+ Author: algmarques
6
+ Maintainer: algmarques
7
+ License-Expression: MIT
8
+ Requires-Python: >=3.12.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: torch>=2.8.0
12
+ Requires-Dist: numpy>=2.3.3
13
+ Dynamic: license-file
14
+
15
+ # Gaussian Mixture Modeling Layer
16
+
17
+ This package contains a Pytorch implementation of a
18
+ **Gaussian mixture modeling layer**.
19
+
20
+ A **Gaussian mixture modeling layer** maps $d$-dimensional input vectors
21
+ onto categorical probability distributions. Such distributions measures the
22
+ likelihood of the input vectors belonging to each component of a Gaussian
23
+ mixture model. The underlying Gaussian mixture distribution is parametrized
24
+ by a collection of: mean-vectors (`mean`), Cholesky factors (`*_fct`),
25
+ and a logit vector (`norm_logit`). The logit vector defines the relative
26
+ importance of each Gaussian component within the mixture, and the collection
27
+ of Cholesky factors (`*_fct`) - each resulting from the Cholesky decomposition
28
+ of the precision matrices of the Gaussian components - defines the shape of
29
+ the Gaussians. Under such parametrization, the computational complexity of the
30
+ functional form of the forward and backward calls to this layer is reduced,
31
+ leading to more efficient evaluations. The forward and backward calls of
32
+ Gaussian mixture modeling layer parameterized by a general Cholesky factor
33
+ (`full_fct`) have a computational complexity of $O(n \times d ^ 2)$, where $n$
34
+ is the number of components of the underlying Gaussian mixture distribution.
35
+ Moreover, its functional form is differentiable in all of its inputs and
36
+ parameters, hence it is autograd compatible.
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 GMMLayer
44
+
45
+ dim = 3
46
+ n_components = 7
47
+ batch_size = 4
48
+
49
+ gmml = GMMLayer(n_components, dim)
50
+
51
+ inpt = rand(batch_size, dim)
52
+ prob = gmml(inpt)
53
+ ```
54
+
55
+ The **Gaussian mixture modeling layer** fits the input data by maximizing the
56
+ log-likelihood, inducing a gradient on both it's inputs and parameters.
57
+
58
+ ```python
59
+ from torch import rand
60
+
61
+ from gmml import GMMLayer, get_log_likelihood
62
+
63
+ dim = 3
64
+ n_components = 7
65
+ batch_size = 4
66
+
67
+ gmml = GMMLayer(n_components, dim)
68
+
69
+ inpt = rand(batch_size, dim)
70
+ ll = get_log_likelihood(inpt, gmml)
71
+ ```
72
+
73
+ The `gmml.functional` namespace contains implementations of differentiable
74
+ procedures relevant to general Gaussian mixture modeling, including: joint
75
+ probability and pair-wise Kullback-Liebler divergence determinations,
76
+ differentiable sampling, and joint entropy upper-bounding.
77
+
78
+ To install this package:
79
+
80
+ ```bash
81
+ python -m venv .test
82
+ .test/bin/pip install -r requirements.txt
83
+ .test/bin/pip install .
84
+ ```
85
+
86
+ To run the test suite:
87
+
88
+ ```bash
89
+ python -m venv .test
90
+ .test/bin/pip install -r requirements.txt
91
+ .test/bin/pip install .
92
+ .test/bin/python -Bm unittest ./test/*
93
+ ```
@@ -0,0 +1,79 @@
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 measures 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 (`mean`), Cholesky factors (`*_fct`),
11
+ and a logit vector (`norm_logit`). The logit vector defines the relative
12
+ importance of each Gaussian component within the mixture, and the collection
13
+ of Cholesky factors (`*_fct`) - each resulting from the Cholesky decomposition
14
+ of the precision matrices of the Gaussian components - defines the shape of
15
+ the Gaussians. Under such parametrization, the computational complexity of the
16
+ functional form of the forward and backward calls to this layer is reduced,
17
+ leading to more efficient evaluations. The forward and backward calls of
18
+ Gaussian mixture modeling layer parameterized by a general Cholesky factor
19
+ (`full_fct`) have a computational complexity of $O(n \times d ^ 2)$, where $n$
20
+ is the number of components of the underlying Gaussian mixture distribution.
21
+ Moreover, its functional form is differentiable in all of its inputs and
22
+ parameters, hence it is autograd compatible.
23
+
24
+ A **Gaussian mixture modeling layer** can be instantiated in the following way:
25
+
26
+ ```python
27
+ from torch import rand
28
+
29
+ from gmml import GMMLayer
30
+
31
+ dim = 3
32
+ n_components = 7
33
+ batch_size = 4
34
+
35
+ gmml = GMMLayer(n_components, dim)
36
+
37
+ inpt = rand(batch_size, dim)
38
+ prob = gmml(inpt)
39
+ ```
40
+
41
+ The **Gaussian mixture modeling layer** fits the input data by maximizing the
42
+ log-likelihood, inducing a gradient on both it's inputs and parameters.
43
+
44
+ ```python
45
+ from torch import rand
46
+
47
+ from gmml import GMMLayer, get_log_likelihood
48
+
49
+ dim = 3
50
+ n_components = 7
51
+ batch_size = 4
52
+
53
+ gmml = GMMLayer(n_components, dim)
54
+
55
+ inpt = rand(batch_size, dim)
56
+ ll = get_log_likelihood(inpt, gmml)
57
+ ```
58
+
59
+ The `gmml.functional` namespace contains implementations of differentiable
60
+ procedures relevant to general Gaussian mixture modeling, including: joint
61
+ probability and pair-wise Kullback-Liebler divergence determinations,
62
+ differentiable sampling, and joint entropy upper-bounding.
63
+
64
+ To install this package:
65
+
66
+ ```bash
67
+ python -m venv .test
68
+ .test/bin/pip install -r requirements.txt
69
+ .test/bin/pip install .
70
+ ```
71
+
72
+ To run the test suite:
73
+
74
+ ```bash
75
+ python -m venv .test
76
+ .test/bin/pip install -r requirements.txt
77
+ .test/bin/pip install .
78
+ .test/bin/python -Bm unittest ./test/*
79
+ ```
@@ -0,0 +1,13 @@
1
+ """
2
+ Public package exports for gmml.
3
+ """
4
+
5
+ from gmml.layer import GMMLayer, DiagGMMLayer, IsoGMMLayer
6
+
7
+ from gmml.functional import get_kl_div, get_log_joint_prob, get_sample
8
+ from gmml.functional import get_diag_kl_div, get_diag_log_joint_prob, \
9
+ get_diag_sample
10
+ from gmml.functional import get_iso_kl_div, get_iso_log_joint_prob, \
11
+ get_iso_sample
12
+
13
+ from gmml.loss import get_log_likelihood, get_cond_entropy, get_importance
@@ -0,0 +1,300 @@
1
+ """
2
+ Codebook abstractions for Gaussian mixture models.
3
+ """
4
+
5
+ from __future__ import annotations
6
+ from abc import ABC, abstractmethod
7
+ from typing import Any
8
+
9
+ from torch import Tensor, zeros
10
+ from torch.nn import Module, Parameter
11
+ from torch.nn.functional import softmax, log_softmax
12
+
13
+ from gmml.util import sample_standard_multivariate_normal
14
+
15
+
16
+ class _CodeBook(Module, ABC):
17
+ """
18
+ Base class for codebooks with learned component vectors.
19
+ """
20
+
21
+ def _init_codevector(self: _CodeBook) -> None:
22
+ """
23
+ Initializes the codevectors parameter according to a standard
24
+ multivariate normal distribution.
25
+
26
+ Args:
27
+ None.
28
+
29
+ Returns:
30
+ None: This function returns only after successful initialization.
31
+ """
32
+
33
+ codevector = sample_standard_multivariate_normal(self.size, self.dim)
34
+
35
+ self.codevector = Parameter(
36
+ codevector,
37
+ requires_grad=True
38
+ )
39
+
40
+ def __init__(
41
+ self: _CodeBook,
42
+ size: int,
43
+ dim: int,
44
+ *args: Any,
45
+ **kwargs: Any
46
+ ) -> None:
47
+ """
48
+
49
+ Args:
50
+ size: Number of codebook entries.
51
+ dim: Dimensionality of each code vector.
52
+ *args: Positional arguments forwarded to the base module.
53
+ **kwargs: Keyword arguments forwarded to the base module.
54
+
55
+ Returns:
56
+ None: This constructor returns after initializing the module.
57
+ """
58
+
59
+ super().__init__(*args, **kwargs)
60
+
61
+ self.size = size
62
+ self.dim = dim
63
+
64
+ self._init_codevector()
65
+
66
+ @abstractmethod
67
+ def forward(self: _CodeBook, inpt: Tensor) -> Tensor:
68
+ """
69
+ Abstract forward method.
70
+
71
+ Args:
72
+ inpt: Input tensor passed to the codebook.
73
+
74
+ Returns:
75
+ Tensor: Output tensor produced by the codebook.
76
+ """
77
+
78
+ raise NotImplementedError()
79
+
80
+
81
+ class _WeightedCodeBook(_CodeBook, ABC):
82
+ """
83
+ Codebook base class with learnable component weights.
84
+ """
85
+
86
+ def _init_logit(self: _WeightedCodeBook) -> None:
87
+ """
88
+ Initializes an equi-weighted logit vector parameter.
89
+
90
+ Args:
91
+ None.
92
+
93
+ Returns:
94
+ None: This function returns only after successful initialization.
95
+ """
96
+
97
+ requires_grad = not self.equi_weighted
98
+
99
+ logit = zeros(self.size)
100
+
101
+ self.logit = Parameter(logit, requires_grad=requires_grad)
102
+
103
+ def __init__(
104
+ self: _WeightedCodeBook,
105
+ size: int,
106
+ dim: int,
107
+ equi_weighted: bool = False,
108
+ *args: Any,
109
+ **kwargs: Any
110
+ ) -> None:
111
+ """
112
+
113
+ Args:
114
+ size: Number of codebook entries.
115
+ dim: Dimensionality of each code vector.
116
+ equi_weighted: Whether to keep all mixture weights equal.
117
+ *args: Positional arguments forwarded to the base module.
118
+ **kwargs: Keyword arguments forwarded to the base module.
119
+
120
+ Returns:
121
+ None: This constructor returns after initializing the module.
122
+ """
123
+
124
+ super().__init__(size, dim, *args, **kwargs)
125
+
126
+ self.equi_weighted = equi_weighted
127
+
128
+ self._init_logit()
129
+
130
+ @property
131
+ def norm_logit(self: _WeightedCodeBook) -> Tensor:
132
+ """
133
+ Returns the normalized logit vector.
134
+
135
+ Args:
136
+ None.
137
+
138
+ Returns:
139
+ Tensor: Log-softmax-normalized logits.
140
+ """
141
+
142
+ return log_softmax(self.logit, dim=-1)
143
+
144
+ @property
145
+ def weight(self: _WeightedCodeBook) -> Tensor:
146
+ """
147
+ Returns weight vector.
148
+
149
+ Args:
150
+ None.
151
+
152
+ Returns:
153
+ Tensor: Softmax-normalized weights.
154
+ """
155
+
156
+ return softmax(self.logit, dim=-1)
157
+
158
+
159
+ class _ProbCodeBook(_CodeBook, ABC):
160
+ """
161
+ Codebook base class that exposes conditional probabilities.
162
+ """
163
+
164
+ def forward(self: _ProbCodeBook, inpt: Tensor) -> Tensor:
165
+ """
166
+
167
+ Args:
168
+ inpt: Input tensor passed to the probabilistic codebook.
169
+
170
+ Returns:
171
+ Tensor: Conditional probability distribution over components.
172
+ """
173
+
174
+ return self.get_cond_prob(inpt)
175
+
176
+ def get_cond_prob(self: _ProbCodeBook, inpt: Tensor) -> Tensor:
177
+ """
178
+ Returns the conditional categorical probability distributions.
179
+
180
+ Args:
181
+ inpt: Input tensor passed to the probabilistic codebook.
182
+
183
+ Returns:
184
+ Tensor: Conditional categorical probability distributions.
185
+ """
186
+
187
+ log_cond_prob = self.get_log_cond_prob(inpt)
188
+
189
+ return softmax(log_cond_prob, dim=-1)
190
+
191
+ def get_cond_entropy(self: _ProbCodeBook, inpt: Tensor) -> Tensor:
192
+ """
193
+ Returns the entropy associated with the conditional categorical
194
+ probability distributions.
195
+
196
+ Args:
197
+ inpt: Input tensor passed to the probabilistic codebook.
198
+
199
+ Returns:
200
+ Tensor: Conditional entropy.
201
+ """
202
+
203
+ log_cond_prob = self.get_log_cond_prob(inpt)
204
+
205
+ return - (log_cond_prob.exp() * log_cond_prob).sum(-1)
206
+
207
+ @abstractmethod
208
+ def get_log_cond_prob(self: _ProbCodeBook, inpt: Tensor) -> Tensor:
209
+ """
210
+ Abstract method for returning logarithm of the conditional categorical
211
+ probability distributions.
212
+
213
+ Args:
214
+ inpt: Input tensor passed to the probabilistic codebook.
215
+
216
+ Returns:
217
+ Tensor: Log-conditional probability distributions.
218
+ """
219
+
220
+ raise NotImplementedError()
221
+
222
+
223
+ class _GaussianCodeBook(_ProbCodeBook, ABC):
224
+ """
225
+ Codebook base class specialized for Gaussian components.
226
+ """
227
+
228
+ def get_log_cond_prob(self: _GaussianCodeBook, inpt: Tensor) -> Tensor:
229
+ """
230
+ Returns logarithm of the conditional categorical probability
231
+ distributions.
232
+
233
+ Args:
234
+ inpt: Input tensor passed to the Gaussian codebook.
235
+
236
+ Returns:
237
+ Tensor: Log-conditional probability distributions.
238
+ """
239
+
240
+ log_joint_prob = self.get_log_joint_prob(inpt)
241
+
242
+ return log_softmax(log_joint_prob, dim=-1)
243
+
244
+ @property
245
+ def mean(self: _GaussianCodeBook) -> Tensor:
246
+ """
247
+ Returns the mean-vectors.
248
+
249
+ Args:
250
+ None.
251
+
252
+ Returns:
253
+ Tensor: Mean vectors of the Gaussian components.
254
+ """
255
+
256
+ return self.codevector
257
+
258
+ @property
259
+ def precision(self: _GaussianCodeBook) -> Tensor:
260
+ """
261
+ Returns the precision matrices.
262
+
263
+ Args:
264
+ None.
265
+
266
+ Returns:
267
+ Tensor: Precision matrices of the Gaussian components.
268
+ """
269
+
270
+ return self.full_fct.mT @ self.full_fct
271
+
272
+ @property
273
+ @abstractmethod
274
+ def full_fct(self: _GaussianCodeBook) -> Tensor:
275
+ """
276
+ Returns the Cholesky factors.
277
+
278
+ Args:
279
+ None.
280
+
281
+ Returns:
282
+ Tensor: Cholesky factors of the Gaussian components.
283
+ """
284
+
285
+ raise NotImplementedError()
286
+
287
+ @abstractmethod
288
+ def get_log_joint_prob(self: _GaussianCodeBook, inpt: Tensor) -> Tensor:
289
+ """
290
+ Abstract method for returning the logarithm of the joint probability
291
+ distributions.
292
+
293
+ Args:
294
+ inpt: Input tensor passed to the Gaussian codebook.
295
+
296
+ Returns:
297
+ Tensor: Log joint probability distributions.
298
+ """
299
+
300
+ raise NotImplementedError()