Использование и изменение переменных в биекторах тензорного потока - PullRequest
0 голосов
/ 16 ноября 2018

В справочнике paper для распределений TensorFlow (теперь Вероятность ) упоминается, что TensorFlow Variable s можно использовать для создания Bijector и TransformedDistribution объектов,т.е.:

import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions

tf.enable_eager_execution()

shift = tf.Variable(1., dtype=tf.float32)
myBij = tfp.bijectors.Affine(shift=shift)

# Normal distribution centered in zero, then shifted to 1 using the bijection
myDistr = tfd.TransformedDistribution(
            distribution=tfd.Normal(loc=0., scale=1.),
            bijector=myBij,
            name="test")

# 2 samples of a normal centered at 1:
y = myDistr.sample(2)
# 2 samples of a normal centered at 0, obtained using inverse transform of myBij:
x = myBij.inverse(y)

Теперь я хотел бы изменить переменную сдвига (скажем, я мог бы вычислить градиенты некоторой функции правдоподобия как функцию сдвига и обновить ее значение), поэтому я делаю

shift.assign(2.)
gx = myBij.forward(x)

Я бы ожидал, что gx=y+1, но я вижу, что gx=y ... И действительно, myBij.shift по-прежнему достигает значения 1.

Если я попытаюсь изменить биектор напрямую,т.е.:

myBij.shift.assign(2.)

Я получаю

AttributeError: 'tensorflow.python.framework.ops.EagerTensor' object has no attribute 'assign'

Вычисление градиентов также не работает должным образом:

with tf.GradientTape() as tape:
    gx = myBij.forward(x)
grad = tape.gradient(gx, shift)

Выход None, а также это исключениекогда сценарий заканчивается:

Exception ignored in: <bound method GradientTape.__del__ of <tensorflow.python.eager.backprop.GradientTape object at 0x7f529c4702e8>>
Traceback (most recent call last):
File "~/.local/lib/python3.6/site-packages/tensorflow/python/eager/backprop.py", line 765, in __del__
AttributeError: 'NoneType' object has no attribute 'context'

Что мне здесь не хватает?

Редактировать: у меня получилось работать с графиком / сессией, поэтому кажется, что есть проблема с нетерпеливым выполнением ...

Примечание: у меня версия tenorflow 1.12.0 и версия tenorflow_probability 0.5.0

.

1 Ответ

0 голосов
/ 26 ноября 2018

Если вы используете активный режим, вам нужно будет пересчитать все из переменной вперед.Лучше всего захватить эту логику в функции;

import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions

tf.enable_eager_execution()

shift = tf.Variable(1., dtype=tf.float32)
def f():
  myBij = tfp.bijectors.Affine(shift=shift)

  # Normal distribution centered in zero, then shifted to 1 using the bijection
  myDistr = tfd.TransformedDistribution(
            distribution=tfd.Normal(loc=0., scale=1.),
            bijector=myBij,
            name="test")

  # 2 samples of a normal centered at 1:
  y = myDistr.sample(2)
  # 2 samples of a normal centered at 0, obtained using inverse
  # transform of myBij:
  x = myBij.inverse(y)
  return x, y
x, y = f()
shift.assign(2.)
gx, _ = f()

Что касается градиентов, вам нужно будет обернуть вызовы в f() в GradientTape

...