1 import tensorflow as tf 2 t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]]) 3 #(3 2 3) 4 slicet1 = tf.slice(t, [1, 0, 0], [1, 1, 3]) 5 slicet2 = tf.slice(t, [1, 0, 0], [1, 2, 3]) 6 slicet3 = tf.slice(t, [1, 0, 0], [2, 1, 3]) 7 sess=tf.Session() 8 print(sess.run((slicet1)))#[[[3 3 3]]] 9 print(sess.run((slicet2)))#[[[3 3 3] 10 #[4 4 4]]] 11 print(sess.run((slicet3)))#[[[3 3 3]] 12 #[[5 5 5]]]
Shape:
shape的功能是讀取tensor各維度的長度,以本例中t為例,括號共有3層,即t為3維tensor,下面進行逐層分析。
只看它最外面的括號,可以看成是:
t = [A, B, C] #這是第一維度
然后每一個里面有兩個元素,可以寫成:
A = [i, j], B = [k, l], C = [m, n] #這是第二維度
最后,這i, j, k, l, m, n中又分別有三個元素:
i = [1, 1, 1], j = [2, 2, 2], k = [3, 3 ,3], l = [4, 4, 4], m = [5, 5, 5], n = [6, 6, 6] # 這是第三維度
所以shape就是中括號 [ ] 的層級里單位的數量。
對於t,最外面括號里有3個元素,分別是A, B, C。這三個元素中每個里面有2個元素, i和j, k和l, m和n。
他們里面每一個又有3個數字。所以t的shape是[3,2,3]。
Slice:
在解釋slice之前,首先要注意python的數組index是從0開始的。
之后來看例子:
tf.slice(t, [1, 0, 0], [1, 1, 3]) # begin = [1, 0, 0]
這里根據順序我們知道,begin是[1, 0, 0], size是[1, 1, 3]. 他們兩個數組的意義是從左至右,每一個數字代表一個維度。上面說了begin的意思是起始位置,那么[1, 0, 0]的意思是在3個維度中,每個維度從哪里開始算起。
第一維度是[A, B, C]。 begin里[1, 0, 0]是1,也就是從B算起。其次第二維度里B = [k, l],begin里第二個數是0,也就是從k算起。第三維度k = [3, 3 ,3],begin里第三個數是0,就是從第一個3算起。
確定這三個起始點之后,再來看size。
size的意思是每個維度的大小,也就是每個維度取幾個元素。size的應該是最后輸出的tensor的shape。
本例中:
t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [1, 1, 3]) # size = [1, 1, 3]
size里第一個是1,意思是在第一個維度取1個元素。t = [A, B, C] begin是起算是B,取1個那就是B。故第一維度結果就是[B]
size第二個也是1,第二維度B = [k, l], begin里起算是k,取1個是k。那么第二維度結果是[[k]]。
size第三個是3,第三維度k = [3, 3 ,3],begin里起算是第一個3。取3個元素,即把三個3都取了,所以是[[[3, 3, 3]]]
例2:
t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [1, 2, 3])
這里begin還是一樣[1, 0 ,0]。 size第一個維度取一個,還是[B]。然后size第二個數不是1了,是2,意為取兩個。因B = [k, l],所以,是k和l都要取。第三維度取3個,即k = [3, 3 ,3],l = [4, 4, 4]都要slice走。
總結一下,第一維度取[B]。第二維度里把B換成[k, l],就變成了[[k, l]]. 第三維度里把k換成[3, 3 ,3],把l 換成 [4, 4, 4],替換后是最終結果
[[[3, 3, 3], [4, 4, 4]]]
例外:
t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [-1, -1, -1])
對於這種情況,源代碼注釋中有一句話:
If `size[i]` is -1, all remaining elements in dimension i are included in the slice. In other words, this is equivalent to setting: `size[i] = input.dim_size(i) - begin[i]`
也就是說,如果size輸入值是-1的話,在那個維度剩下的數都會slice走。上面的例子中,begin是[1, 0, 0]。三個維度都是-1的話,那么結果: 第一維度是[B,C];第二維度是[[k, l], [m, n]]; 第三維度是[[[3,3,3], [4,4,4]], [[5,5,5], [6,6,6]]]
expand_dims()
本例中,原本t為2*3,即長2寬3的二維平面,tf.expand_dims完成升維,即把二維平面擴展為三維空間,即2*3*1,長2寬3高1。
tf.expand_dims(input, dim, name=None)
第1個參數input為輸入張量,第2個參數為新增維度的位置。
比如原來是x*y,現在新增z,t3=tf.expand_dims(t,2)后,現態空間就變成了x*y*z,類似的,第2個參數為0時,現態空間為z*x*y
dim傳的參數值起維度定位作用。
ref:
https://www.tensorflow.org/versions/r1.1/api_docs/python/tf/slice