2015-12-12 56 views
54

MNIST beginner tutorial,有accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))Numpy和Tensorflow中np.mean和tf.reduce_mean之間的區別?

tf.cast基本上改變了張量的對象的類型,但是是什麼tf.reduce_meannp.mean之間的區別?

這裏是tf.reduce_mean的DOC:

reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None) 
input_tensor: The tensor to reduce. Should have numeric type. 
reduction_indices: The dimensions to reduce. If `None` (the defaut), 
    reduces all 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.] 

對於一維向量,它看起來像np.mean == tf.reduce_mean,但我不明白髮生了什麼事在tf.reduce_mean(x, 1) ==> [1., 2.]tf.reduce_mean(x, 0) ==> [1.5, 1.5]有點合理,因爲[1,2]和[1,2]的平均值是[1.5,1.5],但tf.reduce_mean(x,1)是怎麼回事?

+0

他們生產的[整數值不同的結果(http://stackoverflow.com/a/43713062/1090562)由於蟒蛇 –

回答

67

numpy.meantensorflow.reduce_mean的功能是相同的。他們做同樣的事情。從文檔中,可以看到numpytensorflow。讓我們來看一個例子,

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) 

輸出

[ 3.5 5.5 6.5] 
[ 3.5 5.5 6.5] 

在這裏你可以看到,當axis(numpy的)或reduction_indices(tensorflow)爲1,這意味着計算跨(3,4)和( 5,6)和(6,7),因此1定義了在哪個軸上計算均值。當它爲0時,平均值在(3,5,6)和(4,6,7)之間計算,依此類推。我希望你明白這個主意。

現在他們之間有什麼不同?

你可以在python的任何地方計算numpy操作。但爲了進行張量流動操作,必須在張量流Session內完成。你可以閱讀更多關於它here。所以當你需要對張量流圖進行任何計算時(或者如果你願意的話),它必須在張量流Session內完成。

讓我們來看另一個例子。

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) 

我們可以在numpy,你會自然地,但爲了做到這一點在tensorflow,您需要執行,在Session,不使用Session你不能這樣做,增加的意思1。換句話說,當你計算tfMean = tf.reduce_mean(c)時,tensorflow不會計算它。它只計算Session。但是當你寫np.mean()時,numpy立即計算出來。

我希望它是有道理的。

+3

,但**減少**部分**意味着**在這裏? – rsht

+9

@羅曼這是一個來自函數式編程的術語。你可以在這裏閱讀它:http://www.python-course.eu/lambda.php – Daniyar

0

1通常指的是行,而2通常指的是列。減少「超過」索引1意味着減少行方向。

[1., 2.]只是[ <row 1 mean> , <row 2 mean> ]

該指數編號規則是在統計軟件的典型,尤其是R.

+0

我司相信0指列,而不是2 – hfz

1

新文檔指出tf.reduce_mean()與np產生的結果相同。意思是:

相當於np.mean

它還具有絕對相同的參數np.mean。但這裏是一個重要的區別:它們產生相同的結果只在浮點值

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 

如果將刪除類型轉換,你會看到不同的結果


在附加到這一點,諸如reduce_allreduce_any, reduce_min,reduce_max,reduce_prod的許多其他tf.reduce_函數產生與那些numpy類似物相同的值。顯然,因爲它們是操作,它們只能從會話內部執行。

3

這裏的關鍵是reduce這個詞,它是功能性編程的一個概念,它使得TensorFlow中的reduce_mean可以保持一批輸入中計算結果的運行平均值。

如果你不熟悉函數式編程,這可能看起來很神祕。所以首先讓我們看看減少了什麼。如果給出了一個像[1,2,5,4]這樣的列表,並被告知要計算平均值,那很簡單 - 只需將整個數組傳遞給np.mean即可。然而,如果你必須計算一串數字的平均值呢?在這種情況下,你必須首先通過從流中讀取來組裝數組,然後在結果數組上調用np.mean - 你必須編寫更多的代碼。

另一種方法是使用reduce範例。作爲一個例子,看看我們如何使用python中的reduce來計算數字的總和: reduce(lambda x,y: x+y, [1,2,5,4])

它的工作原理是這樣的:

  1. 第1步:從列表中讀取2位 - 1,2。評估lambda 1,2。減少存儲結果3.注意 - 這是從列表中讀取兩位數字的唯一步驟
  2. 步驟2:從列表中讀取下一位數字 - 5.評估lambda 5,3(3是步驟1的結果,減少存儲)。減少存儲結果8.
  3. 步驟3:讀取列表中的下一個數字 - 4.評估lambda 8,4(8是步驟2的結果,減少存儲)。降低存儲結果12
  4. 第4步:閱讀列表中的下一個數字 - 沒有,所以回到這裏多12

讀取的存儲結果Functional Programming in Python

要了解如何適用對於TensorFlow,請看下面的代碼塊,它定義了一個簡單的圖,它接受一個浮點數並計算平均值。然而,圖的輸入不是一個浮點數,而是一個浮點數。 reduce_mean計算所有浮點數的平均值。

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

這個模式在批量圖像計算值時派上用場。看看The Deep MNIST Example在那裏你看到這樣的代碼:

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