1

考虑observe概率编程中语句的定义,如 [1] 中所定义:

观察语句阻止不满足布尔表达式 E 的运行,并且不允许这些执行发生。

现在,考虑以下理论程序:

def f():
    x ~ Normal(0, 1)
    observe(x > 0) # only allow samples x > 0
    return x

它应该从截断的Normal(0, 1)分布中返回值。

因此,我的问题是:如何observe在 TensorFlow Probability 中实现,或者它的等价物是什么?请注意,observe' 参数应该是任何(符号)布尔表达式E:(例如lambda x: x > 0)。

注意:当然,对于上面的程序,可以使用HalfNormal发行版,但我将它用于observe.


[1] 戈登、安德鲁 D. 等人。“概率编程。” 软件工程的未来论文集。2014. 167-181。

4

1 回答 1

1

一般来说,实现这一目标的唯一方法是使用昂贵的拒绝采样器。然后你就没有易处理的密度。一般来说,TFP 要求我们所有的分布都具有易于处理的密度(即dist.prob(x))。我们确实有一个 autodiff 友好的TruncatedNormal,或者你注意到HalfNormal的。

如果你想实现其他东西,它可能很简单:

class Rejection(tfd.Distribution):
  def __init__(self, underlying, condition, name=None):
    self._u = underlying
    self._c = condition
    super().__init__(dtype=underlying.dtype, 
                     name=name or f'rejection_{underlying}',
                     reparameterization_type=tfd.NOT_REPARAMETERIZED,
                     validate_args=underlying.validate_args,
                     allow_nan_stats=underlying.allow_nan_stats)
  def _batch_shape(self):
    return self._u.batch_shape
  def _batch_shape_tensor(self):
    return self._u.batch_shape_tensor()
  def _event_shape(self):
    return self._u.event_shape
  def _event_shape_tensor(self):
    return self._u.event_shape_tensor()

  def _sample_n(self, n, seed=None):
    return tf.while_loop(
        lambda samples: not tf.reduce_all(self._c(samples)),
        lambda samples: (tf.where(self._c(samples), samples, self._u.sample(n, seed=seed)),),
        (self._u.sample(n, seed=seed),))[0]

d = Rejection(tfd.Normal(0,1), lambda x: x > -.3)
s = d.sample(100).numpy()
print(s.min())
于 2020-03-12T10:45:34.570 回答