Dans numpy, avec deux tableaux de même forme, x
et y
, il est possible de créer des tranches comme celle-ci y[x > 1]
. Comment obtenez-vous le même résultat en tensorflow? y[tf.greater(x, 1)]
ne fonctionne pas et tf.slice
ne supporte rien de ce genre non plus. Existe-t-il un moyen d'indexer avec un tenseur booléen actuellement ou est-ce actuellement non pris en charge?
Essayer:
ones = tf.ones_like(x) # create a tensor all ones
mask = tf.greater(x, ones) # boolean tensor, mask[i] = True iff x[i] > 1
slice_y_greater_than_one = tf.boolean_mask(y, mask)
Voir tf.boolean_mask
EDIT: une autre (meilleure?) façon de le faire:
import tensorflow as tf
x = tf.constant([1, 2, 0, 4])
y = tf.Variable([1, 2, 0, 4])
mask = x > 1
slice_y_greater_than_one = tf.boolean_mask(y, mask)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print (sess.run(slice_y_greater_than_one)) # [2 4]
Je ne dirais pas que ce n'est pas complètement implémenté. Comment ça pour un double négatif?
Tensorflow prend en charge de nombreux découpages en tranches et en dés, bien que la syntaxe soit un peu moins jolie. Par exemple, si vous voulez créer un nouveau tableau qui vaut y
quand x>1
mais égal à 0 sinon, vous pouvez certainement le faire. Check out opérateurs de comparaison p. Ex.
masked = tf.greater(x,1)
zeros = tf.zeros_like(x)
new_tensor = tf.where(masked, y, zeros)
Si, par contre, vous voulez créer un nouveau tableau qui ne contient que les types où x>1
vous pouvez le faire en combinant where
avec la fonction gather
. Les détails pour gather
peuvent être trouvés à
https://www.tensorflow.org/versions/master/api_docs/python/array_ops/slicing_and_joining
PS. Bien sûr, x>1
n'est pas différentiable en ce qui concerne x
... tf peut être formidable, mais cela ne fonctionne pas comme par magie :).
Ceci n’est pas encore implémenté, voici le numéro de GitHub qui suit l’avancement - https://github.com/tensorflow/tensorflow/issues/206
tf.boolean_mask
fait le travail, mais sur certaines plates-formes telles que Raspberry Pi ou OSX, l'opération n'est pas prise en charge dans les distributions de roulettes Tensorflow (Cochez this tf.boolean_mask non pris en charge sur OSX . Une alternative consiste donc à utiliser where
et gather
comme @ Jackson Loper a suggéré, par exemple:
x = tf.Variable([1, 2, 0, 4])
ix = tf.where(x > 1)
y = tf.gather(x, ix)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(y))
Je cherchais une capacité similaire pour réduire un tenseur de TensorFlow.js selon un critère défini, mais TensorFlow.js ne dispose pas de la fonction boolean_mask. Après avoir tiré beaucoup de cheveux et grincé des dents, voici ce qui est résumé, ce qui résume essentiellement le nombre total de vrais critères, puis il suffit de sélectionner les valeurs topk pour créer le tenseur.
const a = tf.tensor1d([1, 2, 0, 4]);
const b = a.greater(1).sum().get();
const {values, indices} = tf.topk(a, b);
values.print(); # 4,2
indices.print(); # 3,1
Et pour créer un tenseur de sous-ensemble de valeurs inférieur ou égal à 1, il suffit d'utiliser tf.neg sur le tenseur puisqu'il n'y a pas de fonction de bottomk, puis après avoir obtenu le tenseur via topk, en appliquant à nouveau tf.neg pour restaurer les valeurs d'origine.