2016-08-23 63 views
0

我可以从here运行这个例子:CDF在tensorflow

mu = [1, 2, 3.] 
diag_stdev = [4, 5, 6.] 
dist = tf.contrib.distributions.MultivariateNormalDiag(mu, diag_stdev) 
dist.pdf([-1., 0, 1]) 

但是当我代替最后一行的dist.cdf([-1., 0, 1])我得到一个未实现的错误:

NotImplementedError: log_cdf is not implemented 

任何人可以提出一个至少暂时的解决方法?

回答

0

基于对herehere的解决方案,我已经实现了以下解决方案:

import tensorflow as tf 
import numpy as np 
from scipy.stats import mvn 

def py_func(func, inp, Tout, stateful=True, name=None, grad=None): 

    # Need to generate a unique name to avoid duplicates: 
    rnd_name = 'PyFuncGrad' + str(np.random.randint(0, 1E+10)) 

    tf.RegisterGradient(rnd_name)(grad) 
    g = tf.get_default_graph() 
    with g.gradient_override_map({"PyFunc": rnd_name}): 
     return tf.py_func(func, inp, Tout, stateful=stateful, name=name) 

def np_cdf(mean, diag_sigma, value, name=None): 
    low = np.array([-30, -30]) 
    cdf = list() 
    for variables in zip(value, mean, diag_sigma): 
    S = np.diag(variables[2]) 
    p, _ = mvn.mvnun(low,variables[0],variables[1],S) 
    cdf.append(p) 

    cdfs = np.asarray(cdf, dtype=np.float32).reshape([-1,1]) 
    return cdfs 

def cdf_gradient(op, grad): 
    mu = op.inputs[0] 
    diag_sigma = op.inputs[1] 
    value = op.inputs[2] 
    dist = tf.contrib.distributions.MultivariateNormalDiag(mu, diag_sigma) 
    pdf = dist.pdf(value) 
    dc_dv = tf.inv(diag_sigma) * pdf 
    dc_dm = -1 * dc_dv 
    dc_ds = tf.div(value-mu,tf.square(diag_sigma)+1e-6) * pdf 
    return grad * dc_dm, grad * dc_ds, grad * dc_dv 

def tf_cdf(mean, diag_sigma, value, name=None): 

    with tf.name_scope(name, "MyCDF", [mean, diag_sigma, value]) as name: 
     cdf = py_func(np_cdf, 
         [mean, diag_sigma, value], 
         [tf.float32], 
         name=name, 
         grad=cdf_gradient) # <-- here's the call to the gradient 
     return cdf[0]