¿Cuál es la diferencia entre np.mean y tf.reduce_mean?

90

En el tutorial para principiantes de MNIST , está la declaración

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

tf.castbásicamente cambia el tipo de tensor del objeto, pero ¿cuál es la diferencia entre tf.reduce_meany np.mean?

Aquí está el documento tf.reduce_mean:

reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)

input_tensor: El tensor a reducir. Debería tener tipo numérico.

reduction_indices: Las dimensiones a reducir. Si None(el predeterminado), reduce todas las dimensiones.

# 'x' is [[1., 1. ]]
#         [2., 2.]]
tf.reduce_mean(x) ==> 1.5
tf.reduce_mean(x, 0) ==> [1.5, 1.5]
tf.reduce_mean(x, 1) ==> [1.,  2.]

Para un vector 1D, parece np.mean == tf.reduce_mean, pero no entiendo qué está sucediendo en tf.reduce_mean(x, 1) ==> [1., 2.]. tf.reduce_mean(x, 0) ==> [1.5, 1.5]tiene sentido, ya que significa [1, 2]y [1, 2]es [1.5, 1.5], pero ¿qué está pasando tf.reduce_mean(x, 1)?

O.rka
fuente
producen resultados diferentes en valores enteros debido a la división en python
Salvador Dali
Una diferencia importante para los nuevos en tensorflow: tf.reduce_meanes multiproceso, generalmente se calcula en su GPU, mientras que np.meanse calcula en una sola CPU. Además, tfestá diseñado para procesar un lote de datos, mientras que npactúa sobre una sola instancia de datos.
drevicko

Respuestas:

110

La funcionalidad de numpy.meany tensorflow.reduce_meanes la misma. Ellos hacen la misma cosa. En la documentación, para numpy y tensorflow , puede ver eso. Veamos un ejemplo,

c = np.array([[3.,4], [5.,6], [6.,7]])
print(np.mean(c,1))

Mean = tf.reduce_mean(c,1)
with tf.Session() as sess:
    result = sess.run(Mean)
    print(result)

Salida

[ 3.5  5.5  6.5]
[ 3.5  5.5  6.5]

Aquí puede ver que cuando axis(numpy) o reduction_indices(tensorflow) es 1, calcula la media en (3,4) y (5,6) y (6,7), por lo que 1define en qué eje se calcula la media. Cuando es 0, la media se calcula entre (3,5,6) y (4,6,7), y así sucesivamente. Espero que captes la idea.

Ahora bien, ¿cuáles son las diferencias entre ellos?

Puede calcular la operación numpy en cualquier lugar de Python. Pero para hacer una operación de tensorflow, debe hacerse dentro de un tensorflow Session. Puedes leer más sobre esto aquí . Entonces, cuando necesite realizar cualquier cálculo para su gráfico de flujo tensorial (o estructura si lo desea), debe hacerlo dentro de un flujo tensorial Session.

Veamos otro ejemplo.

npMean = np.mean(c)
print(npMean+1)

tfMean = tf.reduce_mean(c)
Add = tfMean + 1
with tf.Session() as sess:
    result = sess.run(Add)
    print(result)

Podríamos aumentar la media 1en numpycomo lo haría naturalmente, pero para hacerlo en tensorflow, debe realizar eso Session, sin usar, Sessionno puede hacer eso. En otras palabras, cuando estás computando tfMean = tf.reduce_mean(c), tensorflow no lo computa entonces. Solo calcula eso en a Session. Pero numpy calcula eso instantáneamente, cuando escribes np.mean().

Espero que tenga sentido.

Shubhashis
fuente
21
Pero, ¿qué reducir la parte quiere decir aquí?
rsht
20
@Roman es un término de programación funcional. puede leer sobre esto aquí: python-course.eu/lambda.php
Daniyar
1
@rsht REDUCE = reducir los números sumándolos hasta 1 valor. MEAN = promediando esa suma.
Meghna Natraj
1
@rsht Imagina que tienes N elementos y quieres calcular el valor medio (M) de esos N números. Una forma de ver este problema es que tenemos un vector de tamaño (1, N) y sobre el eje = 0, reducimos los elementos (aquí tenemos N elementos). La reducción (o agregación) viene con una funcionalidad y, en nuestro ejemplo, la función es la función media.
alift
22

La clave aquí es la palabra reduce, un concepto de la programación funcional, que hace posible que reduce_mean en TensorFlow mantenga un promedio móvil de los resultados de los cálculos de un lote de entradas.

Si no está familiarizado con la programación funcional, esto puede parecer misterioso. Así que primero veamos qué hace reduce. Si le dieron una lista como [1, 2, 5, 4] y le dijeron que calcule la media, es fácil - simplemente pase la matriz completa a np.mean y obtendrá la media. Sin embargo, ¿qué pasaría si tuvieras que calcular la media de un flujo de números? En ese caso, primero tendría que ensamblar la matriz leyendo de la secuencia y luego llamar a np.mean en la matriz resultante; tendría que escribir más código.

Una alternativa es utilizar el paradigma de reducción. A modo de ejemplo, ver cómo podemos utilizar reducir en Python para calcular la suma de los números: reduce(lambda x,y: x+y, [1,2,5,4]).

Funciona así:

  1. Paso 1: Lea 2 dígitos de la lista: 1,2. Evalúe lambda 1,2. reduce almacena el resultado 3. Nota: este es el único paso en el que se leen 2 dígitos de la lista
  2. Paso 2: Lea el siguiente dígito de la lista - 5. Evalúe lambda 5, 3 (siendo 3 el resultado del paso 1, que reduce almacenado). reducir almacena el resultado 8.
  3. Paso 3: Lea el siguiente dígito de la lista - 4. Evalúe lambda 8,4 (siendo 8 el resultado del paso 2, que reduce almacenado). reducir almacena el resultado 12
  4. Paso 4: Lea el siguiente dígito de la lista; no hay ninguno, así que devuelva el resultado almacenado de 12.

Leer más aquí Programación funcional en Python

Para ver cómo se aplica esto a TensorFlow, observe el siguiente bloque de código, que define un gráfico simple, que toma un flotante y calcula la media. Sin embargo, la entrada al gráfico no es un solo flotante, sino una matriz de flotantes. Reduce_mean calcula el valor medio de todos esos flotantes.

import tensorflow as tf


inp = tf.placeholder(tf.float32)
mean = tf.reduce_mean(inp)

x = [1,2,3,4,5]

with tf.Session() as sess:
    print(mean.eval(feed_dict={inp : x}))

Este patrón es útil cuando se calculan valores sobre lotes de imágenes. Mire The Deep MNIST Example donde verá un código como:

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
Nikhil George
fuente
3

La nueva documentación indica que tf.reduce_mean()produce los mismos resultados que np.mean:

Equivalente a np.mean

También tiene absolutamente los mismos parámetros que np.mean . Pero aquí hay una diferencia importante: producen los mismos resultados solo en valores flotantes :

import tensorflow as tf
import numpy as np
from random import randint

num_dims = 10
rand_dim = randint(0, num_dims - 1)
c = np.random.randint(50, size=tuple([5] * num_dims)).astype(float)

with tf.Session() as sess:
    r1 = sess.run(tf.reduce_mean(c, rand_dim))
    r2 = np.mean(c, rand_dim)
    is_equal = np.array_equal(r1, r2)
    print is_equal
    if not is_equal:
        print r1
        print r2

Si elimina la conversión de tipo, verá resultados diferentes


En adicional a esto, muchas otras tf.reduce_funciones tales como reduce_all, reduce_any, reduce_min, reduce_max, reduce_prodproducen los mismos valores que allí análogos numpy. Claramente, debido a que son operaciones, solo se pueden ejecutar desde dentro de la sesión.

Salvador Dalí
fuente
Podría ser útil si explicara cuál es la diferencia, además del ejemplo. Al ejecutar su ejemplo, tengo la impresión de que tf.reduce_meangarantiza que la salida dtypecoincida con la entrada dtype. La salida de np.mean()es siempre flotante. ¿Es eso correcto?
craq
-1

1generalmente se refiere a filas y 2generalmente se refiere a columnas. Reducir el índice "sobre" 1significa reducir por filas.

[1., 2.]es justo [ <row 1 mean> , <row 2 mean> ].

Esta convención de numeración de índices es típica del software de estadísticas, especialmente R.

Shadowtalker
fuente
1
Creo que 0 se refiere a la columna, no a 2
hfz