文章目录
- 一、shape与reshape
-
- 1. shape
- 2. reshape
- 二、Tensor理解
-
- 1. 一维张量
- 2. 二维张量
- 3. 三维张量
- 4. 超过三维的多维张量
- 三、API理解
-
- 1. 关于reduce_xxx的维度问题
-
- tf.reduce_mean
- 参考
一、shape与reshape
1. shape
举个例子来说:
import tensorflow as tf
a = tf.constant([[1.,2.,3.],[4.,5.,6.],[7.,8.,9.]],shape = [3,3])
b = tf.initialize_all_variables()with tf.Session() as sess:sess.run(b)print(sess.run(a))
运行结果如下:
[[ 1. 2. 3.][ 4. 5. 6.][ 7. 8. 9.]]
可以理解为:
shape[3, 3]
的第一个“3
”表示:“在第一个中括号以内存在3
组元素”,
同理,则shape[3, 3]的第二个“3
”表示:“在第二个中括号以内存在3
组元素”。
由此我们可以知道[5, 5, 1, 32]
这个结构:
- 是一个四维张量
- 第一个维度:由
5
个元素组成 - 这
5
个元素均是由5
个子级元素组成 5
个子级元素中只有1
个次级元素- 一个次级元素中包含了
32
个子元素
2. reshape
tf.reshape(tensor, shape, name=None)
函数的作用是将tensor变换为参数shape
的形式。其中shape
为一个列表形式,特殊的一点是列表中可以存在-1
。
-1
代表的含义是不用我们自己指定这一维的大小,函数会自动计算,但列表中只能存在一个-1
.
shape
可以看着是reshape
变换后的矩阵大小,先不管-1
的那一个维度,先看其他维度,然后用原矩阵的总元素个数除以确定的维度,就能得到-1
维度的值。
下面是例子,自行理解。
# tensor 't' is [1, 2, 3, 4, 5, 6, 7, 8, 9]
# tensor 't' has shape [9]
reshape(t, [3, 3]) ==> [[1, 2, 3],[4, 5, 6],[7, 8, 9]]# tensor 't' is [[[1, 1], [2, 2]],
# [[3, 3], [4, 4]]]
# tensor 't' has shape [2, 2, 2]
reshape(t, [2, 4]) ==> [[1, 1, 2, 2],[3, 3, 4, 4]]# tensor 't' is [[[1, 1, 1],
# [2, 2, 2]],
# [[3, 3, 3],
# [4, 4, 4]],
# [[5, 5, 5],
# [6, 6, 6]]]
# tensor 't' has shape [3, 2, 3]
# pass '[-1]' to flatten 't'
reshape(t, [-1]) ==> [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]# -1 can also be used to infer the shape# -1 is inferred to be 9:
reshape(t, [2, -1]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],[4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 2:
reshape(t, [-1, 9]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],[4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 3:
reshape(t, [ 2, -1, 3]) ==> [[[1, 1, 1],[2, 2, 2],[3, 3, 3]],[[4, 4, 4],[5, 5, 5],[6, 6, 6]]]# tensor 't' is [7]
# shape `[]` reshapes to a scalar
reshape(t, []) ==> 7
二、Tensor理解
1. 一维张量
tf.constant([1.0 , 2.0 , 3.0])
表示:生成一个一维张量(向量),shape是1
行3
列
2. 二维张量
x = tf.constant([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
x
实际上就是:
[ [ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.] ]
shape是(3,3)
,第一对[ ]中有3
个元素,所以第一维是3
,3个元素分别是:[ 1. 2. 3.]
; [ 4. 5. 6.]
和 [ 7. 8. 9.]
。
这三维中的每一维,也就是第二个[ ]中也有3
个元素,所以第二维也是3
。因此shape为(3,3)
这种二维的我们可以理解为,是一个3
行3
列矩阵
3. 三维张量
x = tf.constant([ [ [1., 1.], [2., 2.]], [[3., 3.], [4., 4.] ] ])
x
实际上是:
[
[ [ 1. 1.]
[ 2. 2.] ]
[ [ 3. 3.]
[ 4. 4.] ]
]
shape(2,2,2)
这种三维的我们也可以理解为是2
个2
行2
列的矩阵
4. 超过三维的多维张量
举个例子理解一下:
比如将格子划分成了7x7
的大小,每个格子产生2
个框,每个框产生4
个坐标(x,y,h,w)
所以在坐标那里的代码维度假设考虑为向量,那么向量的shape
就应该是(7,7,2,4)
第一个[ ]
中会有7
个[ ]
作为第一维度的向量[ [ ] , [ ] , [ ] , [ ] , [ ] , [ ] , [ ] ]
如果取第一维度为0
的元素,那么实际上就可以理解为,取走所有第一行的网格格子(7个网格)
产生的方框(7x2个方框)
,每个方框4
个坐标,也就是取走了7x2x4
个元素
然后每一个[ ]
中又有7个[ ]
,再有2个[ ]
,最后再有4
个数字,其实就是一个套一个。
代码中经常取的是[:,:,:,:,0]
,意味着,取走最后一维向量中的第1
个元素,最后一维是坐标(x,y,h,w)
,取走第一个元素,也就意味着取走所有框7x7x2
个框的x
元素。
其实也就是,你取某一行,那就是取走所有这一行的信息,你取某一列,也就取走所有关于这一列的信息,你取某一个坐标,那就是取走所有关于这个坐标的信息。
三、API理解
1. 关于reduce_xxx的维度问题
对于k
维tensor,
tf.reduce_xxx(x, axis=k-1)
的结果:是对最里面一维所有元素进行求和。
tf.reduce_xxx(x, axis=k-2)
:是对倒数第二层里的向量对应的元素进行求和。
tf.reduce_xxx(x, axis=k-3)
:把倒数第三层的每个向量对应元素相加。
…………
tf.reduce_mean
tf.reduce_mean是 计算Tensor各个维度元素的均值。这个方法根据输入参数axis
的维度上减少输入input_tensor
的维度。
该API的结构如下:
reduce_mean(input_tensor,axis=None,keep_dims=False,name=None,reduction_indices=None
)
举个二维的例子说明一下:
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
,即:k-2
,对倒数第二层里的向量对应的元素进行求和取均值,那么在这意味着对列取均值:[1.5, 1.5]
- 当axis取
1
,即:k-1
,对最里面一维所有元素进行求和取均值,那么在这就意味着对行取均值:[1.0, 2.0]
再举一个三维的例子
推测一下,前面二维的经过处理都变成一维的,也就是经历了一次降维,那么现在三维的或许应该变成二维。但现在多了一维,应该从哪个方向做计算呢?
sess = tf.Session()
x = tf.constant([[[1., 1.], [2., 2.]], [[3., 3.], [4., 4.]]]) # 2*2*2
print(sess.run(x))
#[[[ 1. 1.]
# [ 2. 2.]]
#
# [[ 3. 3.]
# [ 4. 4.]]]
print(sess.run(tf.reduce_mean(x)))
print(sess.run(tf.reduce_mean(x, 0)))#[[2 2][3 3]]
print(sess.run(tf.reduce_mean(x, 1)))#[[1.5 1.5][3.5 3.5]]
print(sess.run(tf.reduce_mean(x, 2)))#[[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]]
参考
- https://blog.csdn.net/weixin_43384257/article/details/102290159
- https://blog.csdn.net/kakangel/article/details/88641251
- https://blog.csdn.net/lipku/article/details/103169833