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


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.


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

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.


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.


1
Acredito que 0 se refere à coluna, não 2
— hfz
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.