Tensorflow 的reduce_sum()函數到底是什麼意思,誰能解釋下?

見https://www.tensorflow.org/versions/master/api_docs/python/math_ops.html#reduce_sum

這個例子不是很理解,後面的reduction_indices到底是什麼意思?


reduction_indices很容易搞蒙圈,上個圖加深理解吧。

為了展示的更加清晰,我升級了一下這個圖,但感覺還是不完美,[3, 3]豎起來過來顯示是為了說明reduction_indices=[1, 0]的過程中維度的信息是一直保留著的,所以它並不是一個列向量,亦即它不是[ [3], [3] ],它本質還是[ 3, 3 ],這也是為什麼你在僅僅使用reduction_indices=1的時候,列印出來的是[ 3, 3 ]的原因:

這裡是老版本的示意圖:


reduce_sum() 就是求和,由於求和的對象是tensor,所以是沿著tensor的某些維度求和。reduction_indices是指沿tensor的哪些維度求和。


題主提問這個問題主要是因為對tensor缺乏認識,沒有從維度的角度上去思考。

官方文檔寫的比較詳細了,結合example看。 @li Eta 也說得很詳細了,所以我就在這裡貼一下官方文檔方便參考同時簡單說一下tensor。

官方文檔,關鍵字加粗,注意example的3,4,5行的區別

Computes the sum of elements across dimensions of a tensor.

Reducesinput_tensoralong the dimensions given in reduction_indices. Unless keep_dims is true, the rank of the tensor is reduced by 1 for each entry in reduction_indices. If keep_dims is true, the reduced dimensions are retained with length 1.

If reduction_indices has no entries, all dimensions are reduced, and a tensor with a single element is returned.

For example:

# "x" is [[1, 1, 1]
# [1, 1, 1]]
tf.reduce_sum(x) ==&> 6
tf.reduce_sum(x, 0) ==&> [2, 2, 2]
tf.reduce_sum(x, 1) ==&> [3, 3]
tf.reduce_sum(x, 1, keep_dims=True) ==&> [[3], [3]]
tf.reduce_sum(x, [0, 1]) ==&> 6

Args:

  • input_tensor: The tensor to reduce. Should have numeric type.
  • reduction_indices: The dimensions to reduce. If None (the default), reduces all dimensions.
  • keep_dims: If true, retains reduced dimensions with length 1.
  • name: A name for the operation (optional).

Returns:

The reduced tensor.

學習TF的過程中,思維要從多維的角度上去思考。建議題主仔細了解一下tensor的定義。

這有個不錯的簡單解釋。

還有篇不錯的tensor文檔,不過是英文的,也比較長,如果題主有需求可以閱讀一下。


2017.7.14更新:

在tensorflow 1.0版本中,reduction_indices被改為了axis,感覺方便很多。

原答案:

reduce_xxx這類操作,在官方文檔中,都放在Reduction下:

ReductionTensorFlow provides several operations that you can use to perform common math computations that reduce various dimensions of a tensor.

也就是說,這些操作的本質就是降維,以xxx的手段降維。

在所有reduce_xxx系列操作中,都有reduction_indices這個參數,即沿某個方向,使用xxx方法,對input_tensor進行降維。

reduction_indices的默認值是None,即把input_tensor降到 0維,也就是一個數。

對於2維input_tensor,reduction_indices=0時,按列;reduction_indices=1時,按行。


看了一圈發現居然沒有多維的例子,補充一個。

計算方法:

規律:

對於k維的,tf.reduce_sum(x, axis=k-1)的結果是對最裡面一維所有元素進行求和。tf.reduce_sum(x, axis=k-2)是對倒數第二層里的向量對應的元素進行求和。tf.reduce_sum(x, axis=k-3)把倒數第三層的每個向量對應元素相加。

用tf.reduce_sum里的例子進行檢驗:

# "x" is [[1, 1, 1]

# [1, 1, 1]]

tf.reduce_sum(x, 0) ==&> [2, 2, 2] # 倒數第二層對應元素相加

tf.reduce_sum(x, 1) ==&> [3, 3] #最裡面一層求和


之前的回答不知為啥沒發出來啊。

reduction 簡單粗暴的說就是,n 維的數據中,把某一個維度上這一序列的數縮減到一個(比如求它們的和或者平均值),這樣就降低了一個維度,所以叫 reduce,比如 map-reduce 也差不多是這個意思。

上面 凡心 的圖已經很清楚了,目前這個 reduction_indices 參數改名叫 axis ,這樣就直白多了,代表 reduce 是沿著哪個軸的方向進行的。

下面是我寫的 tensorflow 關於 reduce_sum 的小例子和運行結果 (具體說明在程序注釋中):

import tensorflow as tf

# x 的定義,和函數注釋里一樣的
# ^
# | [
# [1, 1, 1]
# 0軸 [1, 1, 1]
# ]
# |
# | ----- 1軸 -------&>
#
x = tf.constant([[1, 1, 1], [1, 1, 1]])

#
# 如果 axis 參數默認的話,就是 reduce 所有的維度,得到常數 6
#
reduce_sum_default = tf.reduce_sum(x)

# 沿著 0 軸的方向逐個相加
# ^
# | [
# [1, 1, 1]
# 0軸 [1, 1, 1]
# ]
# | || || ||
# |
# | [2, 2, 2]
# |
# | ----- 1軸 -------&>
#
reduce_sum_axis0 = tf.reduce_sum(x, axis = 0)
#
# [2, 2, 2] 只剩下 1 個維度,reduce 到 0 維 即常數 6
#
resuce_sum_axis0_axis0 = tf.reduce_sum(reduce_sum_axis0)

# 沿著 1 軸的方向逐個相加
# ^
# | [
# [1, 1, 1] = 3
# | ( )
# 0軸 [1, 1, 1] = 3
# ]
# |
# | ----- 1軸 -------&>
#
reduce_sum_axis1 = tf.reduce_sum(x, 1)
#
# [3, 3] 只剩下 1 個維度,reduce 到 0 維 即常數 6
#
reduce_sum_axis1_axis0 = tf.reduce_sum(reduce_sum_axis1, 0)

#
# 一次沿著 2 個軸先後 reduce
#
reduce_sum_axis_01 = tf.reduce_sum(x, [0, 1])
reduce_sum_axis_10 = tf.reduce_sum(x, [1, 0])

with tf.Session() as sess:
result_default = sess.run(reduce_sum_default)

result_0 = sess.run(reduce_sum_axis0)
result_0_0 = sess.run(resuce_sum_axis0_axis0)

result_1 = sess.run(reduce_sum_axis1)
result_1_0 = sess.run(reduce_sum_axis1_axis0)

result_01 = sess.run(reduce_sum_axis_01)
result_10 = sess.run(reduce_sum_axis_10)

print (u"不傳入 axis 參數,默認 reduce 到0維:")
print (result_default)

print ("------")
print (u"axis 參數傳入0:")
print (result_0)
print (u"將 %s 再次reduce:" % str(result_0))
print (result_0_0)

print ("------")
print (u"axis 參數傳入1:")
print (result_1)
print (u"將 %s 再次reduce:" % str(result_1))
print (result_1_0)

print ("------")
print (u"axis 參數輸入 [0, 1]:")
print (result_01)
print (u"axis 參數輸入 [1, 0]:")
print (result_10)

運行結果:

不傳入 axis 參數,默認 reduce 到0維:
6
------
axis 參數傳入0:
[2 2 2]
將 [2 2 2] 再次reduce:
6
------
axis 參數傳入1:
[3 3]
將 [3 3] 再次reduce:
6
------
axis 參數輸入 [0, 1]:
6
axis 參數輸入 [1, 0]:
6


最近在學習tensorflow,說一下自己的理解,不知道是不是正確,請各位大神幫忙糾正下 tf.reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)

示例 sess = tf.Session() t1 = tf.constant([[1., 2., 3.], [4., 5., 6.]])

print(sess.run(t1)) ==&> [[ 1. 2. 3.] [ 4. 5. 6.]]

print(sess.run(tf.reduce_mean(t1))) ==&> 3.5

print(sess.run(tf.reduce_mean(t1,0))) ==&> [ 2.5 3.5 4.5]

print(sess.run(tf.reduce_mean(t1,1))) ==&> [ 2. 5.]

維度的個人理解(暫時不知道定義是否正確):

第一維表示tensor最外層的數據,比如【[], []】中文中括弧表示的維度

第二維表示第一維裡面緊跟著的那一層維度,比如[【】, 【】] 中文中括弧表示的維度

第三維表示第二維裡面緊跟著的那一層維度,比如[[【】], [【】]] 中文中括弧表示的維度

第n維依次類推

計算規則(自己整理,未見得準確):

1. 先計算每個維度內所有數據的和值(如果是數字直接相加,如果是矩陣直接執行矩陣相加)

2. 再使用上一步計算結果除以該維度的寬度(或長度)

例如:

t1 = tf.constant([[1., 2., 3.], [4., 5., 6.]])

print(sess.run(tf.reduce_mean(t1,0))) ==&> [ 2.5 3.5 4.5]

按上述步驟,先計算第一維內所有數據和值,也就是執行矩陣加法形如(僅供參考理解,表達式可能不正確):[1., 2., 3.] + [4., 5., 6.] = [5., 7., 9.]

再使用上一步計算結果除以該維度的寬度(或長度), [5., 7., 9.] / 2 = [ 2.5 3.5 4.5]

再比如:

t1 = tf.constant([[1., 2., 3.], [4., 5., 6.]]) print(sess.run(tf.reduce_mean(t1,1))) ==&> [ 2. 5.]

按上述步驟,先計算第二維內所有數據和值,也就是執行矩陣加法得到tf.reduce_sum(t1, 1) &<=大概意思=&> [sum([1., 2., 3.]), sum([4., 5., 6.])] = [6., 15.]

再使用上一步計算結果除以該維度的寬度(或長度), [6., 15.,] / 3 = [ 2. 5.]

同理,tf.reduce_sum/tf.reduce_max/tf.reduce_min等,應該也可以這樣理解


看了些回答有的講按行按列,有的只給例子,不容易被新手理解。下面結合自己的理解舉個多維tensor例子簡單說明。下面是個2*3*4的tensor。

[[[ 1 2 3 4]

[ 5 6 7 8]

[ 9 10 11 12]]

[[13 14 15 16]

[17 18 19 20]

[21 22 23 24]]]

如果計算tf.reduce_sum(tensor, axis=0),axis=0說明是按第一個維度進行求和,也就是說把

[[ 1 2 3 4]

[ 5 6 7 8]

[ 9 10 11 12]

[[13 14 15 16]

[17 18 19 20]

[21 22 23 24]]相加,所以第一個維度(也就是2)抹去,求和結束得到的tensor_ans是3*4(之前tensor是2*3*4)。顯然tensor_ans的元素分別是1+13;2+14;3+15……;12+24。即:

[[1+13 2+14 3+15 4+16]

[5+17 6+18 7+19 8+20]

[9+21 10+22 11+23 12+24]]。

依次類推,如果axis=1,那麼求和結果shape是2*4,即:

[[ 1 + 5 + 9 2 + 6+10 3 + 7+11 4 + 8+12]

[13+17+21 14+18+22 15+19+23 16+20+24]]

如果axis=2,那麼求和結果shape是2*3,即:

[[1+2+3+4 5+6+7+8 9+10+11+12]

[13+14+15+16 17+18+19+20 21+22+23+24]]


一般在python的科學計算里,0是按列的,1是按行的


與numpy.sum是一樣的。

看看文檔就懂了。

Help on function reduce_sum in module tensorflow.python.ops.math_ops:

reduce_sum(input_tensor, axis=None, keep_dims=False, name=None, reduction_indice

s=None)

Computes the sum of elements across dimensions of a tensor.

Reduces `input_tensor` along the dimensions given in `axis`.

Unless `keep_dims` is true, the rank of the tensor is reduced by 1 for each

entry in `axis`. If `keep_dims` is true, the reduced dimensions

are retained with length 1.

If `axis` has no entries, all dimensions are reduced, and a

tensor with a single element is returned.

For example:

```python

# "x" is [[1, 1, 1]

# [1, 1, 1]]

tf.reduce_sum(x) ==&> 6

tf.reduce_sum(x, 0) ==&> [2, 2, 2]

tf.reduce_sum(x, 1) ==&> [3, 3]

tf.reduce_sum(x, 1, keep_dims=True) ==&> [[3], [3]]

tf.reduce_sum(x, [0, 1]) ==&> 6

```

Args:

input_tensor: The tensor to reduce. Should have numeric type.

axis: The dimensions to reduce. If `None` (the default),

reduces all dimensions.

keep_dims: If true, retains reduced dimensions with length 1.

name: A name for the operation (optional).

reduction_indices: The old (deprecated) name for axis.

Returns:

The reduced tensor.

@compatibility(numpy)

Equivalent to np.sum

@end_compatibility


簡單的寫下自己的看法,我看了下感覺像是這裡reduce_sum()中的reduction_indices類似於numpy中的np.sum()中的axis。axis可以看做是從矩陣括弧的順序(如果你把矩陣中的括弧全部打上,就像python中的print那樣)


x[ ][ ] = [[1, 1, 1],

[1, 1, 1]]

按第一維方向投影再求和

tf.reduce_sum(x, 0) --&>[2,2,2]

按第二維方向投影再求和

tf.reduce_sum(x, 1) --&>[3,

3]

第一維的方向:x[0]-&>x[1] 即 [1, 1, 1]-&>[1, 1, 1],垂直投影

第二維的方向,首先要確定上一個維度的值,隨便取一個0:x[0][0]-&>x[0][1] 即 1-&>1,水平投影


reduce_sum很好理解,如果不加參數 reduce_sum(矩陣A) ,即對矩陣所有的值累加,求和,如果加參數reduction_indices 就稍顯複雜,以矩陣A 有2維舉例,假設矩陣A 為 3*4的矩陣,reduction_indices =[0,1]的含義就是 先從第一維開始壓縮,將其縱向壓扁求和,將其變成1*4的矩陣,然後再橫向壓扁求和,變成1*1的數值,如A = [[1,2,3,4],[2,3,4,5],[3,4,5,6]] ,則第一步壓縮變成

[1+2+3,2+3+4,3+4+5,4+5+6] = [6,9,12,15] ,第二步[6+9+12+15] = [42] = 42


比較直觀的理解來說,tf裡面的tensor就是一個多維數組。所以reduce sum就是壓縮這個數組。就像把一個立方體壓成平的。


推薦閱讀:

如何看待谷歌移動端深度學習框架 TensorFlow Lite 正式發布?可能會帶來什麼影響?
有沒有基於移動端GPU的深度學習前饋網路框架?
如何評價deep mind開源的sonnet?
如何評價陳天奇的模塊化深度學習系統NNVM?

TAG:Python | 機器學習 | 深度學習DeepLearning | TensorFlow |