Issues with transforming of a Mixture of Generalized Pareto using Bijector
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 30/100
- Issue-Typ
- Bug
- Klarheit
- Muss geklärt werden
- Aktivitätsstatus
- Veraltet
- Tech-Stack
- python
- Bereich
- machine-learning
Rechercherichtung
Beginne damit, den bereitgestellten ApproxTransform- und SafeGeneralizedPareto-Reproducer auszuführen, mit Fokus auf _forward, _inverse und dem Support-Verhalten von GeneralizedPareto. Vergleiche den Normal-Fall mit der Mischung aus Generalized-Pareto-Komponenten und dem Generalized-Extreme-Value-Ziel. Als erledigt gilt die Aufgabe, wenn die transformierte Mischung gültige endliche Ergebnisse ohne nicht unterstützte PDF- oder CDF-Werte erzeugt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
I would like to transform a mixture of distributions into another distribution and then apply the learned transformation to the individual components for a specific engineering application. While I am able to accomplish this for a Normal distribution, it does not work for the Generalized Pareto distribution.
The code below illustrates the workflow.
import tensorflow_probability as tfp
from scipy.optimize import brentq
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
tfd = tfp.distributions
tfb = tfp.bijectors
normal1 = tfd.Normal(loc=1.5, scale=0.5)
normal2 = tfd.Normal(loc=1.0, scale=1.0)
source_dist = tfd.Mixture(cat=tfd.Categorical(probs=[0.4, 0.6]), components=[normal1, normal2])
target_dist = tfd.Exponential(rate=1.0)
# Define the variable transformer
transformer = ApproxTransform(source_dist=source_dist, target_dist=target_dist)
# Transform the source distribution
transformed_dist = tfd.TransformedDistribution(distribution=source_dist, bijector=transformer)
# Now apply the transformation to individual distributions
transformed_normal1 = tfd.TransformedDistribution(distribution=normal1, bijector=transformer)
transformed_normal2 = tfd.TransformedDistribution(distribution=normal2, bijector=transformer)
recombined = tfd.Mixture(cat=tfd.Categorical(probs=[0.4, 0.6]), components=[transformed_normal1, transformed_normal2])
Here
class ApproxTransform(tfb.Bijector):
def __init__(self, source_dist, target_dist, min_support=-1e9, max_support=1e9, name="ApproxTransform"):
super().__init__(forward_min_event_ndims=0, name=name)
self.source = source_dist
self.target = target_dist
self.min_support = min_support
self.max_support = max_support
def approx_quantile(self, dist, qi):
if np.ndim(qi) == 0:
# scalar
def objective(x):
return dist.cdf(x) - qi
return brentq(objective, self.min_support, self.max_support)
else:
# Vector over qi elements
quantiles = [self.approx_quantile(dist, q) for q in qi]
return np.array(quantiles)
def _forward(self, x):
x = tf.convert_to_tensor(x)
x = tf.cast(x, self.source.dtype)
u = self.source.cdf(x)
return self.approx_quantile(self.target, u)
def _inverse(self, y):
y = tf.convert_to_tensor(y)
y = tf.cast(y, self.source.dtype)
u = self.target.cdf(y)
return self.approx_quantile(self.source, u)
def _forward_log_det_jacobian(self, x):
"""log|dy/dx| = log f_X(x) - log f_Y(y)"""
desired_dtype = self.source.dtype
x = tf.cast(x, desired_dtype)
y = self._forward(x)
y = tf.cast(y, desired_dtype)
return self.source.log_prob(x) - self.target.log_prob(y)
def _is_increasing(self):
"""Transformation is monotonic increasing."""
return True
This works, as illustrated in the image below.
Now, I want to perform this process for a mixture of Generalized Pareto Distributions. Specifically, I aim to combine two Pareto distributions, transform the mixture into another distribution (for example, a Generalized Extreme Value distribution), and then recover the transformed components.
However, I am encountering an issue where TensorFlow Probability (TFP) reports PDF and CDF values below the distribution’s support, making my workflow impractical. I attempted to resolve this by implementing a custom class that wraps around tfd.GeneralizedPareto, but the resulting transformed distribution produces only NaN values. Is there any way to transform the mixture into a GEV distribution successfully?
class SafeGeneralizedPareto(tfd.GeneralizedPareto):
def __init__(self, *args, **kwargs):
# Force disable built-in validation to avoid assertion errors
kwargs['validate_args'] = False
super().__init__(*args, **kwargs)
def prob(self, x):
base_prob = super().prob(x)
return tf.where(x < self.loc, tf.zeros_like(base_prob), base_prob)
def cdf(self, x):
base_cdf = super().cdf(x)
return tf.where(x < self.loc, tf.zeros_like(base_cdf), base_cdf)
def log_prob(self, x):
# raise NotImplemented
base_log_prob = super().log_prob(x)
return tf.where(x < self.loc, tf.constant(-float('inf'), dtype=base_log_prob.dtype), base_log_prob)
gpd_1 = SafeGeneralizedPareto(loc=17.402, scale=37.613, concentration=-0.118)
gpd_2 = SafeGeneralizedPareto(loc=21.007, scale=9.453, concentration=0.136)
source_dist = tfd.Mixture(cat=tfd.Categorical(probs=[0.4, 0.6]), components=[gpd_1, gpd_2])
target_dist = tfd.GeneralizedExtremeValue(loc=3.930, scale=0.747, concentration=-0.2357)
# Define the variable transformer
transformer = ApproxTransform(source_dist=source_dist, target_dist=target_dist)
# Transform the source distribution
transformed_dist = tfd.TransformedDistribution(distribution=source_dist, bijector=transformer)
- Vorherrschende Sprache
- Jupyter Notebook
- Sterne
- 4.4k
- Forks
- 1.1k
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus tensorflow/probability
-
KL divergence between two `TransformedDistribution`s with a shared non-injective bijector (`AbsoluteValue`) returns the base KLEvtl. vergeben @Andreas-Hum hat das vor 9 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
tensorflow/probability#2036 ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 54/100
tensorflow/probability#2040 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 68/100
tensorflow/probability#2034 ·
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
tensorflow/probability#2021 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 48/100
tensorflow/probability#2013 ·
Alle Issues in tensorflow/probability
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
JdeRobot/PerceptionMetrics#680 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
TuringLang/Turing.jl#2917 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug good first issue
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
Selectus2/trainers-rb#29 ·
-
test_issue1702 hardware test fails in a full `-m gpu` run: it reads a process-wide pinned-memory counter that test_issue1174 leaves non-zeroEvtl. vergeben @jafarovvvvvvv hat das heute übernommen. Offenbug claimed difficulty:2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
MakazhanAlpamys/Soup#2680 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
training
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
tinaudio/synth-setter#3758 ·
Maintainer antworten meist innerhalb von 1 Tag