一文理解Tensorflow中reduce_mean() reduce_sum() reduce_max()...系列
在Tensorflow(TF)中,常常會看到“reduce_"系列的東西,比如reduce_sum,reduce_mean…,剛剛開始我覺得,求和就sum就行,為什麼加一個reduce_字首?
後來我意識到,每一次求和或者求平均值,其實都是自動的對Tensor進行了降維,例如,對向量[1,2,3,4]求和,得到一個標量10。
剛剛開始接觸reduce系列,通常需要花一些時間在腦海中視覺化哪一個維度被減掉了,但是在熟悉了tensor的 shape/dimensions/indexing之後,很多debug會節省很多時間。
其實TF的sum和mean與numpy,matlab都類似,index=0表示按列求和或者取平均,index=1表示按照行求和或者取平均,只是TF中處理的多是4維或者5維[batch_size, time_steps, width, height, channels]張量,不那麼容易理解,下面以一個三維Tensor為例子來操作。
# Let's initialize the tensor. In [3]: x = tf.constant([[[1,2,3,4,5], [4,5,6,7,8]], [[2,4,6,8,10],[3,6,9,12,15]], [[8,8,8,8,8], [9,9,9,9,9]]]) In [9]: sess = tf.InteractiveSession() # Let's see how it looks. In [10]: x.eval() Out[10]: array([[[ 1, 2, 3, 4, 5], [ 4, 5, 6, 7, 8]], [[ 2, 4, 6, 8, 10], [ 3, 6, 9, 12, 15]], [[ 8, 8, 8, 8, 8], [ 9, 9, 9, 9, 9]]], dtype=int32)
這裡順便說一下tf.InteractiveSession和tf.Session的區別,經常做大專案的同學知道,tf.Session一般都是在整個網路的計算圖構建完了之後,再來run初始化變數和feed資料。但是tf.InteractiveSession不同,它支援先開sess,然後加入計算圖,也就是說,如果是做小實驗,熟悉Tensorflow的各個函式,用tf.InteractiveSession和eval()函式是合適的。
tf.reduce_max(x,0) 輸出是什麼呢?
tf.reduce_max(x, 0) 減掉的是第0維,所以這個(3,2,5)的tensor中的3會消失。
In [11]: tf.reduce_max(x,0) Out[11]: <tf.Tensor 'Max:0' shape=(2, 5) dtype=int32> In [12]: tf.reduce_max(x,0).eval() Out[12]: array([[ 8, 8, 8, 8, 10], [ 9, 9, 9, 12, 15]], dtype=int32)
對於第一維是一樣的,結果的shape是(3,5)
In [14]: tf.reduce_max(x,1)
Out[14]: <tf.Tensor 'Max_3:0' shape=(3, 5) dtype=int32>
In [15]: tf.reduce_max(x,1).eval()
Out[15]:
array([[ 4, 5, 6, 7, 8],
[ 3, 6, 9, 12, 15],
[ 9, 9, 9, 9, 9]], dtype=int32)
在一些實際程式碼中,可能會看到reduce中不是減掉單個維度而是減掉幾個維度,比如tf.reduce_max(x,(1,2))意味著我們想要每個batch中的最大值(batch_size通常是dimension 0),這種情況下坍縮的就是維度1和2.
In [16]: tf.reduce_max(x,(1,2)).eval()
Out[16]: array([ 8, 15, 9], dtype=int32)
In [17]: tf.reduce_max(x,(1,2))
Out[17]: <tf.Tensor 'Max_11:0' shape=(3,) dtype=int32>
你會發現這改變了最初tensor的shape,怎麼辦?
加上那句keepdims=True.
In [22]: tf.reduce_max(x,(1,2), keepdims=True).eval()
Out[22]:
array([[[ 8]],
[[15]],
[[ 9]]], dtype=int32)
In [23]: tf.reduce_max(x,(1,2), keepdims=True)
Out[23]: <tf.Tensor 'Max_10:0' shape=(3, 1, 1) dtype=int32>