TensorFlow: Max de un tensor a lo largo de un eje

Mi pregunta está en dos partes conectadas:

  1. ¿Cómo calculo el máximo a lo largo de un determinado eje de un tensor? Por ejemplo, si tengo

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

    Quiero algo como

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

    Sé que hay un tf.argmax y un tf.maximum , pero ninguno da el valor máximo a lo largo de un eje de un solo tensor. Por ahora tengo una solución:

     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])) 

    Pero se ve menos que óptimo. ¿Hay una mejor manera de hacer esto?

  2. Dados los índices de un argmax de un tensor, ¿cómo indizo en otro tensor usando esos índices? Usando el ejemplo de x anterior, ¿cómo hago algo como lo siguiente:

     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] 

    Sé que el corte en rodajas, como la última línea, aún no existe en TensorFlow ( # 206 ).

    Mi pregunta es: ¿cuál es la mejor solución para mi caso específico (tal vez usando otros métodos como recostackr, seleccionar, etc.)?

    Información adicional: ¡Sé que x e y serán tensores bidimensionales solamente!

El operador tf.reduce_max() proporciona exactamente esta funcionalidad. Por defecto, calcula el máximo global del tensor dado, pero puede especificar una lista de reduction_indices de reduction_indices , que tiene el mismo significado que axis en NumPy. Para completar tu ejemplo:

 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 calcula el argmax usando tf.argmax() , puede obtener los valores de un tensor diferente y al aplanar y usando tf.reshape() , convirtiendo los índices de argmax en índices de vectores de la siguiente manera, y usando tf.gather() Para extraer los valores apropiados:

 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. # NB 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)" 

A partir de TensorFlow 1.10.0dev20180626 , tf.reduce_max acepta argumentos de palabras clave de axis y keepdims que ofrecen la funcionalidad similar de 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) 

Para tener un tensor resultante de la misma dimensión que el tensor de entrada, use keepdims=True

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

Si el argumento del axis no se especifica explícitamente, se devuelve el elemento de nivel máximo del tensor (es decir, se reducen todos los ejes).

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