1. 程式人生 > >[TensorFlow]Tensor維度理解

[TensorFlow]Tensor維度理解

question 分享 流動 小括號 ash 4.5 就是 axis rank

http://wossoneri.github.io/2017/11/15/[Tensorflow]The-dimension-of-Tensor/

Tensor維度理解

Tensor在Tensorflow中是N維矩陣,所以涉及到Tensor的方法,也都是對矩陣的處理。由於是多維,在Tensorflow中Tensor的流動過程就涉及到升維降維,這篇就通過一些接口的使用,來體會Tensor的維度概念。以下是個人體會,有不準確的請指出。

tf.reduce_mean

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

計算Tensor各個維度元素的均值。這個方法根據輸入參數axis的維度上減少輸入input_tensor的維度。
舉個例子:

x = tf.constant([[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.]

x是二維數組[[1.0,1.0],[2.0, 2.0]]
axis參數取默認值時,計算整個數組的均值:(1.+1.+2.+2.)/4=1.5
axis

取0,意味著對列取均值:[1.5, 1.5]
axis取1,意味著對行取均值:[1.0, 2.0]

再換一個3*3的矩陣:

sess = tf.Session()
x = tf.constant([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
print(sess.run(x))
print(sess.run(tf.reduce_mean(x)))
print(sess.run(tf.reduce_mean(x, 0)))
print(sess.run(tf.reduce_mean(x, 1)))

輸出結果是

[[ 1.  2.  3.]
 [ 4.  5.  6.]
 [ 7.  8.  9.]]
5.0
[ 4.  5.  6.]
[ 2.  5.  8.]

如果我再加一維是怎麽計算的?

sess = tf.Session()
x = tf.constant([[[1., 1.], [2., 2.]], [[3., 3.], [4., 4.]]])
print(sess.run(x))
print(sess.run(tf.reduce_mean(x)))
print(sess.run(tf.reduce_mean(x, 0)))
print(sess.run(tf.reduce_mean(x, 1)))
print(sess.run(tf.reduce_mean(x, 2)))

我給的輸入Tensor是三維數組:

[[[ 1.  1.]
  [ 2.  2.]]

 [[ 3.  3.]
  [ 4.  4.]]]

推測一下,前面二維的經過處理都變成一維的,也就是經歷了一次降維,那麽現在三維的或許應該變成二維。但現在多了一維,應該從哪個放向做計算呢?
看下結果:

2.5
[[ 2.  2.]
 [ 3.  3.]]
[[ 1.5  1.5]
 [ 3.5  3.5]]
[[ 1.  2.]
 [ 3.  4.]]

發現,
axis參數取默認值時,依然計算整個數組的均值:(float)(1+2+3+4+1+2+3+4)/8=2.5
axis取0,計算方式是:

[[(1+3)/2, (1+3)/2],
 [(2+4)/2, (2+4)/2]]

axis取1,計算方式是:

[[(1+2)/2, (1+2)/2],
 [(3+4)/2, (3+4)/2]]

axis取2,計算方式是:

[[(1+1)/2, (2+2)/2],
 [(3+3)/2, (4+4)/2]]

看到這裏,能推斷出怎麽從四維降到三維嗎?
有人總結了一下:

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

拿上面的數組驗證這個規律:

[[[ 1.  1.]
  [ 2.  2.]]

 [[ 3.  3.]
  [ 4.  4.]]]

我們的k=3。小括號是一層,在一層內進行計算:
axis=3-1=2,做最內層計算,我們的最內層就是(1,1),(2,2),(3,3),(4,4),計算出來的就是

[[ 1.  2.]
 [ 3.  4.]]

axis=3-2=1,做倒數第二層計算(參考二維計算):([1,1],[2,2])和([3, 3],[4, 4])

[[ 1.5  1.5]
 [ 3.5  3.5]]

axis=3-3=1,做倒數第三層計算:([[1, 1], [2, 2]])([[3, 3], [4, 4]])

[[ 2.  2.]
 [ 3.  3.]]

對於四維的,就貼段結果,自己可以嘗試算一下,加深理解。

# input 4-D
[[[[ 1.  1.]
   [ 2.  2.]]

  [[ 3.  3.]
   [ 4.  4.]]]


 [[[ 5.  5.]
   [ 6.  6.]]

  [[ 7.  7.]
   [ 8.  8.]]]]
# axis=none
4.5

# axis=0
[[[ 3.  3.]
  [ 4.  4.]]

 [[ 5.  5.]
  [ 6.  6.]]]

# axis=1
[[[ 2.  2.]
  [ 3.  3.]]

 [[ 6.  6.]
  [ 7.  7.]]]

在tensorflow 1.0版本中,reduction_indices被改為了axis,在所有reduce_xxx系列操作中,都有reduction_indices這個參數,即沿某個方向,使用xxx方法,對input_tensor進行降維。

對於axis參數的作用,文檔的解釋是

the rank of the tensor is reduced by 1 for each entry in axis

即Tensor在axis的每一個分量上的秩減少1。如何理解矩陣的「秩」? - 馬同學的回答 - 知乎

附一張reduction_indices的圖
技術分享圖片

下面再看下第三個參數keep_dims,該參數缺省值是False,如果設置為True,那麽減少的維度將被保留為長度為1。
回頭看看最開始的例子:

# 2*2
[[ 1.  1.]
 [ 2.  2.]]
# keep_dims=False
[ 1.5  1.5] # 1*2
[ 1.  2.]   #1*2
# keep_dims=True
[[ 1.5  1.5]]   #1*2
[[ 1.]          #2*1
 [ 2.]]

可以看到差別。關於這個參數,還沒看到太多介紹,還需要了解。

[TensorFlow]Tensor維度理解