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 |