Jaka jest różnica między np.mean i tf.reduce_mean?

90

W samouczku dla początkujących MNIST znajduje się oświadczenie

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

tf.cast zasadniczo zmienia typ tensora obiektu, ale jaka jest różnica między tf.reduce_mean i np.mean?

Oto dokument dotyczący tf.reduce_mean:

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

input_tensor: Tensor do zmniejszenia. Powinien mieć typ liczbowy.

reduction_indices: Wymiary do zmniejszenia. Jeśli None(defaut), zmniejsza wszystkie wymiary.

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

Wygląda to na wektor 1D np.mean == tf.reduce_mean, ale nie rozumiem, co się dzieje tf.reduce_mean(x, 1) ==> [1., 2.]. tf.reduce_mean(x, 0) ==> [1.5, 1.5]trochę ma sens, skoro średnia [1, 2]i [1, 2]jest [1.5, 1.5], ale o co chodzi tf.reduce_mean(x, 1)?

O.rka
źródło
dają różne wyniki na wartościach całkowitych ze względu na podział w Pythonie
Salvador Dali
Jedna ważna różnica w przypadku nowych użytkowników tensorflow: tf.reduce_meanjest wielowątkowa, zwykle obliczana na GPU, podczas gdy np.meanjest obliczana na pojedynczym procesorze. Ponadto tfjest przeznaczony do przetwarzania partii danych, podczas gdy npdziała na pojedynczej instancji danych.
drevicko

Odpowiedzi:

110

Funkcjonalność numpy.meani tensorflow.reduce_meansą takie same. Robią to samo. Możesz to zobaczyć w dokumentacji dla numpy i tensorflow . Spójrzmy na przykład,

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)

Wynik

[ 3.5  5.5  6.5]
[ 3.5  5.5  6.5]

Tutaj widać, że gdy axis(numpy) lub reduction_indices(tensorflow) wynosi 1, oblicza średnią w poprzek (3,4) i (5,6) i (6,7), więc1 definiuje, na której osi obliczana jest średnia. Gdy wynosi 0, średnia jest obliczana w przedziałach (3,5,6) i (4,6,7) i tak dalej. Mam nadzieję, że wpadłeś na pomysł.

Jakie są między nimi różnice?

Możesz obliczyć operację numpy w dowolnym miejscu w Pythonie. Aby jednak wykonać operację tensorflow, należy ją wykonać wewnątrz tensorflow Session. Więcej na ten temat przeczytasz tutaj . Więc kiedy musisz wykonać jakiekolwiek obliczenia dla swojego wykresu tensorflow (lub struktury, jeśli chcesz), musisz to zrobić wewnątrz tensorflow Session.

Spójrzmy na inny przykład.

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)

Moglibyśmy zwiększyć średni przez 1in numpytak, jak byś to naturalnie zrobił, ale aby zrobić to w tensorflow, musisz to zrobić Session, bez użycia Sessionnie możesz tego zrobić. Innymi słowy, podczas obliczania tfMean = tf.reduce_mean(c)tensorflow go nie oblicza. Oblicza to tylko w pliku Session. Ale numpy oblicza to natychmiast, kiedy piszesznp.mean() .

Mam nadzieję, że to ma sens.

Shubhashis
źródło
21
ale co tutaj oznacza zredukowana część ?
rsht
20
@Roman to termin z programowania funkcyjnego. możesz o tym poczytać tutaj: python-course.eu/lambda.php
Daniyar
1
@rsht REDUCE = zmniejszanie liczb poprzez zsumowanie ich do 1 wartości. ŚREDNIA = uśrednianie tej sumy.
Meghna Natraj
1
@rsht Wyobraź sobie, że masz N elementów i chcesz obliczyć średnią wartość (M) tych N liczb. Sposobem na zobaczenie tego problemu jest to, że mamy wektor o rozmiarze (1, N) i na osi = 0 redukujemy elementy (tutaj mamy N elementów). Redukcja (lub agregacja) wiąże się z funkcjonalnością, aw naszym przykładzie funkcja jest funkcją średnią.
wynieść
23

Kluczem jest tutaj słowo redukuj, pojęcie z programowania funkcjonalnego, które umożliwia mechanizmowi zmniejszania średniego w TensorFlow zachowanie średniej bieżącej wyników obliczeń z partii danych wejściowych.

Jeśli nie jesteś zaznajomiony z programowaniem funkcjonalnym, może to wydawać się tajemnicze. Więc najpierw zobaczmy, co robi redukcja. Jeśli otrzymałeś listę taką jak [1,2,5,4] i powiedziano ci, że masz obliczyć średnią, to jest łatwe - po prostu przekaż całą tablicę do np.mean i otrzymasz średnią. A co by było, gdybyś musiał obliczyć średnią strumienia liczb? W takim przypadku musiałbyś najpierw złożyć tablicę, czytając ze strumienia, a następnie wywołać np.mean na wynikowej tablicy - musiałbyś napisać więcej kodu.

Alternatywą jest użycie paradygmatu redukuj. Jako przykład przyjrzyj się, jak możemy użyć funkcji redukuj w Pythonie do obliczenia sumy liczb: reduce(lambda x,y: x+y, [1,2,5,4]) .

Działa to tak:

  1. Krok 1: Odczytaj 2 cyfry z listy - 1,2. Oszacuj lambda 1,2. redukuje zapisuje wynik 3. Uwaga - jest to jedyny krok, w którym z listy odczytywane są 2 cyfry
  2. Krok 2: Odczytaj kolejną cyfrę z listy - 5. Oszacuj lambda 5, 3 (3 to wynik z kroku 1, który redukuje zapisane). redukuje zapisuje wynik 8.
  3. Krok 3: Odczytaj następną cyfrę z listy - 4. Wyznacz lambda 8,4 (8 jest wynikiem kroku 2, które zmniejszają zapisane). zmniejszyć zapamiętuje wynik 12
  4. Krok 4: Przeczytaj kolejną cyfrę z listy - nie ma, więc zwróć zapisany wynik 12.

Przeczytaj więcej tutaj Programowanie funkcjonalne w Pythonie

Aby zobaczyć, jak to się odnosi do TensorFlow, spójrz na następujący blok kodu, który definiuje prosty wykres, który przyjmuje zmiennoprzecinkowy i oblicza średnią. Jednak dane wejściowe do wykresu nie są pojedynczymi liczbami zmiennoprzecinkowymi, ale tablicą liczb zmiennoprzecinkowych. Redukcja_mean oblicza średnią wartość ze wszystkich tych zmiennych.

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

Ten wzorzec jest przydatny podczas obliczania wartości na partiach obrazów. Spójrz na przykład The Deep MNIST, gdzie widzisz kod taki jak:

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
Nikhil George
źródło
3

Nowa dokumentacja stwierdza, że tf.reduce_mean()daje takie same wyniki jak np.mean:

Odpowiednik np.mean

Ma również absolutnie te same parametry, co np.mean . Ale tutaj jest ważna różnica: dają te same wyniki tylko dla wartości zmiennoprzecinkowych :

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

Jeśli usuniesz konwersję typu, zobaczysz inne wyniki


W dodatkowych do tego, wiele innych tf.reduce_funkcji, takich jak reduce_all, reduce_any, reduce_min, reduce_max, reduce_prodprodukują te same wartości jak tam NumPy analogów. Oczywiście, ponieważ są to operacje, można je wykonać tylko z wnętrza sesji.

Salvador Dali
źródło
może być pomocne, jeśli oprócz przykładu wyjaśnisz różnicę. Po uruchomieniu przykładu mam wrażenie, tf.reduce_meanże dane wyjściowe są dtypezgodne z danymi wejściowymi dtype. Wynik np.mean()jest zawsze liczbą zmiennoprzecinkową. Czy to jest poprawne?
craq
-1

1zwykle odnosi się do wierszy, a 2zwykle do kolumn. Zmniejszenie wskaźnika „over” 1oznacza redukcję wierszową.

[1., 2.]jest po prostu [ <row 1 mean> , <row 2 mean> ].

Ta konwencja numerowania indeksów jest typowa dla oprogramowania statystycznego, zwłaszcza R.

Shadowtalker
źródło
1
Myślę, że 0 odnosi się do kolumny, a nie 2
hfz