2 votos

MAPA de clasificación de procesos gaussianos en Tensorflow Probability

Estoy intentando implementar el aprendizaje por clasificación de procesos gaussianos en tensorflow-probability pero mi estimador resulta estar muy sesgado hacia cero. A diferencia de sklearn Intenté optimizar directamente la probabilidad logarítmica posterior para encontrar el estimador máximo a posteriori.

¿Hay algo que esté haciendo mal en el proceso? ¿O de hecho es imposible aprender la clasificación de procesos gaussianos directamente a partir de la verdadera probabilidad logarítmica posterior?

Para probar mi configuración, genero una única función $f$ a partir de una distribución GP en puntos independientes dados $X$ y generar una observación independiente en cada punto según $P(Y_i = 1) = \sigma(f(X_i))$ donde $\sigma$ es la función logística $\frac{1}{1 + \exp(-z)}$ .

El siguiente gráfico muestra lo lejos de la verdad que tiende a estar mi estimador:

learnt probabilities

Generando los datos de la siguiente manera:

import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

# GP kernel
kernel = tfp.positive_semidefinite_kernels.ExponentiatedQuadratic()
# Independent variable points
X = np.random.uniform(-1,1, (30,1)).astype("float32")

# Generating a latent function at observable points
gp = tfp.distributions.GaussianProcess(kernel=kernel, index_points=X)
f = gp.sample(1)

with tf.Session() as sess:
    f_ = sess.run(f)

# Generating observed classes (+-1)
Y = 2*tfp.distributions.Bernoulli(logits=tf.reshape(f_, (-1,))).sample(1) - 1

with tf.Session() as sess:
    Y_ = sess.run(Y)

Aprendizaje del espacio latente mediante scikit-learn que proporciona un estimador utilizando la aproximación de Laplace

from sklearn.gaussian_process import GaussianProcessClassifier

clf = GaussianProcessClassifier()
clf.fit(X, Y_.reshape(-1))
sigma_f_sklearn = clf.predict_proba(X)[:,1]

Optimización directa de la distribución posterior mediante tensorflow

def generate_posterior_log_likelihood(locations, observations):
    """
    Build posterior log likelihood function with GP prior at specific locations
    """
    gp_infer = tfp.distributions.GaussianProcess(
        kernel=kernel, index_points=locations
    )
    def posterior_log_likelihood(f):
        return (
            gp_infer.log_prob(f) +
            tf.reduce_sum(
                tf.log_sigmoid(
                    tf.multiply(tf.cast(observations, tf.float32), f)
                )
            )
        )
    return posterior_log_likelihood

f = tf.get_variable("latent_f", shape=Y.shape, 
                    initializer=tf.initializers.random_normal())
neg_log_likelihood = -generate_posterior_log_likelihood(X, Y_)(f)
optimize = tf.train.AdagradOptimizer(learning_rate=0.1)\
             .minimize(neg_log_likelihood)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    prev_neg_log_likelihood = np.inf
    # Optimizing until convergence
    _, neg_log_likelihood_ = sess.run([optimize, neg_log_likelihood])
    while prev_neg_log_likelihood - neg_log_likelihood_ > 1e-12:
        prev_neg_log_likelihood = neg_log_likelihood_
        _, neg_log_likelihood_ = sess.run([optimize, neg_log_likelihood])

    # Calculating the points
    f_map = sess.run(f)

0voto

Jay Allen Puntos 159

Creo que tu expresión Bernoulli log prob es incorrecta (aunque no he pensado en la expresión correcta para un {-1, 1} -Bernoulli). Para estar seguro, puede intentar

# go back to {0, 1}
y = .5 * (observations + 1)
tfp.distributions.Bernoulli(logits=f).log_prob(y)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X