Пример #1
0
 def __init__(self, layers=None):
     get_session()
     if layers is None:
         self.layers = []
         self.shape = []
         self.n_vars = 0
         self.n_params = 0
         self.is_differentiable = True
         self.is_multivariate = []
         self.is_reparameterized = True
         self.is_normal = True
         self.is_entropy = True
     else:
         self.layers = layers
         self.shape = [layer.shape for layer in self.layers]
         self.n_vars = sum([layer.n_vars for layer in self.layers])
         self.n_params = sum([layer.n_params for layer in self.layers])
         self.is_differentiable = all([layer.is_differentiable
                                       for layer in self.layers])
         self.is_multivariate = [layer.is_multivariate for layer in self.layers]
         self.is_reparameterized = all([layer.is_reparameterized
                                        for layer in self.layers])
         self.is_normal = all([isinstance(layer, Normal)
                               for layer in self.layers])
         self.is_entropy = all(['entropy' in layer.__class__.__dict__
                                for layer in self.layers])
Пример #2
0
 def __init__(self, layers=[]):
     get_session()
     self.layers = layers
     if layers == []:
         self.num_factors = 0
         self.num_vars = 0
         self.num_params = 0
         self.is_reparam = True
         self.is_normal = True
         self.is_entropy = True
         self.sample_tensor = []
     else:
         self.num_factors = sum(
             [layer.num_factors for layer in self.layers])
         self.num_vars = sum([layer.num_vars for layer in self.layers])
         self.num_params = sum([layer.num_params for layer in self.layers])
         self.is_reparam = all([
             'reparam' in layer.__class__.__dict__ for layer in self.layers
         ])
         self.is_normal = all(
             [isinstance(layer, Normal) for layer in self.layers])
         self.is_entropy = all([
             'entropy' in layer.__class__.__dict__ for layer in self.layers
         ])
         self.sample_tensor = [layer.sample_tensor for layer in self.layers]
Пример #3
0
 def __init__(self, layers=None):
     get_session()
     if layers is None:
         self.layers = []
         self.shape = []
         self.num_vars = 0
         self.num_params = 0
         self.is_reparam = True
         self.is_normal = True
         self.is_entropy = True
         self.sample_tensor = []
         self.is_multivariate = []
     else:
         self.layers = layers
         self.shape = [layer.shape for layer in self.layers]
         self.num_vars = sum([layer.num_vars for layer in self.layers])
         self.num_params = sum([layer.num_params for layer in self.layers])
         self.is_reparam = all(['reparam' in layer.__class__.__dict__
                                for layer in self.layers])
         self.is_normal = all([isinstance(layer, Normal)
                               for layer in self.layers])
         self.is_entropy = all(['entropy' in layer.__class__.__dict__
                                for layer in self.layers])
         self.sample_tensor = [layer.sample_tensor for layer in self.layers]
         self.is_multivariate = [layer.is_multivariate for layer in self.layers]
Пример #4
0
 def __init__(self, layers=None):
     get_session()
     if layers is None:
         self.layers = []
         self.shape = []
         self.n_vars = 0
         self.n_params = 0
         self.is_differentiable = True
         self.is_multivariate = []
         self.is_reparameterized = True
         self.is_normal = True
         self.is_entropy = True
     else:
         self.layers = layers
         self.shape = [layer.shape for layer in self.layers]
         self.n_vars = sum([layer.n_vars for layer in self.layers])
         self.n_params = sum([layer.n_params for layer in self.layers])
         self.is_differentiable = all(
             [layer.is_differentiable for layer in self.layers])
         self.is_multivariate = [
             layer.is_multivariate for layer in self.layers
         ]
         self.is_reparameterized = all(
             [layer.is_reparameterized for layer in self.layers])
         self.is_normal = all(
             [isinstance(layer, Normal) for layer in self.layers])
         self.is_entropy = all([
             'entropy' in layer.__class__.__dict__ for layer in self.layers
         ])
Пример #5
0
 def finalize(self):
     get_session()
     x = self.data.sample(self.n_data) # uses mini-batch
     z, _ = self.variational.sample()
     var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                                  scope='variational')
     inv_cov = hessian(self.model.log_prob(x, z), var_list)
     print("Precision matrix:")
     print(inv_cov.eval())
Пример #6
0
    def finalize(self):
        """Function to call after convergence.

        Computes the Hessian at the mode.
        """
        get_session()
        x = self.data.sample(self.n_data) # uses mini-batch
        z = self.variational.sample()
        var_list = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                                     scope='variational')
        inv_cov = hessian(self.model.log_prob(x, z), var_list)
        print("Precision matrix:")
        print(inv_cov.eval())
Пример #7
0
    def __init__(self, model, data=Data()):
        """Initialization.

        Calls ``util.get_session()``

        Parameters
        ----------
        model : ed.Model
            probability model
        data : ed.Data, optional
            observed data
        """
        self.model = model
        self.data = data
        get_session()
Пример #8
0
  def update(self, feed_dict=None):
    """Run one iteration of inference.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run. It is used to feed
      placeholders that are not fed during initialization.

    Returns
    -------
    dict
      Dictionary of algorithm-specific information.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor):
        feed_dict[key] = value

    sess = get_session()
    t = sess.run(self.increment_t)

    if self.debug:
      sess.run(self.op_check)

    if self.logging and self.n_print != 0:
      if t == 1 or t % self.n_print == 0:
        summary = sess.run(self.summarize, feed_dict)
        self.train_writer.add_summary(summary, t)

    return {'t': t}
Пример #9
0
 def print_params(self):
     sess = get_session()
     m, s = sess.run([self.m, self.s])
     print("mean:")
     print(m)
     print("std dev:")
     print(s)
Пример #10
0
 def print_params(self):
     sess = get_session()
     a, b = sess.run([self.a, self.b])
     print("shape:")
     print(a)
     print("scale:")
     print(b)
Пример #11
0
    def update(self, feed_dict=None):
        """Run one iteration of inference.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run. It is used to feed
      placeholders that are not fed during initialization.

    Returns
    -------
    dict
      Dictionary of algorithm-specific information.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor):
                feed_dict[key] = value

        sess = get_session()
        t = sess.run(self.increment_t)

        if self.debug:
            sess.run(self.op_check)

        if self.logging and self.n_print != 0:
            if t == 1 or t % self.n_print == 0:
                summary = sess.run(self.summarize, feed_dict)
                self.train_writer.add_summary(summary, t)

        return {'t': t}
Пример #12
0
 def print_params(self):
     sess = get_session()
     m, s = sess.run([self.m, self.s])
     print("mean:")
     print(m)
     print("std dev:")
     print(s)
Пример #13
0
    def update(self, feed_dict=None):
        """Run one iteration of optimization.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run. It is used to feed
        placeholders that are not fed during initialization.

    Returns:
      dict.
      Dictionary of algorithm-specific information. In this case, the
      loss function value after one iteration.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                feed_dict[key] = value

        sess = get_session()
        _, t, loss = sess.run([self.train, self.increment_t, self.loss],
                              feed_dict)

        if self.debug:
            sess.run(self.op_check, feed_dict)

        if self.logging and self.n_print != 0:
            if t == 1 or t % self.n_print == 0:
                summary = sess.run(self.summarize, feed_dict)
                self.train_writer.add_summary(summary, t)

        return {'t': t, 'loss': loss}
Пример #14
0
  def update(self, feed_dict=None):
    """Run one iteration of inference.

    Any derived class of `Inference` **must** implement this method.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run. It is used to feed
        placeholders that are not fed during initialization.

    Returns:
      dict.
        Dictionary of algorithm-specific information.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
        feed_dict[key] = value

    sess = get_session()
    t = sess.run(self.increment_t)

    if self.debug:
      sess.run(self.op_check, feed_dict)

    if self.logging and self.n_print != 0:
      if t == 1 or t % self.n_print == 0:
        summary = sess.run(self.summarize, feed_dict)
        self.train_writer.add_summary(summary, t)

    return {'t': t}
Пример #15
0
    def update(self, feed_dict=None):
        """Run one iteration of sampling for Monte Carlo.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run. It is used to feed
      placeholders that are not fed during initialization.

    Returns
    -------
    dict
      Dictionary of algorithm-specific information. In this case, the
      acceptance rate of samples since (and including) this iteration.

    Notes
    -----
    We run the increment of t separately from other ops. Whether the
    others op run with the t before incrementing or after incrementing
    depends on which is run faster in the TensorFlow graph. Running it
    separately forces a consistent behavior.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor):
                feed_dict[key] = value

        sess = get_session()
        _, accept_rate = sess.run([self.train, self.n_accept_over_t],
                                  feed_dict)
        t = sess.run(self.increment_t)
        return {'t': t, 'accept_rate': accept_rate}
Пример #16
0
  def update(self, feed_dict=None):
    """Run one iteration of optimizer for variational inference.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run. It is used to feed
      placeholders that are not fed during initialization.

    Returns
    -------
    dict
      Dictionary of algorithm-specific information. In this case, the
      loss function value after one iteration.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor):
        feed_dict[key] = value

    sess = get_session()
    _, t, loss = sess.run([self.train, self.increment_t, self.loss], feed_dict)
    return {'t': t, 'loss': loss}
Пример #17
0
  def update(self, feed_dict=None):
    """Run one iteration of optimization.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run. It is used to feed
        placeholders that are not fed during initialization.

    Returns:
      dict.
      Dictionary of algorithm-specific information. In this case, the
      loss function value after one iteration.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
        feed_dict[key] = value

    sess = get_session()
    _, t, loss = sess.run([self.train, self.increment_t, self.loss], feed_dict)

    if self.debug:
      sess.run(self.op_check, feed_dict)

    if self.logging and self.n_print != 0:
      if t == 1 or t % self.n_print == 0:
        if self.summarize is not None:
          summary = sess.run(self.summarize, feed_dict)
          self.train_writer.add_summary(summary, t)

    return {'t': t, 'loss': loss}
Пример #18
0
    def update(self, feed_dict=None):
        """Run one iteration of inference.

    Any derived class of `Inference` **must** implement this method.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run. It is used to feed
        placeholders that are not fed during initialization.

    Returns:
      dict.
        Dictionary of algorithm-specific information.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                feed_dict[key] = value

        sess = get_session()
        t = sess.run(self.increment_t)

        if self.debug:
            sess.run(self.op_check, feed_dict)

        if self.logging and self.n_print != 0:
            if t == 1 or t % self.n_print == 0:
                summary = sess.run(self.summarize, feed_dict)
                self.train_writer.add_summary(summary, t)

        return {'t': t}
Пример #19
0
 def print_params(self):
     sess = get_session()
     a, b = sess.run([self.a, self.b])
     print("shape:")
     print(a)
     print("scale:")
     print(b)
Пример #20
0
    def __init__(self, model, data=None):
        """Initialization.

        Parameters
        ----------
        model : ed.Model
            probability model
        data : dict, optional
            Data dictionary. For TensorFlow, Python, and Stan models,
            the key type is a string; for PyMC3, the key type is a
            Theano shared variable. For TensorFlow, Python, and PyMC3
            models, the value type is a NumPy array or TensorFlow
            tensor; for Stan, the value type is the type
            according to the Stan program's data block.

        Notes
        -----
        If ``data`` is not passed in, the dictionary is empty.

        Three options are available for batch training:
        1. internally if user passes in data as a dictionary of NumPy
           arrays;
        2. externally if user passes in data as a dictionary of
           TensorFlow placeholders (and manually feeds them);
        3. externally if user passes in data as TensorFlow tensors
           which are the outputs of data readers.
        """
        sess = get_session()
        self.model = model
        if data is None:
            data = {}

        if isinstance(model, StanModel):
            # Stan models do no support data subsampling because they
            # take arbitrary data structure types in the data block
            # and not just NumPy arrays (this makes it unamenable to
            # TensorFlow placeholders). Therefore fix the data
            # dictionary ``self.data`` at compile time to ``data``.
            self.data = data
        else:
            self.data = {}
            for key, value in six.iteritems(data):
                if isinstance(value, tf.Tensor):
                    # If ``data`` has TensorFlow placeholders, the user
                    # must manually feed them at each step of
                    # inference.
                    # If ``data`` has tensors that are the output of
                    # data readers, then batch training operates
                    # according to the reader.
                    self.data[key] = value
                elif isinstance(value, np.ndarray):
                    # If ``data`` has NumPy arrays, store the data
                    # in the computational graph.
                    placeholder = tf.placeholder(tf.float32, value.shape)
                    var = tf.Variable(placeholder, trainable=False, collections=[])
                    self.data[key] = var
                    sess.run(var.initializer, {placeholder: value})
                else:
                    raise NotImplementedError()
Пример #21
0
    def update(self, feed_dict=None, variables=None):
        """Run one iteration of optimization.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run. It is used to feed
      placeholders that are not fed during initialization.
    variables : str, optional
      Which set of variables to update. Either "Disc" or "Gen".
      Default is both.

    Returns
    -------
    dict
      Dictionary of algorithm-specific information. In this case, the
      iteration number and generative and discriminative losses.

    Notes
    -----
    The outputted iteration number is the total number of calls to
    ``update``. Each update may include updating only a subset of
    parameters.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor):
                if "Placeholder" in key.op.type:
                    feed_dict[key] = value

        sess = get_session()
        if variables is None:
            _, _, t, loss, loss_d = sess.run([
                self.train, self.train_d, self.increment_t, self.loss,
                self.loss_d
            ], feed_dict)
        elif variables == "Gen":
            _, t, loss = sess.run([self.train, self.increment_t, self.loss],
                                  feed_dict)
            loss_d = 0.0
        elif variables == "Disc":
            _, t, loss_d = sess.run(
                [self.train_d, self.increment_t, self.loss_d], feed_dict)
            loss = 0.0
        else:
            raise NotImplementedError()

        if self.debug:
            sess.run(self.op_check)

        if self.logging and self.n_print != 0:
            if t == 1 or t % self.n_print == 0:
                if self.summarize is not None:
                    summary = sess.run(self.summarize, feed_dict)
                    self.train_writer.add_summary(summary, t)

        return {'t': t, 'loss': loss, 'loss_d': loss_d}
Пример #22
0
 def __str__(self):
     try:
         sess = get_session()
         mu, chol = sess.run([self.distribution.mu, self.distribution.chol])
         return "mu: \n" + mu.__str__() + "\n" + \
                "chol: \n" + chol.__str__()
     except:
         return super(MultivariateNormalCholesky, self).__str__()
Пример #23
0
  def update(self, feed_dict=None, variables=None):
    info_dict = super(WGANInference, self).update(feed_dict, variables)

    sess = get_session()
    if self.clip_op is not None and variables in (None, "Disc"):
      sess.run(self.clip_op)

    return info_dict
Пример #24
0
  def update(self, feed_dict=None, variables=None):
    info_dict = super(WGANInference, self).update(feed_dict, variables)

    sess = get_session()
    if variables is None or variables == "Disc":
      sess.run(self.clip_d)

    return info_dict
Пример #25
0
 def __str__(self):
     try:
         sess = get_session()
         n, alpha = sess.run([self.distribution.n, self.distribution.alpha])
         return "n: \n" + n.__str__() + "\n" + \
                "alpha: \n" + alpha.__str__()
     except:
         return super(DirichletMultinomial, self).__str__()
Пример #26
0
 def __str__(self):
     try:
         sess = get_session()
         a, b = sess.run([self.distribution.a, self.distribution.b])
         return "a: \n" + a.__str__() + "\n" + \
                "b: \n" + b.__str__()
     except:
         return super(Beta, self).__str__()
Пример #27
0
    def update(self, feed_dict=None, variables=None):
        info_dict = super(WGANInference, self).update(feed_dict, variables)

        sess = get_session()
        if self.clip_op is not None and variables in (None, "Disc"):
            sess.run(self.clip_op)

        return info_dict
Пример #28
0
    def sample(self, size=1):
        """x ~ p(x | params)"""
        sess = get_session()
        a, b = sess.run([self.alpha, self.beta])
        x = np.zeros((size, self.num_vars))
        for d in range(self.num_vars):
            x[:, d] = invgamma.rvs(a[d], b[d], size=size)

        return x
Пример #29
0
    def sample(self, size=1):
        """z ~ q(z | lambda)"""
        sess = get_session()
        a, b = sess.run([self.a, self.b])
        z = np.zeros((size, self.num_vars))
        for d in range(self.num_vars):
            z[:, d] = invgamma.rvs(a[d], b[d], size=size)

        return z
Пример #30
0
    def sample(self, size=1):
        """z ~ q(z | lambda)"""
        sess = get_session()
        a, b = sess.run([self.a, self.b])
        z = np.zeros((size, self.num_vars))
        for d in range(self.num_vars):
            z[:, d] = invgamma.rvs(a[d], b[d], size=size)

        return z
Пример #31
0
 def __str__(self):
     try:
         sess = get_session()
         loc, scale = sess.run(
             [self.distribution.loc, self.distribution.scale])
         return "loc: \n" + loc.__str__() + "\n" + \
                "scale: \n" + scale.__str__()
     except:
         return super(Laplace, self).__str__()
Пример #32
0
 def __str__(self):
     try:
         sess = get_session()
         mu, diag_stdev = sess.run(
             [self.distribution.mu, self.distribution.diag_stdev])
         return "mu: \n" + mu.__str__() + "\n" + \
                "diag_stdev: \n" + diag_stdev.__str__()
     except:
         return super(MultivariateNormalDiag, self).__str__()
Пример #33
0
 def __str__(self):
     try:
         sess = get_session()
         alpha, beta = sess.run(
             [self.distribution.alpha, self.distribution.beta])
         return "alpha: \n" + alpha.__str__() + "\n" + \
                "beta: \n" + beta.__str__()
     except:
         return super(InverseGamma, self).__str__()
Пример #34
0
 def __str__(self):
     try:
         sess = get_session()
         mu, sigma = sess.run(
             [self.distribution.mu, self.distribution.sigma])
         return "mu: \n" + mu.__str__() + "\n" + \
                "sigma: \n" + sigma.__str__()
     except:
         return super(Normal, self).__str__()
Пример #35
0
  def update(self, feed_dict=None, variables=None):
    """Run one iteration of optimization.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run. It is used to feed
        placeholders that are not fed during initialization.
      variables: str, optional.
        Which set of variables to update. Either "Disc" or "Gen".
        Default is both.

    Returns:
      dict.
      Dictionary of algorithm-specific information. In this case, the
      iteration number and generative and discriminative losses.

    #### Notes

    The outputted iteration number is the total number of calls to
    `update`. Each update may include updating only a subset of
    parameters.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
        feed_dict[key] = value

    sess = get_session()
    if variables is None:
      _, _, t, loss, loss_d = sess.run(
          [self.train, self.train_d, self.increment_t, self.loss, self.loss_d],
          feed_dict)
    elif variables == "Gen":
      _, t, loss = sess.run(
          [self.train, self.increment_t, self.loss], feed_dict)
      loss_d = 0.0
    elif variables == "Disc":
      _, t, loss_d = sess.run(
          [self.train_d, self.increment_t, self.loss_d], feed_dict)
      loss = 0.0
    else:
      raise NotImplementedError("variables must be None, 'Gen', or 'Disc'.")

    if self.debug:
      sess.run(self.op_check, feed_dict)

    if self.logging and self.n_print != 0:
      if t == 1 or t % self.n_print == 0:
        if self.summarize is not None:
          summary = sess.run(self.summarize, feed_dict)
          self.train_writer.add_summary(summary, t)

    return {'t': t, 'loss': loss, 'loss_d': loss_d}
Пример #36
0
    def __init__(self, latent_vars=None, data=None):
        """Initialization.

    Parameters
    ----------
    latent_vars : dict, optional
      Collection of latent variables (of type ``RandomVariable`` or
      ``tf.Tensor``) to perform inference on. Each random variable is
      binded to another random variable; the latter will infer the
      former conditional on data.
    data : dict, optional
      Data dictionary which binds observed variables (of type
      ``RandomVariable`` or ``tf.Tensor``) to their realizations (of
      type ``tf.Tensor``). It can also bind placeholders (of type
      ``tf.Tensor``) used in the model to their realizations; and
      prior latent variables (of type ``RandomVariable``) to posterior
      latent variables (of type ``RandomVariable``).

    Examples
    --------
    >>> mu = Normal(loc=tf.constant(0.0), scale=tf.constant(1.0))
    >>> x = Normal(loc=tf.ones(50) * mu, scale=tf.constant(1.0))
    >>>
    >>> qmu_loc = tf.Variable(tf.random_normal([]))
    >>> qmu_scale = tf.nn.softplus(tf.Variable(tf.random_normal([])))
    >>> qmu = Normal(loc=qmu_loc, scale=qmu_scale)
    >>>
    >>> inference = ed.Inference({mu: qmu}, data={x: tf.zeros(50)})
    """
        sess = get_session()
        if latent_vars is None:
            latent_vars = {}
        if data is None:
            data = {}

        check_latent_vars(latent_vars)
        self.latent_vars = latent_vars

        check_data(data)
        self.data = {}
        for key, value in six.iteritems(data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                self.data[key] = value
            elif isinstance(key, (RandomVariable, tf.Tensor)):
                if isinstance(value, (RandomVariable, tf.Tensor)):
                    self.data[key] = value
                elif isinstance(
                        value, (float, list, int, np.ndarray, np.number, str)):
                    # If value is a Python type, store it in the graph.
                    # Assign its placeholder with the key's data type.
                    with tf.variable_scope("data"):
                        ph = tf.placeholder(key.dtype, np.shape(value))
                        var = tf.Variable(ph, trainable=False, collections=[])
                        sess.run(var.initializer, {ph: value})
                        self.data[key] = var
Пример #37
0
    def update(self):
        """Run one iteration of optimizer for variational inference.

        Returns
        -------
        loss : double
            Loss function values after one iteration.
        """
        sess = get_session()
        _, loss = sess.run([self.train, self.loss])
        return loss
Пример #38
0
    def update(self):
        """Runs one iteration of KLpq minimization.

        Returns
        -------
        loss : double
            KLpq loss function value after one iteration.
        """
        sess = get_session()
        feed_dict = self.variational.np_dict(self.zs)
        _, loss = sess.run([self.train, self.loss], feed_dict)
        return loss
Пример #39
0
 def __str__(self):
     try:
         sess = get_session()
         df, mu, sigma = sess.run([
             self.distribution.df, self.distribution.mu,
             self.distribution.sigma
         ])
         return "df: \n" + df.__str__() + "\n" + \
                "mu: \n" + mu.__str__() + "\n" + \
                "sigma: \n" + sigma.__str__()
     except:
         return super(StudentT, self).__str__()
Пример #40
0
 def __init__(self, layers=[]):
     get_session()
     self.layers = layers
     if layers == []:
         self.num_factors = 0
         self.num_vars = 0
         self.num_params = 0
         self.is_reparam = True
         self.is_normal = True
         self.is_entropy = True
         self.sample_tensor = []
     else:
         self.num_factors = sum([layer.num_factors for layer in self.layers])
         self.num_vars = sum([layer.num_vars for layer in self.layers])
         self.num_params = sum([layer.num_params for layer in self.layers])
         self.is_reparam = all(['reparam' in layer.__class__.__dict__
                                for layer in self.layers])
         self.is_normal = all([isinstance(layer, Normal)
                               for layer in self.layers])
         self.is_entropy = all(['entropy' in layer.__class__.__dict__
                                for layer in self.layers])
         self.sample_tensor = [layer.sample_tensor for layer in self.layers]
Пример #41
0
    def __init__(self, shape=1):
        """Initialize.

        Parameters
        ----------
        shape : int, list, or tuple, optional
            Shape of random variable(s). If ``is_multivariate=True``, then the
            inner-most (right-most) dimension indicates the dimension of
            the multivariate random variable. Otherwise, all dimensions
            are conceptually the same.
        """
        get_session()
        if isinstance(shape, int):
            shape = (shape, )
        elif isinstance(shape, list):
            shape = tuple(shape)

        self.shape = shape
        self.num_vars = np.prod(self.shape)
        self.num_params = None
        self.sample_tensor = False
        self.is_multivariate = False
Пример #42
0
    def __init__(self, shape=1):
        """Initialize.

        Parameters
        ----------
        shape : int, list, or tuple, optional
            Shape of random variable(s). If ``is_multivariate=True``,
            then the inner-most (right-most) dimension indicates the
            multivariate dimension. Otherwise, all dimensions are
            conceptually the same.
        """
        get_session()
        if isinstance(shape, int):
            shape = (shape, )
        elif isinstance(shape, list):
            shape = tuple(shape)

        self.shape = shape
        self.n_vars = np.prod(self.shape)
        self.n_params = None
        self.is_differentiable = False
        self.is_multivariate = False
        self.is_reparameterized = False
Пример #43
0
    def __init__(self, latent_vars=None, data=None):
        """Create an inference algorithm.

    Args:
      latent_vars: dict, optional.
        Collection of latent variables (of type `RandomVariable` or
        `tf.Tensor`) to perform inference on. Each random variable is
        binded to another random variable; the latter will infer the
        former conditional on data.
      data: dict, optional.
        Data dictionary which binds observed variables (of type
        `RandomVariable` or `tf.Tensor`) to their realizations (of
        type `tf.Tensor`). It can also bind placeholders (of type
        `tf.Tensor`) used in the model to their realizations; and
        prior latent variables (of type `RandomVariable`) to posterior
        latent variables (of type `RandomVariable`).
    """
        sess = get_session()
        if latent_vars is None:
            latent_vars = {}
        if data is None:
            data = {}

        check_latent_vars(latent_vars)
        self.latent_vars = latent_vars

        check_data(data)
        self.data = {}
        for key, value in six.iteritems(data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                self.data[key] = value
            elif isinstance(key, (RandomVariable, tf.Tensor)):
                if isinstance(value, (RandomVariable, tf.Tensor)):
                    self.data[key] = value
                elif isinstance(
                        value, (float, list, int, np.ndarray, np.number, str)):
                    # If value is a Python type, store it in the graph.
                    # Assign its placeholder with the key's data type.
                    with tf.variable_scope(None, default_name="data"):
                        ph = tf.placeholder(key.dtype, np.shape(value))
                        var = tf.Variable(ph, trainable=False, collections=[])
                        sess.run(var.initializer, {ph: value})
                        self.data[key] = var
Пример #44
0
  def update(self, feed_dict=None):
    """Run one iteration of sampling for Monte Carlo.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run. It is used to feed
      placeholders that are not fed during initialization.

    Returns
    -------
    dict
      Dictionary of algorithm-specific information. In this case, the
      acceptance rate of samples since (and including) this iteration.

    Notes
    -----
    We run the increment of ``t`` separately from other ops. Whether the
    others op run with the ``t`` before incrementing or after incrementing
    depends on which is run faster in the TensorFlow graph. Running it
    separately forces a consistent behavior.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor):
        feed_dict[key] = value

    sess = get_session()
    _, accept_rate = sess.run([self.train, self.n_accept_over_t], feed_dict)
    t = sess.run(self.increment_t)

    if self.debug:
      sess.run(self.op_check)

    if self.logging and self.n_print != 0:
      if t == 1 or t % self.n_print == 0:
        summary = sess.run(self.summarize, feed_dict)
        self.train_writer.add_summary(summary, t)

    return {'t': t, 'accept_rate': accept_rate}
Пример #45
0
  def __init__(self, latent_vars=None, data=None):
    """Create an inference algorithm.

    Args:
      latent_vars: dict, optional.
        Collection of latent variables (of type `RandomVariable` or
        `tf.Tensor`) to perform inference on. Each random variable is
        binded to another random variable; the latter will infer the
        former conditional on data.
      data: dict, optional.
        Data dictionary which binds observed variables (of type
        `RandomVariable` or `tf.Tensor`) to their realizations (of
        type `tf.Tensor`). It can also bind placeholders (of type
        `tf.Tensor`) used in the model to their realizations; and
        prior latent variables (of type `RandomVariable`) to posterior
        latent variables (of type `RandomVariable`).
    """
    sess = get_session()
    if latent_vars is None:
      latent_vars = {}
    if data is None:
      data = {}

    check_latent_vars(latent_vars)
    self.latent_vars = latent_vars

    check_data(data)
    self.data = {}
    for key, value in six.iteritems(data):
      if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
        self.data[key] = value
      elif isinstance(key, (RandomVariable, tf.Tensor)):
        if isinstance(value, (RandomVariable, tf.Tensor)):
          self.data[key] = value
        elif isinstance(value, (float, list, int, np.ndarray, np.number, str)):
          # If value is a Python type, store it in the graph.
          # Assign its placeholder with the key's data type.
          with tf.variable_scope("data"):
            ph = tf.placeholder(key.dtype, np.shape(value))
            var = tf.Variable(ph, trainable=False, collections=[])
            sess.run(var.initializer, {ph: value})
            self.data[key] = var
Пример #46
0
    def update(self, feed_dict=None):
        """Run one iteration of sampling.

    Args:
      feed_dict: dict.
        Feed dictionary for a TensorFlow session run. It is used to feed
        placeholders that are not fed during initialization.

    Returns:
      dict.
      Dictionary of algorithm-specific information. In this case, the
      acceptance rate of samples since (and including) this iteration.

    #### Notes

    We run the increment of `t` separately from other ops. Whether the
    others op run with the `t` before incrementing or after incrementing
    depends on which is run faster in the TensorFlow graph. Running it
    separately forces a consistent behavior.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                feed_dict[key] = value

        sess = get_session()
        _, accept_rate = sess.run([self.train, self.n_accept_over_t],
                                  feed_dict)
        t = sess.run(self.increment_t)

        if self.debug:
            sess.run(self.op_check, feed_dict)

        if self.logging and self.n_print != 0:
            if t == 1 or t % self.n_print == 0:
                summary = sess.run(self.summarize, feed_dict)
                self.train_writer.add_summary(summary, t)

        return {'t': t, 'accept_rate': accept_rate}
Пример #47
0
    def finalize(self, feed_dict=None):
        """Function to call after convergence.

    Computes the Hessian at the mode.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run during evaluation
        of Hessian. It is used to feed placeholders that are not fed
        during initialization.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                feed_dict[key] = value

        sess = get_session()
        sess.run(self.finalize_ops, feed_dict)
        super(Laplace, self).finalize()
Пример #48
0
  def finalize(self, feed_dict=None):
    """Function to call after convergence.

    Computes the Hessian at the mode.

    Args:
      feed_dict: dict, optional.
        Feed dictionary for a TensorFlow session run during evaluation
        of Hessian. It is used to feed placeholders that are not fed
        during initialization.
    """
    if feed_dict is None:
      feed_dict = {}

    for key, value in six.iteritems(self.data):
      if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
        feed_dict[key] = value

    sess = get_session()
    sess.run(self.finalize_ops, feed_dict)
    super(Laplace, self).finalize()
Пример #49
0
    def finalize(self, feed_dict=None):
        """Function to call after convergence.

    Computes the Hessian at the mode.

    Parameters
    ----------
    feed_dict : dict, optional
      Feed dictionary for a TensorFlow session run during evaluation
      of Hessian. It is used to feed placeholders that are not fed
      during initialization.
    """
        if feed_dict is None:
            feed_dict = {}

        for key, value in six.iteritems(self.data):
            if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type:
                feed_dict[key] = value

        var_list = list(six.itervalues(self.latent_vars))
        hessians = tf.hessians(self.loss, var_list)

        assign_ops = []
        for z, hessian in zip(six.iterkeys(self.latent_vars), hessians):
            qz = self.latent_vars_normal[z]
            sigma_var = get_variables(qz.sigma)[0]
            if isinstance(qz, MultivariateNormalCholesky):
                sigma = tf.matrix_inverse(tf.cholesky(hessian))
            elif isinstance(qz, MultivariateNormalDiag):
                sigma = 1.0 / tf.diag_part(hessian)
            else:  # qz is MultivariateNormalFull
                sigma = tf.matrix_inverse(hessian)

            assign_ops.append(sigma_var.assign(sigma))

        sess = get_session()
        sess.run(assign_ops, feed_dict)
        self.latent_vars = self.latent_vars_normal.copy()
        del self.latent_vars_normal
        super(Laplace, self).finalize()
Пример #50
0
def eval_model(Xx, Yy, nom, probabilities=None,
               dataset=None, qw=None, qb=None):
    if probabilities is None:
        ans = get_y_preds(Xx, Yy, qvars=[qw, qb], n_samples=10000)
        zw, zb = [np.mean(an, axis=0) for an in ans]
        probabilities = sigmoid(Xx.dot(zw) + zb)

    ins = pd.DataFrame(probabilities, columns=['prob'])
    ins['target'] = Yy
    ins['guess'] = ins['prob'].round().clip(0, 1)
    print(nom, '\n------')
    print('acc:', (ins['target'] == ins['guess']).mean())
    print('sk.logloss:', log_loss(ins['target'], ins['prob']))
    sess = get_session()
    print('ed.logloss (corrected):', sess.run(
        binary_crossentropy(ins['target'], -np.log(1 / ins['prob'] - 1))))
    print('ed.logloss (current):',
          sess.run(binary_crossentropy(ins['target'], ins['prob'])))

    if dataset is not None:
        if nom == 'ins':
            eras = dataset.training_data['era']
        else:
            eras = dataset.prediction_data['era']

        big_ins = pd.concat([pd.DataFrame(Xx), eras, ins], axis=1).dropna()
        consist = 0
        for x in big_ins.era.unique():
            lil_ins = big_ins[big_ins.era == x]
            lloss = log_loss(lil_ins['target'], lil_ins['prob'])
            print(x.replace("era", "regime"),
                  '(%s) :' % str(float(len(lil_ins)) / len(big_ins))[:5],
                  (lil_ins['target'] == lil_ins['guess']).mean(),
                  lloss)
            if lloss < -np.log(.5):
                consist += 1

        print('consistency:', float(consist) / len(big_ins.era.unique()))
        print('')
    return ins
Пример #51
0
def ppc(T, data, latent_vars=None, n_samples=100):
  """Posterior predictive check
  (Rubin, 1984; Meng, 1994; Gelman, Meng, and Stern, 1996).

  PPC's form an empirical distribution for the predictive discrepancy,

  $p(T\mid x) = \int p(T(x^{\\text{rep}})\mid z) p(z\mid x) dz$

  by drawing replicated data sets $x^{\\text{rep}}$ and
  calculating $T(x^{\\text{rep}})$ for each data set. Then it
  compares it to $T(x)$.

  If `data` is inputted with the prior predictive distribution, then
  it is a prior predictive check (Box, 1980).

  Args:
    T: function.
      Discrepancy function, which takes a dictionary of data and
      dictionary of latent variables as input and outputs a `tf.Tensor`.
    data: dict.
      Data to compare to. It binds observed variables (of type
      `RandomVariable` or `tf.Tensor`) to their realizations (of
      type `tf.Tensor`). It can also bind placeholders (of type
      `tf.Tensor`) used in the model to their realizations.
    latent_vars: dict, optional.
      Collection of random variables (of type `RandomVariable` or
      `tf.Tensor`) binded to their inferred posterior. This argument
      is used when the discrepancy is a function of latent variables.
    n_samples: int, optional.
      Number of replicated data sets.

  Returns:
    list of np.ndarray.
    List containing the reference distribution, which is a NumPy array
    with `n_samples` elements,

    $(T(x^{{\\text{rep}},1}, z^{1}), ...,
       T(x^{\\text{rep,nsamples}}, z^{\\text{nsamples}}))$

    and the realized discrepancy, which is a NumPy array with
    `n_samples` elements,

    $(T(x, z^{1}), ..., T(x, z^{\\text{nsamples}})).$


  #### Examples

  ```python
  # build posterior predictive after inference:
  # it is parameterized by a posterior sample
  x_post = ed.copy(x, {z: qz, beta: qbeta})

  # posterior predictive check
  # T is a user-defined function of data, T(data)
  T = lambda xs, zs: tf.reduce_mean(xs[x_post])
  ed.ppc(T, data={x_post: x_train})

  # in general T is a discrepancy function of the data (both response and
  # covariates) and latent variables, T(data, latent_vars)
  T = lambda xs, zs: tf.reduce_mean(zs[z])
  ed.ppc(T, data={y_post: y_train, x_ph: x_train},
         latent_vars={z: qz, beta: qbeta})

  # prior predictive check
  # run ppc on original x
  ed.ppc(T, data={x: x_train})
  ```
  """
  sess = get_session()
  if not callable(T):
    raise TypeError("T must be a callable function.")

  check_data(data)
  if latent_vars is None:
    latent_vars = {}

  check_latent_vars(latent_vars)
  if not isinstance(n_samples, int):
    raise TypeError("n_samples must have type int.")

  # Build replicated latent variables.
  zrep = {key: tf.convert_to_tensor(value)
          for key, value in six.iteritems(latent_vars)}

  # Build replicated data.
  xrep = {x: (x.value() if isinstance(x, RandomVariable) else obs)
          for x, obs in six.iteritems(data)}

  # Create feed_dict for data placeholders that the model conditions
  # on; it is necessary for all session runs.
  feed_dict = {key: value for key, value in six.iteritems(data)
               if isinstance(key, tf.Tensor) and "Placeholder" in key.op.type}

  # Calculate discrepancy over many replicated data sets and latent
  # variables.
  Trep = T(xrep, zrep)
  Tobs = T(data, zrep)
  Treps = []
  Ts = []
  for _ in range(n_samples):
    # Take a forward pass (session run) to get new samples for
    # each calculation of the discrepancy.
    # Alternatively, we could unroll the graph by registering this
    # operation `n_samples` times, each for different parent nodes
    # representing `xrep` and `zrep`. But it's expensive.
    Treps += [sess.run(Trep, feed_dict)]
    Ts += [sess.run(Tobs, feed_dict)]

  return [np.stack(Treps), np.stack(Ts)]
Пример #52
0
 def __init__(self, num_factors=1):
     get_session()
     self.num_factors = num_factors
     self.num_vars = None
     self.num_params = None
     self.sample_tensor = False
Пример #53
0
def ppc(T, data, latent_vars=None, model_wrapper=None, n_samples=100):
  """Posterior predictive check
  (Rubin, 1984; Meng, 1994; Gelman, Meng, and Stern, 1996).

  If ``latent_vars`` is inputted as ``None``, then it is a prior
  predictive check (Box, 1980).

  PPC's form an empirical distribution for the predictive discrepancy,

  .. math::
    p(T) = \int p(T(x^{rep}) | z) p(z | x) dz

  by drawing replicated data sets xrep and calculating
  :math:`T(x^{rep})` for each data set. Then it compares it to
  :math:`T(x)`.

  Parameters
  ----------
  T : function
    Discrepancy function, which takes a dictionary of data and
    dictionary of latent variables as input and outputs a ``tf.Tensor``.
  data : dict
    Data to compare to. It binds observed variables (of type
    ``RandomVariable``) to their realizations (of type ``tf.Tensor``). It
    can also bind placeholders (of type ``tf.Tensor``) used in the model
    to their realizations.
  latent_vars : dict of str to RandomVariable, optional
    Collection of random variables binded to their inferred posterior.
    It is an optional argument, necessary for when the discrepancy is
    a function of latent variables.
  model_wrapper : ed.Model, optional
    An optional wrapper for the probability model. It must have a
    ``sample_likelihood`` method. If ``latent_vars`` is not specified,
    it must also have a ``sample_prior`` method, as ``ppc`` will
    default to a prior predictive check. ``data`` is also changed. For
    TensorFlow, Python, and Stan models, the key type is a string; for
    PyMC3, the key type is a Theano shared variable. For TensorFlow,
    Python, and PyMC3 models, the value type is a NumPy array or
    TensorFlow placeholder; for Stan, the value type is the type
    according to the Stan program's data block.
  n_samples : int, optional
    Number of replicated data sets.

  Returns
  -------
  list of np.ndarray
    List containing the reference distribution, which is a NumPy
    array of size elements,

    .. math::
      (T(x^{rep,1}, z^{1}), ..., T(x^{rep,size}, z^{size}))

    and the realized discrepancy, which is a NumPy array of size
    elements,

    .. math::
      (T(x, z^{1}), ..., T(x, z^{size})).


  Examples
  --------
  >>> # build posterior predictive after inference: it is
  >>> # parameterized by posterior means
  >>> x_post = copy(x, {z: qz.mean(), beta: qbeta.mean()})
  >>>
  >>> # posterior predictive check
  >>> # T is a user-defined function of data, T(data)
  >>> T = lambda xs, zs: tf.reduce_mean(xs[x_post])
  >>> ppc(T, data={x_post: x_train})
  >>>
  >>> # in general T is a discrepancy function of the data (both response and
  >>> # covariates) and latent variables, T(data, latent_vars)
  >>> T = lambda xs, zs: tf.reduce_mean(zs['z'])
  >>> ppc(T, data={y_post: y_train, x_ph: x_train},
  ...     latent_vars={'z': qz, 'beta': qbeta})
  >>>
  >>> # prior predictive check
  >>> # running ppc on original x
  >>> ppc(T, data={x: x_train})
  """
  sess = get_session()
  # Sample to get replicated data sets and latent variables.
  if model_wrapper is None:
    if latent_vars is None:
      zrep = None
    else:
      zrep = {key: value.value()
              for key, value in six.iteritems(latent_vars)}

    xrep = {}
    for x, obs in six.iteritems(data):
      if isinstance(x, RandomVariable):
        # Replace observed data with replicated data.
        xrep[x] = x.value()
      else:
        xrep[x] = obs
  else:
    if latent_vars is None:
      zrep = model_wrapper.sample_prior()
    else:
      zrep = {key: value.value()
              for key, value in six.iteritems(latent_vars)}

    xrep = model_wrapper.sample_likelihood(zrep)

  # Create feed_dict for data placeholders that the model conditions
  # on; it is necessary for all session runs.
  feed_dict = {x: obs for x, obs in six.iteritems(data)
               if not isinstance(x, RandomVariable) and
               not isinstance(x, str)}

  # Calculate discrepancy over many replicated data sets and latent
  # variables.
  Trep = T(xrep, zrep)
  Tobs = T(data, zrep)
  Treps = []
  Ts = []
  for s in range(n_samples):
    # Take a forward pass (session run) to get new samples for
    # each calculation of the discrepancy.
    # Note that alternatively we can unroll the graph by registering
    # this operation ``n_samples`` times, each for different parent
    # nodes representing ``xrep`` and ``zrep``.
    Treps += [sess.run(Trep, feed_dict)]
    Ts += [sess.run(Tobs, feed_dict)]

  return [np.stack(Treps), np.stack(Ts)]
Пример #54
0
def ppc(model, variational=None, data=None, T=None, size=100):
    """Posterior predictive check.
    (Rubin, 1984; Meng, 1994; Gelman, Meng, and Stern, 1996)
    If no posterior approximation is provided through ``variational``,
    then we default to a prior predictive check (Box, 1980).

    PPC's form an empirical distribution for the predictive discrepancy,

    .. math::
        p(T) = \int p(T(yrep) | z) p(z | y) dz

    by drawing replicated data sets yrep and calculating
    :math:`T(yrep)` for each data set. Then it compares it to
    :math:`T(y)`.

    Parameters
    ----------
    model : ed.Model
        class object that implements the ``sample_likelihood`` method
    variational : ed.Variational, optional
        latent variable distribution q(z) to sample from. It is an
        approximation to the posterior, e.g., a variational
        approximation or an empirical distribution from MCMC samples.
        If not specified, samples will be obtained from the model
        through the ``sample_prior`` method.
    data : dict, optional
        Observed data to compare to. If not specified, will return
        only the reference distribution with an assumed replicated
        data set size of 1. For TensorFlow, Python, and Stan models,
        the key type is a string; for PyMC3, the key type is a Theano
        shared variable. For TensorFlow, Python, and PyMC3 models, the
        value type is a NumPy array or TensorFlow placeholder; for
        Stan, the value type is the type according to the Stan
        program's data block.
    T : function, optional
        Discrepancy function, which takes a data dictionary and list
        of latent variables as input and outputs a tf.Tensor. Default
        is the identity function.
    size : int, optional
        number of replicated data sets

    Returns
    -------
    list
        List containing the reference distribution, which is a Numpy
        vector of size elements,

        .. math::
            (T(yrep^{1}, z^{1}), ..., T(yrep^{size}, z^{size}))

        and the realized discrepancy, which is a NumPy vector of size
        elements,

        .. math::
            (T(y, z^{1}), ..., T(y, z^{size})).

        If the discrepancy function is not specified, then the list
        contains the full data distribution where each element is a
        data set (dictionary).
    """
    sess = get_session()
    if data is None:
        N = 1
        y = {}
    else:
        # Assume all values have the same data set size.
        N = get_dims(list(six.itervalues(data))[0])[0]
        y = data

    # 1. Sample from posterior (or prior).
    # We must fetch zs out of the session because sample_likelihood()
    # may require a SciPy-based sampler.
    if variational is not None:
        zs = variational.sample(size=size)
        # This is to avoid fetching, e.g., a placeholder x with the
        # dictionary {x: np.array()}. TensorFlow will raise an error.
        if isinstance(zs, list):
            zs = [tf.identity(zs_elem) for zs_elem in zs]
        else:
            zs = tf.identity(zs)

        zs = sess.run(zs)
    else:
        zs = model.sample_prior(size=size)
        zs = zs.eval()

    # 2. Sample from likelihood.
    yreps = model.sample_likelihood(zs, size=N)

    # 3. Calculate discrepancy.
    if T is None:
        if y is None:
            return yreps
        else:
            return [yreps, y]

    Tyreps = []
    Tys = []
    for yrep, z in zip(yreps, tf.unpack(zs)):
        Tyreps += [T(yrep, z)]
        if y is not None:
            Tys += [T(y, z)]

    if y is None:
        return sess.run(tf.pack(Tyreps))
    else:
        return sess.run([tf.pack(Tyreps), tf.pack(Tys)])
Пример #55
0
def evaluate(metrics, model, variational, data, y_true=None):
    """Evaluate fitted model using a set of metrics.

    Parameters
    ----------
    metrics : list or str
        List of metrics or a single metric.
    model : ed.Model
        Probability model p(x, z)
    variational : ed.Variational
        Variational approximation to the posterior p(z | x)
    data : dict
        Data dictionary to evaluate model with. For TensorFlow,
        Python, and Stan models, the key type is a string; for PyMC3,
        the key type is a Theano shared variable. For TensorFlow,
        Python, and PyMC3 models, the value type is a NumPy array or
        TensorFlow placeholder; for Stan, the value type is the type
        according to the Stan program's data block.
    y_true : np.ndarray or tf.Tensor
        True values to compare to in supervised learning tasks.

    Returns
    -------
    list or float
        A list of evaluations or a single evaluation.

    Raises
    ------
    NotImplementedError
        If an input metric does not match an implemented metric in Edward.
    """
    sess = get_session()
    # Monte Carlo estimate the mean of the posterior predictive:
    # 1. Sample a batch of latent variables from posterior
    n_minibatch = 100
    zs = variational.sample(size=n_minibatch)
    # 2. Make predictions, averaging over each sample of latent variables
    y_pred = model.predict(data, zs)

    # Evaluate y_pred according to y_true for all metrics.
    evaluations = []
    if isinstance(metrics, str):
        metrics = [metrics]

    for metric in metrics:
        if metric == 'accuracy' or metric == 'crossentropy':
            # automate binary or sparse cat depending on max(y_true)
            support = tf.reduce_max(y_true).eval()
            if support <= 1:
                metric = 'binary_' + metric
            else:
                metric = 'sparse_categorical_' + metric

        if metric == 'binary_accuracy':
            evaluations += [sess.run(binary_accuracy(y_true, y_pred))]
        elif metric == 'categorical_accuracy':
            evaluations += [sess.run(categorical_accuracy(y_true, y_pred))]
        elif metric == 'sparse_categorical_accuracy':
            evaluations += [sess.run(sparse_categorical_accuracy(y_true, y_pred))]
        elif metric == 'log_loss' or metric == 'binary_crossentropy':
            evaluations += [sess.run(binary_crossentropy(y_true, y_pred))]
        elif metric == 'categorical_crossentropy':
            evaluations += [sess.run(categorical_crossentropy(y_true, y_pred))]
        elif metric == 'sparse_categorical_crossentropy':
            evaluations += [sess.run(sparse_categorical_crossentropy(y_true, y_pred))]
        elif metric == 'hinge':
            evaluations += [sess.run(hinge(y_true, y_pred))]
        elif metric == 'squared_hinge':
            evaluations += [sess.run(squared_hinge(y_true, y_pred))]
        elif metric == 'mse' or metric == 'MSE' or \
             metric == 'mean_squared_error':
            evaluations += [sess.run(mean_squared_error(y_true, y_pred))]
        elif metric == 'mae' or metric == 'MAE' or \
             metric == 'mean_absolute_error':
            evaluations += [sess.run(mean_absolute_error(y_true, y_pred))]
        elif metric == 'mape' or metric == 'MAPE' or \
             metric == 'mean_absolute_percentage_error':
            evaluations += [sess.run(mean_absolute_percentage_error(y_true, y_pred))]
        elif metric == 'msle' or metric == 'MSLE' or \
             metric == 'mean_squared_logarithmic_error':
            evaluations += [sess.run(mean_squared_logarithmic_error(y_true, y_pred))]
        elif metric == 'poisson':
            evaluations += [sess.run(poisson(y_true, y_pred))]
        elif metric == 'cosine' or metric == 'cosine_proximity':
            evaluations += [sess.run(cosine_proximity(y_true, y_pred))]
        elif metric == 'log_lik' or metric == 'log_likelihood':
            evaluations += [sess.run(y_pred)]
        else:
            raise NotImplementedError()

    if len(evaluations) == 1:
        return evaluations[0]
    else:
        return evaluations
Пример #56
0
 def __str__(self):
     sess = get_session()
     a, b = sess.run([self.alpha, self.beta])
     return "shape: \n" + a.__str__() + "\n" + \
            "scale: \n" + b.__str__()
Пример #57
0
 def sample(self, size=1):
     sess = get_session()
     a, b = sess.run([self.alpha, self.beta])
     return invgamma.rvs(a, b, size=size)
Пример #58
0
 def __str__(self):
     sess = get_session()
     m, s = sess.run([self.loc, self.scale])
     return "mean: \n" + m.__str__() + "\n" + \
            "std dev: \n" + s.__str__()