コード例 #1
0
  def __init__(self, latent_vars, data=None, discriminator=None,
               global_vars=None):
    """Create an inference algorithm.

    Args:
      discriminator: function.
        Function (with parameters). Unlike `GANInference`, it is
        interpreted as a ratio estimator rather than a discriminator.
        It takes three arguments: a data dict, local latent variable
        dict, and global latent variable dict. As with GAN
        discriminators, it can take a batch of data points and local
        variables, of size $M$, and output a vector of length
        $M$.
      global_vars: dict of RandomVariable to RandomVariable.
        Identifying which variables in `latent_vars` are global
        variables, shared across data points. These will not be
        encompassed in the ratio estimation problem, and will be
        estimated with tractable variational approximations.
    """
    if not callable(discriminator):
      raise TypeError("discriminator must be a callable function.")

    self.discriminator = discriminator
    if global_vars is None:
      global_vars = {}

    check_latent_vars(global_vars)
    self.global_vars = global_vars
    # call grandparent's method; avoid parent (GANInference)
    super(GANInference, self).__init__(latent_vars, data)
コード例 #2
0
  def __init__(self, latent_vars, proposal_vars, data=None,
               inverse_temperatures=np.logspace(0, -2, 5), exchange_freq=0.1):
    """Create an inference algorithm.

    Args:
      proposal_vars: dict of RandomVariable to RandomVariable.
        Collection of random variables to perform inference on; each is
        binded to a proposal distribution $g(z' \mid z)$.
      inverse_temperatures: list of inverse temperature.
      exchange_freq: frequency of exchanging replica.
    """
    check_latent_vars(proposal_vars)
    self.proposal_vars = proposal_vars

    self.n_replica = len(inverse_temperatures)
    if inverse_temperatures[0] != 1:
      raise ValueError("inverse_temperatures[0] must be 1.")
    self.inverse_temperatures = [tf.convert_to_tensor(inverse_temperature,
                                 dtype=list(latent_vars.values())[0].dtype)
                                 for inverse_temperature in
                                 inverse_temperatures]

    # Make replica.
    self.replica_vars = []
    for inverse_temperature in self.inverse_temperatures:
      self.replica_vars.append({z: Empirical(params=tf.Variable(tf.zeros(
          qz.params.shape, dtype=latent_vars[z].dtype))) for z, qz in
          six.iteritems(latent_vars)})

    self.exchange_freq = exchange_freq

    super(ReplicaExchangeMC, self).__init__(latent_vars, data)
コード例 #3
0
ファイル: gibbs.py プロジェクト: ylfzr/edward
    def __init__(self, latent_vars, proposal_vars=None, data=None):
        """
    Parameters
    ----------
    proposal_vars : dict of RandomVariable to RandomVariable, optional
      Collection of random variables to perform inference on; each is
      binded to its complete conditionals which Gibbs cycles draws on.
      If not specified, default is to use ``ed.complete_conditional``.

    Examples
    --------
    >>> x_data = np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 1])
    >>>
    >>> p = Beta(1.0, 1.0)
    >>> x = Bernoulli(p=p, sample_shape=10)
    >>>
    >>> qp = Empirical(tf.Variable(tf.zeros(500)))
    >>> inference = ed.Gibbs({p: qp}, data={x: x_data})
    """
        if proposal_vars is None:
            proposal_vars = {
                z: complete_conditional(z)
                for z in six.iterkeys(latent_vars)
            }
        else:
            check_latent_vars(proposal_vars)

        self.proposal_vars = proposal_vars
        super(Gibbs, self).__init__(latent_vars, data)
コード例 #4
0
ファイル: replica_exchange_mc.py プロジェクト: JoyceYa/edward
  def __init__(self, latent_vars, proposal_vars, data=None,
               inverse_temperatures=np.logspace(0, -2, 5), exchange_freq=0.1):
    """Create an inference algorithm.

    Args:
      proposal_vars: dict of RandomVariable to RandomVariable.
        Collection of random variables to perform inference on; each is
        binded to a proposal distribution $g(z' \mid z)$.
      inverse_temperatures: list of inverse temperature.
      exchange_freq: frequency of exchanging replica.
    """
    check_latent_vars(proposal_vars)
    self.proposal_vars = proposal_vars
    super(ReplicaExchangeMC, self).__init__(latent_vars, data)

    self.n_replica = len(inverse_temperatures)
    if inverse_temperatures[0] != 1:
      raise ValueError("inverse_temperatures[0] must be 1.")
    self.inverse_temperatures = tf.cast(inverse_temperatures,
                                        dtype=list(self.latent_vars)[0].dtype)

    # Make replica.
    self.replica_vars = []
    for i in range(self.n_replica):
      self.replica_vars.append({z: Empirical(params=tf.Variable(tf.zeros(
          qz.params.shape, dtype=self.latent_vars[z].dtype))) for z, qz in
          six.iteritems(self.latent_vars)})

    self.exchange_freq = exchange_freq
コード例 #5
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
コード例 #6
0
  def __init__(self, latent_vars, proposal_vars, data=None):
    """Create an inference algorithm.

    Args:
      proposal_vars: dict of RandomVariable to RandomVariable.
        Collection of random variables to perform inference on; each is
        binded to a proposal distribution $g(z' \mid z)$.
    """
    check_latent_vars(proposal_vars)
    self.proposal_vars = proposal_vars
    super(MetropolisHastings, self).__init__(latent_vars, data)
コード例 #7
0
ファイル: metropolis_hastings.py プロジェクト: ekostem/edward
  def __init__(self, latent_vars, proposal_vars, data=None):
    """Create an inference algorithm.

    Args:
      proposal_vars: dict of RandomVariable to RandomVariable.
        Collection of random variables to perform inference on; each is
        binded to a proposal distribution $g(z' \mid z)$.
    """
    check_latent_vars(proposal_vars)
    self.proposal_vars = proposal_vars
    super(MetropolisHastings, self).__init__(latent_vars, data)
コード例 #8
0
ファイル: implicit_klqp.py プロジェクト: ylfzr/edward
    def __init__(self,
                 latent_vars,
                 data=None,
                 discriminator=None,
                 global_vars=None):
        """
    Parameters
    ----------
    discriminator : function
      Function (with parameters). Unlike ``GANInference``, it is
      interpreted as a ratio estimator rather than a discriminator.
      It takes three arguments: a data dict, local latent variable
      dict, and global latent variable dict. As with GAN
      discriminators, it can take a batch of data points and local
      variables, of size :math:`M`, and output a vector of length
      :math:`M`.
    global_vars : dict of RandomVariable to RandomVariable, optional
      Identifying which variables in ``latent_vars`` are global
      variables, shared across data points. These will not be
      encompassed in the ratio estimation problem, and will be
      estimated with tractable variational approximations.

    Notes
    -----
    Unlike ``GANInference``, ``discriminator`` takes dict's as input,
    and must subset to the appropriate values through lexical scoping
    from the previously defined model and latent variables. This is
    necessary as the discriminator can take an arbitrary set of data,
    latent, and global variables.

    Note the type for ``discriminator``'s output changes when one
    passes in the ``scale`` argument to ``initialize()``.

    + If ``scale`` has at most one item, then ``discriminator``
    outputs a tensor whose multiplication with that element is
    broadcastable. (For example, the output is a tensor and the single
    scale factor is a scalar.)
    + If ``scale`` has more than one item, then in order to scale
    its corresponding output, ``discriminator`` must output a
    dictionary of same size and keys as ``scale``.
    """
        if not callable(discriminator):
            raise TypeError("discriminator must be a callable function.")

        self.discriminator = discriminator
        if global_vars is None:
            global_vars = {}

        check_latent_vars(global_vars)
        self.global_vars = global_vars
        # call grandparent's method; avoid parent (GANInference)
        super(GANInference, self).__init__(latent_vars, data)
コード例 #9
0
ファイル: gibbs.py プロジェクト: zhuoliwu/edward
  def __init__(self, latent_vars, proposal_vars=None, data=None):
    """Create an inference algorithm.

    Args:
      proposal_vars: dict of RandomVariable to RandomVariable, optional.
        Collection of random variables to perform inference on; each is
        binded to its complete conditionals which Gibbs cycles draws on.
        If not specified, default is to use `ed.complete_conditional`.
    """
    if proposal_vars is None:
      proposal_vars = {z: complete_conditional(z)
                       for z in six.iterkeys(latent_vars)}
    else:
      check_latent_vars(proposal_vars)

    self.proposal_vars = proposal_vars
    super(Gibbs, self).__init__(latent_vars, data)
コード例 #10
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
コード例 #11
0
ファイル: inference.py プロジェクト: ekostem/edward
  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
コード例 #12
0
ファイル: metropolis_hastings.py プロジェクト: powa64/edward
  def __init__(self, latent_vars, proposal_vars, data=None):
    """
    Parameters
    ----------
    proposal_vars : dict of RandomVariable to RandomVariable
      Collection of random variables to perform inference on; each is
      binded to a proposal distribution :math:`g(z' \mid z)`.

    Examples
    --------
    >>> z = Normal(mu=0.0, sigma=1.0)
    >>> x = Normal(mu=tf.ones(10) * z, sigma=1.0)
    >>>
    >>> qz = Empirical(tf.Variable(tf.zeros(500)))
    >>> proposal_z = Normal(mu=z, sigma=0.5)
    >>> data = {x: np.array([0.0] * 10, dtype=np.float32)}
    >>> inference = ed.MetropolisHastings({z: qz}, {z: proposal_z}, data)
    """
    check_latent_vars(proposal_vars)
    self.proposal_vars = proposal_vars
    super(MetropolisHastings, self).__init__(latent_vars, data)
  def test(self):
    with self.test_session():
      mu = Normal(0.0, 1.0)
      qmu = Normal(tf.Variable(0.0), tf.constant(1.0))
      qmu_vec = Normal(tf.constant([0.0]), tf.constant([1.0]))

      check_latent_vars({mu: qmu})
      check_latent_vars({mu: tf.constant(0.0)})
      check_latent_vars({tf.constant(0.0): qmu})
      self.assertRaises(TypeError, check_latent_vars, {mu: '5'})
      self.assertRaises(TypeError, check_latent_vars, {mu: qmu_vec})
コード例 #14
0
ファイル: ppc.py プロジェクト: ekostem/edward
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)]
コード例 #15
0
def ppc(T, data, latent_vars=None, n_samples=100):
    """Posterior predictive check
  [@rubin1984bayesianly; @meng1994posterior; @gelman1996posterior].

  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 [@box1980sampling].

  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)]