Qual é a diferença entre np.mean e tf.reduce_mean?

90

No tutorial do iniciante MNIST , há a instrução

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

tf.castbasicamente muda o tipo de tensor do objeto, mas qual é a diferença entre tf.reduce_meane np.mean?

Aqui está o documento sobre tf.reduce_mean:

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

input_tensor: O tensor a ser reduzido. Deve ter tipo numérico.

reduction_indices: As dimensões a reduzir. Se None(o padrão), reduz todas as dimensões.

# '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 um vetor 1D, parece np.mean == tf.reduce_mean, mas não entendo o que está acontecendo em tf.reduce_mean(x, 1) ==> [1., 2.]. tf.reduce_mean(x, 0) ==> [1.5, 1.5]meio que faz sentido, uma vez que significa [1, 2]e [1, 2]é [1.5, 1.5], mas o que está acontecendo tf.reduce_mean(x, 1)?

O.rka
fonte
eles produzem resultados diferentes em valores inteiros devido à divisão em python
Salvador Dali
Uma diferença importante para aqueles que são novos no tensorflow: tf.reduce_meané multi-threaded, normalmente calculado em sua GPU, enquanto np.meané calculado em uma única CPU. Além disso, tfé projetado para processar um lote de dados enquanto npatua em uma única instância de dados.
drevicko

Respostas:

110

As funcionalidades de numpy.meane tensorflow.reduce_meansão as mesmas. Eles fazem a mesma coisa. Na documentação, para numpy e tensorflow , você pode ver isso. Vejamos um exemplo,

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)

Resultado

[ 3.5  5.5  6.5]
[ 3.5  5.5  6.5]

Aqui você pode ver que quando axis(numpy) ou reduction_indices(tensorflow) é 1, ele calcula a média em (3,4) e (5,6) e (6,7), então 1define em qual eixo a média é calculada. Quando é 0, a média é calculada em (3,5,6) e (4,6,7), e assim por diante. Espero que você tenha a idéia.

Agora, quais são as diferenças entre eles?

Você pode calcular a operação numpy em qualquer lugar no python. Mas para fazer uma operação de tensorflow, ela deve ser feita dentro de um tensorflow Session. Você pode ler mais sobre isso aqui . Portanto, quando você precisar realizar qualquer cálculo para seu gráfico de tensorflow (ou estrutura, se preferir), deve ser feito dentro de um tensorflow Session.

Vejamos outro exemplo.

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)

Poderíamos aumentar a média por 1in numpycomo você faria naturalmente, mas para fazê-lo em tensorflow, você precisa executar em Session, sem usar Sessionvocê não pode fazer isso. Em outras palavras, quando você está computando tfMean = tf.reduce_mean(c), o tensorflow não o computa. Ele apenas calcula isso em a Session. Mas o numpy calcula isso instantaneamente, quando você escreve np.mean().

Eu espero que faça sentido.

Shubhashis
fonte
21
mas o que reduzir parte significa aqui?
rsht
20
@Roman é um termo de programação funcional. você pode ler sobre isso aqui: python-course.eu/lambda.php
Daniyar
1
@rsht REDUCE = reduzindo os números somando-os até 1 valor. MEAN = média dessa soma.
Meghna Natraj
1
@rsht Imagine que você tem N elementos e deseja calcular o valor médio (M) desses N números. Uma maneira de ver este problema é que temos um vetor de tamanho (1, N) e sobre o eixo = 0, reduzimos os elementos (aqui temos N elementos). A redução (ou agregação) vem com uma funcionalidade e, em nosso exemplo, a função é a função média.
alift
22

A chave aqui é a palavra reduzir, um conceito da programação funcional, que torna possível para a redução_mean no TensorFlow manter uma média dos resultados dos cálculos de um lote de entradas.

Se você não está familiarizado com a programação funcional, isso pode parecer misterioso. Então, primeiro vamos ver o que reduz. Se você recebeu uma lista como [1,2,5,4] e foi instruído a calcular a média, isso é fácil - apenas passe o array inteiro para np.mean e você obterá a média. No entanto, e se você tivesse que calcular a média de um fluxo de números? Nesse caso, você teria que primeiro montar o array lendo o stream e então chamar np.mean no array resultante - você teria que escrever mais algum código.

Uma alternativa é usar o paradigma de redução. Como exemplo, veja como podemos usar reduzir em python para calcular a soma dos números: reduce(lambda x,y: x+y, [1,2,5,4]).

Funciona assim:

  1. Etapa 1: Leia 2 dígitos da lista - 1,2. Avalie lambda 1,2. reduzir armazena o resultado 3. Nota - esta é a única etapa onde 2 dígitos são lidos na lista
  2. Passo 2: Leia o próximo dígito da lista - 5. Avalie lambda 5, 3 (sendo 3 o resultado do passo 1, que reduz o armazenado). reduzir armazena o resultado 8.
  3. Passo 3: Leia o próximo dígito da lista - 4. Avalie lambda 8,4 (sendo 8 o resultado do passo 2, que reduz o armazenado). reduzir lojas o resultado 12
  4. Etapa 4: Leia o próximo dígito da lista - não há nenhum, então retorne o resultado armazenado de 12.

Leia mais aqui Programação Funcional em Python

Para ver como isso se aplica ao TensorFlow, observe o seguinte bloco de código, que define um gráfico simples, que pega um ponto flutuante e calcula a média. A entrada para o gráfico, entretanto, não é um único flutuante, mas uma matriz de flutuantes. Reduza_mean calcula o valor médio de todos esses flutuadores.

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

Esse padrão é útil ao calcular valores em lotes de imagens. Veja o exemplo de The Deep MNIST, onde você vê um 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
fonte
3

A nova documentação afirma que tf.reduce_mean()produz os mesmos resultados que np.mean:

Equivalente a np.mean

Ele também tem absolutamente os mesmos parâmetros que np.mean . Mas aqui está uma diferença importante: eles produzem os mesmos resultados apenas em valores flutuantes :

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

Se você remover a conversão de tipo, verá resultados diferentes


Em adicional para isso, muitas outras tf.reduce_funções, tais como reduce_all, reduce_any, reduce_min, reduce_max, reduce_prodproduzir os mesmos valores que lá análogos numpy. Obviamente, por serem operações, elas podem ser executadas apenas de dentro da sessão.

Salvador Dalí
fonte
pode ser útil se você explicar qual é a diferença, além do exemplo. Ao executar seu exemplo, tenho a impressão de que tf.reduce_meangarante que a saída dtypecorresponda à entrada dtype. A saída de np.mean()é sempre um float. Isso está correto?
craq
-1

1geralmente se refere a linhas e 2geralmente se refere a colunas. Reduzir o índice "acima" 1significa reduzir o número de linhas.

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

Esta convenção de numeração de índice é típica em software de estatísticas, especialmente R.

Shadowtalker
fonte
1
Acredito que 0 se refere à coluna, não 2
hfz