Quelle est la différence entre np.mean et tf.reduce_mean?


90

Dans le didacticiel MNIST pour débutants , il y a la déclaration

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

tf.castchange fondamentalement le type de tenseur de l'objet, mais quelle est la différence entre tf.reduce_meanet np.mean?

Voici la doc sur tf.reduce_mean:

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

input_tensor: Le tenseur à réduire. Doit avoir un type numérique.

reduction_indices: Les dimensions à réduire. Si None(le défaut), réduit toutes les dimensions.

# '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.]

Pour un vecteur 1D, cela ressemble à np.mean == tf.reduce_mean, mais je ne comprends pas ce qui se passe tf.reduce_mean(x, 1) ==> [1., 2.]. tf.reduce_mean(x, 0) ==> [1.5, 1.5]a du sens, puisque signifie [1, 2]et [1, 2]est [1.5, 1.5], mais que se passe- tf.reduce_mean(x, 1)t-il?


ils produisent des résultats différents sur les valeurs entières en raison de la division en python
Salvador Dali

Une différence importante pour ceux qui découvrent tensorflow: tf.reduce_meanest multi-thread, généralement calculé sur votre GPU, alors qu'il np.meanest calculé sur un seul processeur. En outre, tfest conçu pour traiter un lot de données alors qu'il npagit sur une seule instance de données.
drevicko

Réponses:


110

Les fonctionnalités de numpy.meanet tensorflow.reduce_meansont les mêmes. Ils font la même chose. Dans la documentation, pour numpy et tensorflow , vous pouvez le voir. Regardons un exemple,

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)

Production

[ 3.5  5.5  6.5]
[ 3.5  5.5  6.5]

Ici, vous pouvez voir que lorsque axis(numpy) ou reduction_indices(tensorflow) vaut 1, il calcule la moyenne à travers (3,4) et (5,6) et (6,7), donc 1définit sur quel axe la moyenne est calculée. Lorsqu'il vaut 0, la moyenne est calculée entre (3,5,6) et (4,6,7), et ainsi de suite. J'espère que vous avez l'idée.

Maintenant, quelles sont les différences entre eux?

Vous pouvez calculer l'opération numpy n'importe où sur python. Mais pour effectuer une opération tensorflow, elle doit être effectuée à l'intérieur d'un tensorflow Session. Vous pouvez en savoir plus ici . Ainsi, lorsque vous devez effectuer un calcul pour votre graphe tensorflow (ou structure si vous voulez), il doit être fait à l'intérieur d'un tensorflow Session.

Regardons un autre exemple.

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)

Nous pourrions augmenter moyenne par 1en numpycomme vous le feriez naturellement, mais pour le faire en tensorflow, vous devez effectuer que Session, sans utiliser Sessionvous ne pouvez pas faire cela. En d'autres termes, lorsque vous tfMean = tf.reduce_mean(c)calculez, tensorflow ne le calcule pas alors. Il ne calcule que dans un fichier Session. Mais numpy calcule cela instantanément, lorsque vous écrivez np.mean().

J'espère que ça a du sens.


21
mais que signifie ici réduire la partie ?
rsht du

20
@Roman c'est un terme de la programmation fonctionnelle. vous pouvez en savoir plus ici: python-course.eu/lambda.php
Daniyar

1
@rsht REDUCE = réduire les nombres en les additionnant jusqu'à 1 valeur. MOYEN = moyenne de cette somme.
Meghna Natraj

1
@rsht Imaginez que vous avez N éléments et que vous voulez calculer la valeur moyenne (M) de ces N nombres. Une façon de voir ce problème est que nous avons un vecteur de taille (1, N) et sur l'axe = 0, nous réduisons les éléments (ici nous avons N éléments). La réduction (ou agrégation) vient avec une fonctionnalité, et dans notre exemple, la fonction est la fonction moyenne.
alift

22

La clé ici est le mot réduire, un concept issu de la programmation fonctionnelle, qui permet à Reduce_mean dans TensorFlow de conserver une moyenne courante des résultats de calculs à partir d'un lot d'entrées.

Si vous n'êtes pas familier avec la programmation fonctionnelle, cela peut paraître mystérieux. Voyons donc d'abord ce que fait réduire. Si on vous a donné une liste comme [1,2,5,4] et qu'on vous a dit de calculer la moyenne, c'est facile - passez simplement le tableau entier à np.mean et vous obtenez la moyenne. Mais que se passerait-il si vous deviez calculer la moyenne d'un flux de nombres? Dans ce cas, vous devrez d'abord assembler le tableau en lisant le flux, puis appeler np.mean sur le tableau résultant - vous devrez écrire un peu plus de code.

Une alternative consiste à utiliser le paradigme de réduction. À titre d'exemple, regardez comment nous pouvons utiliser réduire en python pour calculer la somme des nombres: reduce(lambda x,y: x+y, [1,2,5,4]).

Cela fonctionne comme ceci:

  1. Étape 1: Lisez 2 chiffres de la liste - 1,2. Évaluez lambda 1,2. Réduire stocke le résultat 3. Remarque - c'est la seule étape où 2 chiffres sont lus dans la liste
  2. Étape 2: Lisez le chiffre suivant de la liste - 5. Évaluez lambda 5, 3 (3 étant le résultat de l'étape 1, qui réduit stocké). réduire stocke le résultat 8.
  3. Étape 3: Lisez le chiffre suivant de la liste - 4. Évaluez lambda 8,4 (8 étant le résultat de l'étape 2, qui réduit stocké). réduire stocke le résultat 12
  4. Étape 4: Lisez le chiffre suivant de la liste - il n'y en a pas, renvoyez donc le résultat stocké de 12.

En savoir plus ici Programmation fonctionnelle en Python

Pour voir comment cela s'applique à TensorFlow, regardez le bloc de code suivant, qui définit un graphique simple, qui prend un flottant et calcule la moyenne. L'entrée du graphique n'est cependant pas un flottant unique mais un tableau de flottants. Le paramètre reduction_mean calcule la valeur moyenne sur tous ces flottants.

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

Ce modèle est pratique lors du calcul de valeurs sur des lots d'images. Regardez l' exemple Deep MNIST où vous voyez du code comme:

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

3

La nouvelle documentation indique que tf.reduce_mean()produit les mêmes résultats que np.mean:

Équivalent à np.mean

Il a également absolument les mêmes paramètres que np.mean . Mais voici une différence importante: ils ne produisent les mêmes résultats que sur des valeurs flottantes :

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 vous supprimez la conversion de type, vous verrez des résultats différents


En plus de cela, beaucoup d' autres tf.reduce_fonctions telles que reduce_all, reduce_any, reduce_min, reduce_max, reduce_prodproduisent les mêmes valeurs que là analogues numpy. De toute évidence, comme ce sont des opérations, elles ne peuvent être exécutées qu'à l'intérieur de la session.


il pourrait être utile d'expliquer quelle est la différence, en plus de l'exemple. En exécutant votre exemple, j'ai l'impression tf.reduce_meanque la sortie dtypecorrespond à l'entrée dtype. La sortie de np.mean()est toujours un float. Est-ce exact?
craq

-1

1fait généralement référence à des lignes et 2fait généralement référence à des colonnes. Réduction de l'index "sur"1 signifie réduire par ligne.

[1., 2.]est juste [ <row 1 mean> , <row 2 mean> ].

Cette convention de numérotation d'index est typique des logiciels de statistiques, en particulier R.


1
Je crois que 0 fait référence à la colonne, pas à 2
hfz
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.