Bases: MI
Computes the Mutual Information (MI) using tf.linalg.slogdet
for numerical stability,
especially for large or ill-conditioned covariance matrices.
The slogdet (sign and log determinant) method computes the sign and the natural
logarithm of the absolute value of the determinant of a square matrix.
This is more numerically stable than computing the determinant directly and then
taking the logarithm, as tf.linalg.det
can return very small or very large
numbers that lead to underflow/overflow when tf.math.log
is applied.
Jitter is also added to the diagonal for additional numerical stability.
Source code in sgptools/objectives.py
| class SLogMI(MI):
"""
Computes the Mutual Information (MI) using `tf.linalg.slogdet` for numerical stability,
especially for large or ill-conditioned covariance matrices.
The slogdet (sign and log determinant) method computes the sign and the natural
logarithm of the absolute value of the determinant of a square matrix.
This is more numerically stable than computing the determinant directly and then
taking the logarithm, as `tf.linalg.det` can return very small or very large
numbers that lead to underflow/overflow when `tf.math.log` is applied.
Jitter is also added to the diagonal for additional numerical stability.
"""
def __call__(self, X: tf.Tensor) -> tf.Tensor:
"""
Computes the Mutual Information for the given input points `X` using `tf.linalg.slogdet`.
Args:
X (tf.Tensor): The input points (e.g., sensing locations) for which
MI is to be computed. Shape: (M, D).
Returns:
tf.Tensor: The computed Mutual Information value.
Usage:
```python
import gpflow
import numpy as np
# Assume X_objective and kernel are defined
# X_objective = np.random.rand(100, 2)
# kernel = gpflow.kernels.SquaredExponential()
# noise_variance = 0.1
slogmi_objective = SLogMI(X_objective=X_objective, kernel=kernel, noise_variance=noise_variance)
X_sensing = tf.constant(np.random.rand(10, 2), dtype=tf.float64)
mi_value = slogmi_objective(X_sensing)
```
"""
# K(X_objective, X_objective)
K_obj_obj = self.kernel(self.X_objective)
# K(X, X)
K_X_X = self.kernel(X)
# K(X_objective U X, X_objective U X)
K_combined = self.kernel(tf.concat([self.X_objective, X], axis=0))
# Compute log determinants using slogdet for numerical stability
_, logdet_K_obj_obj = tf.linalg.slogdet(self.jitter_fn(K_obj_obj))
_, logdet_K_X_X = tf.linalg.slogdet(self.jitter_fn(K_X_X))
_, logdet_K_combined = tf.linalg.slogdet(self.jitter_fn(K_combined))
# MI formula
mi = logdet_K_obj_obj + logdet_K_X_X - logdet_K_combined
return mi
|
Computes the Mutual Information for the given input points X
using tf.linalg.slogdet
.
Parameters:
Name |
Type |
Description |
Default |
X
|
Tensor
|
The input points (e.g., sensing locations) for which
MI is to be computed. Shape: (M, D).
|
required
|
Returns:
Type |
Description |
Tensor
|
tf.Tensor: The computed Mutual Information value.
|
Usage
import gpflow
import numpy as np
# Assume X_objective and kernel are defined
# X_objective = np.random.rand(100, 2)
# kernel = gpflow.kernels.SquaredExponential()
# noise_variance = 0.1
slogmi_objective = SLogMI(X_objective=X_objective, kernel=kernel, noise_variance=noise_variance)
X_sensing = tf.constant(np.random.rand(10, 2), dtype=tf.float64)
mi_value = slogmi_objective(X_sensing)
Source code in sgptools/objectives.py
| def __call__(self, X: tf.Tensor) -> tf.Tensor:
"""
Computes the Mutual Information for the given input points `X` using `tf.linalg.slogdet`.
Args:
X (tf.Tensor): The input points (e.g., sensing locations) for which
MI is to be computed. Shape: (M, D).
Returns:
tf.Tensor: The computed Mutual Information value.
Usage:
```python
import gpflow
import numpy as np
# Assume X_objective and kernel are defined
# X_objective = np.random.rand(100, 2)
# kernel = gpflow.kernels.SquaredExponential()
# noise_variance = 0.1
slogmi_objective = SLogMI(X_objective=X_objective, kernel=kernel, noise_variance=noise_variance)
X_sensing = tf.constant(np.random.rand(10, 2), dtype=tf.float64)
mi_value = slogmi_objective(X_sensing)
```
"""
# K(X_objective, X_objective)
K_obj_obj = self.kernel(self.X_objective)
# K(X, X)
K_X_X = self.kernel(X)
# K(X_objective U X, X_objective U X)
K_combined = self.kernel(tf.concat([self.X_objective, X], axis=0))
# Compute log determinants using slogdet for numerical stability
_, logdet_K_obj_obj = tf.linalg.slogdet(self.jitter_fn(K_obj_obj))
_, logdet_K_X_X = tf.linalg.slogdet(self.jitter_fn(K_X_X))
_, logdet_K_combined = tf.linalg.slogdet(self.jitter_fn(K_combined))
# MI formula
mi = logdet_K_obj_obj + logdet_K_X_X - logdet_K_combined
return mi
|