web-dev-qa-db-fra.com

Comment passer un scalaire via un dictionnaire de flux TensorFlow

Mon modèle TensorFlow utilise tf.random_uniform pour initialiser une variable. J'aimerais spécifier la plage lorsque je commence la formation. J'ai donc créé un espace réservé pour la valeur d'initialisation.

init = tf.placeholder(tf.float32, name="init")
v = tf.Variable(tf.random_uniform((100, 300), -init, init), dtype=tf.float32)
initialize = tf.initialize_all_variables()

J'initialise les variables au début de la formation, comme ça.

session.run(initialize, feed_dict={init: 0.5})

Cela me donne l'erreur suivante:

ValueError: initial_value must have a shape specified: Tensor("Embedding/random_uniform:0", dtype=float32)

Je n'arrive pas à comprendre le paramètre shape correct à transmettre à tf.placeholder. Je pense que pour un scalaire, je devrais faire init = tf.placeholder(tf.float32, shape=0, name="init") mais ceci donne l'erreur suivante:

ValueError: Incompatible shapes for broadcasting: (100, 300) and (0,)

Si je remplace init par la valeur littérale 0.5 dans l'appel à tf.random_uniform, cela fonctionne.

Comment passer cette valeur initiale scalaire via le dictionnaire de flux?

13
W.P. McNeill

TL; DR: Définissez init avec une forme scalaire comme suit:

init = tf.placeholder(tf.float32, shape=(), name="init")

Cela ressemble à un détail d'implémentation malheureux de tf.random_uniform() : il utilise actuellement tf.add() et tf.multiply() pour redimensionner la valeur aléatoire de [-1, +1] à [minval, maxval], mais si la forme de minval ou maxval est inconnue , tf.add() et tf.multiply() ne peuvent pas en déduire les formes appropriées, car il peut y avoir une diffusion impliquée.

En définissant init avec une forme connue (où un scalaire est () ou [], pas 0), TensorFlow peut tirer les conclusions appropriées sur la forme du résultat de tf.random_uniform() et votre programme doit fonctionner comme prévu.

28
mrry

Vous n'avez pas besoin d'un paramètre fictif pour passer le scalaire, car tout tenseur, capteur de lumière ou capteur de tension ou le tuple suivant peut être correct. Le doc lit que: 

The optional `feed_dict` argument allows the caller to override
the value of tensors in the graph. Each key in `feed_dict` can be
one of the following types:
* If the key is a `tf.Tensor`, the
  value may be a Python scalar, string, list, or numpy ndarray
  that can be converted to the same `dtype` as that
  tensor. Additionally, if the key is a
  `tf.placeholder`, the shape of
  the value will be checked for compatibility with the placeholder.
* If the key is a
  `tf.SparseTensor`,
  the value should be a
  `tf.SparseTensorValue`.
* If the key is a nested Tuple of `Tensor`s or `SparseTensor`s, the value
  should be a nested Tuple with the same structure that maps to their
  corresponding values as above.

Et dans votre scénario, tout tenseur, comme une constante, une variable ou un espace réservé, peut convenir. 

init = tf.constant(0)
init_1 = tf.Variable(0)
v = tf.Variable(tf.random_uniform((100, 300), -init, init), dtype=tf.float32)
initialize = tf.global_variables_initializer()
sess.run(intialize, feed_dict={init: 0.5})
sess.run(intialize, feed_dict={init_1: 0.5})

Vous pouvez lui transmettre soit float, soit int, car seul le type de données vérifie les paramètres comme indiqué ci-dessus. 

0
lerner