9
votes

Définir les plus gros éléments d'un tenseur à zéro dans tensorflow

Je veux trouver k les plus gros éléments de chaque ligne de H et définir la valeur zéro sur ces éléments maximum.

Je pourrais pouvoir sélectionner les index de Top la plus utile de chaque ligne à l'aide de la fonction top_k comme: xxx

mais je ne pouvais pas utiliser les index retournés par top_k pour mettre à jour le tenseur.

Comment puis-je faire ça? Merci d'avance ...


0 commentaires

3 Réponses :


13
votes

Ceci est un peu délicat, peut-être qu'il y a une meilleure solution. tf.scatter_update () ne fonctionne pas ici car il ne peut modifier que des parties de tenseur le long de la première dimension (pas un élément de première ligne et une deuxième colonne par exemple).

Vous devez obtenir les valeurs et indices à partir de tf.nn.top_k () pour créer un tenseur rare et soustrayez-le à la Tensor initial x : xxx


5 commentaires

Mon mauvais, je n'ai pas assez lu assez la question. Je vais mettre à jour ma réponse dans une minute.


Merci Oliver, j'ai eu l'idée. Mais quand je l'ai essayé pour K> 1, Sparse_To_Dense n'a pas pu générer le tenseur. Je pense que je dois jouer avec Tensorflow pour pouvoir le comprendre. Le style de codage numpy / tensorflow est difficile pour moi, car j'ai une mentalité Java :-)


Désolé pour la réponse tardive. Merci cela a fonctionné. Je devais définir Validate_indices à False pour désactiver la vérification des commandes d'indice.


Pour les tailles inconnues, je devais changer indices.get_shape () [0] à tf.shape (indices) [0] .


Syntaxe de TF.CONCAT a changé. Donc, dans le code des arguments de réponse doit être retourné ou transmis par nom: FULL_INDICES = TF.CONCAT (AXIS = 2, Valeurs = [TF.EXPAND_DIMS (my_Range_Repeated, 2), tf.expand_dims (indices, 2) ])



3
votes

Je faisais face au problème opposé et je voulais une opération qui appuyait des gradients. top_k ne prend pas en charge la propagation de gradient et donc un bon moyen sera de mettre en œuvre la fonction en C ++.

top_k Code C ++ est trouvé ICI .

Le noyau de votre opération ressemblera à ceci: xxx

Ma mise en œuvre pour un problème connexe est ici .


0 commentaires

1
votes

avec disponibilité récente de STERPTER_ND_UPDATE CODE> Fonction dans tensorflow, voici une version modifiée de la réponse de Oliver .

k = 2
val_to_replace_with = -333
x = tf.Variable([[6., 2., 0.], [0., 4., 5.]])  # of type tf.float32


values, indices = tf.nn.top_k(x, k, sorted=False)  # indices will be [[0, 1], [1, 2]], values will be [[6., 2.], [4., 5.]]
# We need to create full indices like [[0, 0], [0, 1], [1, 2], [1, 1]]
my_range = tf.expand_dims(tf.range(0, tf.shape(indices)[0]), 1)  # will be [[0], [1]]
my_range_repeated = tf.tile(my_range, [1, k])  # will be [[0, 0], [1, 1]]
# change shapes to [N, k, 1] and [N, k, 1], to concatenate into [N, k, 2]
full_indices = tf.concat([tf.expand_dims(my_range_repeated, -1), tf.expand_dims(indices, -1)], axis=2)
full_indices = tf.reshape(full_indices, [-1, 2])


# only significant modification -----------------------------------------------------------------
updates = val_to_replace_with + tf.zeros([tf.size(indices)], dtype=tf.float32)
c = tf.scatter_nd_update(x, full_indices, updates)
# only significant modification -----------------------------------------------------------------


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(c))


0 commentaires