«ValueError: градиенты не указаны для любой переменной», когда scale_diag в MultivariateNormalDiag () является константой - PullRequest
0 голосов
/ 30 мая 2019

Ниже приведен фрагмент кода, который с учетом state генерирует action из распределения, зависящего от состояния (prob_policy).Затем веса графика обновляются в соответствии с потерями, которые в -1 раз превышают вероятность выбора этого действия.В следующем примере как среднее (mu), так и ковариация (sigma) MultivariateNormal обучаемы / изучены.

import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

# make the graph
state = tf.placeholder(tf.float32, (1, 2), name="state")
mu = tf.contrib.layers.fully_connected(
    inputs=state,
    num_outputs=2,
    biases_initializer=tf.ones_initializer)
sigma = tf.contrib.layers.fully_connected(
    inputs=state,
    num_outputs=2,
    biases_initializer=tf.ones_initializer)
sigma = tf.squeeze(sigma)
mu = tf.squeeze(mu)
prob_policy = tfp.distributions.MultivariateNormalDiag(loc=mu, scale_diag=sigma)
action = prob_policy.sample()
picked_action_prob = prob_policy.prob(action)
loss = -tf.log(picked_action_prob)
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(loss)

# run the optimizer
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    state_input = np.expand_dims([0.,0.],0)
    _, action_loss = sess.run([train_op, loss], { state: state_input })
    print(action_loss)

Однако, когда я заменяю эту строку

prob_policy = tfp.distributions.MultivariateNormalDiag(loc=mu, scale_diag=sigma)

следующей строкой (и закомментирую строки, которые генерируют слой сигмы и сжимают его)

prob_policy = tfp.distributions.MultivariateNormalDiag(loc=mu, scale_diag=[1.,1.])

Я получаю следующую ошибку

ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables ["<tf.Variable 'fully_connected/weights:0' shape=(2, 2) dtype=float32_ref>", "<tf.Variable 'fully_connected/biases:0' shape=(2,) dtype=float32_ref>"] and loss Tensor("Neg:0", shape=(), dtype=float32).

Я не понимаю, почему это происходит.Разве он все еще не может принять градиент по отношению к весам в слое mu?Почему создание ковариации константы распределения внезапно делает ее недифференцируемой?

Сведения о системе:

  • Tensorflow 1.13.1
  • Tensorflow Вероятность 0.6.0
  • Python 3.6.8
  • MacOS 10.13.6

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Существует проблема, вызванная некоторым кешированием, которое мы делаем внутри MVNDiag (и других подклассов TransformedDistribution) для обратимости.

Если вы сделаете + 0 (как обходной путь) после вашего .sample (), градиент будет работать.

Также я бы предложил использовать dist.log_prob(..) вместо tf.log(dist.prob(..)). Лучшие цифры.

import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

# make the graph
state = tf.placeholder(tf.float32, (1, 2), name="state")
mu = tf.contrib.layers.fully_connected(
    inputs=state,
    num_outputs=2,
    biases_initializer=tf.ones_initializer)
sigma = tf.contrib.layers.fully_connected(
    inputs=state,
    num_outputs=2,
    biases_initializer=tf.ones_initializer)
sigma = tf.squeeze(sigma)
mu = tf.squeeze(mu)
prob_policy = tfp.distributions.MultivariateNormalDiag(loc=mu, scale_diag=[1.,1.])
action = prob_policy.sample() + 0
loss = -prob_policy.log_prob(action)
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(loss)

# run the optimizer
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    state_input = np.expand_dims([0.,0.],0)
    _, action_loss = sess.run([train_op, loss], { state: state_input })
    print(action_loss)
0 голосов
/ 31 мая 2019

Мне пришлось изменить эту строку

action = prob_policy.sample()

на эту строку

action = tf.stop_gradient(prob_policy.sample())

Если у кого-то есть объяснение того, почему изучение весов ковариации делает весовые коэффициенты дифференцируемымиВ отношении потери, но превращение ковариации в константу не имеет значения, и как изменение этой линии влечет за собой это, я бы с удовольствием объяснил!Спасибо!

...