Hi. I’m new to Edward and I’m confused about how to set up custom random variables.
I figure the “hello world” of custom random variables is to just set up a basic wrapper to an existing Edward random variable class. Here is my attempt to do that with NormalWithSoftplusScale:
import edward as ed
import numpy as np
import tensorflow as tf
from edward.models import RandomVariable
from tensorflow.contrib.distributions import Distribution
from edward.models import Normal
from edward.models import NormalWithSoftplusScale
class CustomRandomVariable(RandomVariable, Distribution):
def __init__(self, loc, scale, sample_shape,
validate_args=False,
allow_nan_stats=True,
name="Custom"):
self._loc = loc
self._scale = scale
self._sample_shape = sample_shape
super(CustomRandomVariable, self).__init__(
dtype=tf.float32,
reparameterization_type=tf.contrib.distributions.FULLY_REPARAMETERIZED,
validate_args=validate_args,
allow_nan_stats=allow_nan_stats,
sample_shape=sample_shape,
name=name)
def _log_prob(self, value):
return NormalWithSoftplusScale(loc=self._loc, scale=self._scale, sample_shape=self._sample_shape)._log_prob(value)
def _sample_n(self, n, seed=None):
return NormalWithSoftplusScale(loc=self._loc, scale=self._scale, sample_shape=self._sample_shape)._sample_n(n)
X_train = np.random.normal(0.0, 1.0, 10)
mu = Normal(loc=10.0, scale=5.0)
sigma = Normal(loc=0.0, scale=1.0)
qmu = Normal(loc=tf.Variable(10.0), scale=tf.Variable(5.0))
qsigma = Normal(loc=tf.Variable(0.0), scale=tf.Variable(1.0))
X = CustomRandomVariable(loc=mu, scale=sigma, sample_shape=X_train.shape)
inference = ed.KLqp({mu:qmu, sigma:qsigma}, {X:X_train})
inference.run(n_samples=10, n_iter=250)
Running this gives the error:
TypeError: __init__() got an unexpected keyword argument 'reparameterization_type'
If I comment out the reparameterization_type argument in the super() call, I get a conflicting error:
TypeError: __init__() missing 1 required positional argument: 'reparameterization_type'
Damned if I do, damned if I don’t. I suppose there is a conflict in the arguments expected by the RandomVariable and Distribution classes. But I’ve seen examples that seem to make similar things work with the same type of call to super()
in __init__()
. So, I’m not sure of the best/proper way to resolve the arguments to make this wrapper class work.
I’m trying to implement a more complicated custom random variable, but I keep running into errors like the above. If someone can help be debug the example above, I think that will be a good start.
Thanks!