Shape,expand_dims,slice基本用法
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