web-dev-qa-db-fra.com

TensorFlow: Max d'un tenseur le long d'un axe

Ma question est en deux parties liées:

  1. Comment calculer le max le long d'un certain axe d'un tenseur? Par exemple, si j'ai

    x = tf.constant([[1,220,55],[4,3,-1]])
    

    Je veux quelque chose comme

    x_max = tf.max(x, axis=1)
    print sess.run(x_max)
    
    output: [220,4]
    

    Je sais qu'il y a un tf.argmax et un tf.maximum, mais ne donne pas non plus la valeur maximale le long d'un axe d'un seul tenseur. Pour l'instant j'ai une solution de contournement:

    x_max = tf.slice(x, begin=[0,0], size=[-1,1])
    for a in range(1,2):
        x_max = tf.maximum(x_max , tf.slice(x, begin=[0,a], size=[-1,1]))
    

    Mais cela semble moins qu'optimal. Y a-t-il une meilleure manière de faire cela?

  2. Étant donné les indices d'un argmax d'un tenseur, comment puis-je indexer dans un autre tenseur à l'aide de ces indices? En utilisant l'exemple de x ci-dessus, comment puis-je faire quelque chose comme ce qui suit:

    ind_max = tf.argmax(x, dimension=1)    #output is [1,0]
    y = tf.constant([[1,2,3], [6,5,4])
    y_ = y[:, ind_max]                     #y_ should be [2,6]
    

    Je sais que le découpage, comme la dernière ligne, n’existe pas encore dans TensorFlow ( # 206 ).

    Ma question est: quelle est la meilleure solution de contournement pour mon cas spécifique (peut-être en utilisant d'autres méthodes telles que rassembler, sélectionner, etc.)?

    Informations complémentaires: Je sais que x et y ne seront que des tenseurs bidimensionnels!

28
aphdstudent

L'opérateur tf.reduce_max() fournit exactement cette fonctionnalité. Par défaut, il calcule le maximum global du tenseur donné, mais vous pouvez spécifier une liste de reduction_indices, Qui a la même signification que axis dans NumPy. Pour compléter votre exemple:

x = tf.constant([[1, 220, 55], [4, 3, -1]])
x_max = tf.reduce_max(x, reduction_indices=[1])
print sess.run(x_max)  # ==> "array([220,   4], dtype=int32)"

Si vous calculez l'argmax en utilisant tf.argmax() , vous pouvez obtenir les valeurs d'un tenseur différent y en aplatissant y en utilisant tf.reshape() , convertissant les indices argmax en indices vectoriels comme suit, et en utilisant tf.gather() pour extraire les valeurs appropriées:

ind_max = tf.argmax(x, dimension=1)
y = tf.constant([[1, 2, 3], [6, 5, 4]])

flat_y = tf.reshape(y, [-1])  # Reshape to a vector.

# N.B. Handles 2-D case only.
flat_ind_max = ind_max + tf.cast(tf.range(tf.shape(y)[0]) * tf.shape(y)[1], tf.int64)

y_ = tf.gather(flat_y, flat_ind_max)

print sess.run(y_) # ==> "array([2, 6], dtype=int32)"
58
mrry

À partir de TensorFlow 1.10.0 - dev20180626, tf.reduce_max accepte axis et keepdims arguments de mot clé offrant les mêmes fonctionnalités que numpy.max.

In [55]: x = tf.constant([[1,220,55],[4,3,-1]])

In [56]: tf.reduce_max(x, axis=1).eval() 
Out[56]: array([220,   4], dtype=int32)

Pour obtenir un tenseur résultant de la même dimension que le tenseur d'entrée, utilisez keepdims=True

In [57]: tf.reduce_max(x, axis=1, keepdims=True).eval()Out[57]: 
array([[220],
       [  4]], dtype=int32)

Si l'argument axis n'est pas spécifié explicitement, l'élément maximal du niveau de tensor est renvoyé (tous les axes sont réduits).

In [58]: tf.reduce_max(x).eval()
Out[58]: 220
1
kmario23