这几天在看一些tensorflow如何创建神经网络代码,对张量的维数问题产生了一些困惑,在查阅了资料后将自己的理解和感悟写下。
更新:如何判断张量的shape
比如:
img1 = tf.constant(value=[[[[1],[2],[3],[4]],[[1],[2],[3],[4]],[[1],[2],[3],[4]],[[1],[2],[3],[4]]]],dtype=tf.float32)
它的shape是什么呢?
我的理解如下:
首先先看最里面的括号,它表示一位张量,看里面的元素的个数,上面代码最里面括号里有1个元素。
接着看倒数第二层括号,倒数第二层括号里面有4个元素。
同理倒数第三层括号里有4个元素。
最外侧括号里有1个3维张量。
因此它的shape为:[1 4 4 1]
----------------------------------------------------------------------------------------------------------------------------------------------------------------
首先一维矩阵是很好理解的
a = tf.ones([2])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(a))
产生1行2列的矩阵
二维矩阵
a = tf.ones([2,3])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(a))
2行3列的矩阵
三维矩阵
a = tf.ones([2,3,3])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(a))
三维矩阵就不能用简单的行列式来理解了,它产生了2*3*3个1,先看最右边的3,代表最内层矩阵有3个1(我觉得可以理解成矩阵的列),接着中间的3代表第二层矩阵,它有3行,最左边的2表示最外层矩阵,有2行。我们如果给它填充些数字
a = tf.constant([1.,2,3,4,5,6,7,8,9],shape=[2,3,3])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(a))
它产生的结果如上图,为什么是这么填充的呢?
首先执行最右边的3,表示最内层矩阵a有3个元素:[1. 2. 3.]
接着执行中间的3,表示中间层b有3个最内层矩阵a:
[[1. 2. 3.]
[4. 5. 6.]
[7. 8. 9.]]
最后执行最左边的2,表示最外层有2个中间层b,因为并有个18个数字,所以剩下的9个数字都是最后的9:
[[[1. 2. 3.]
[4. 5. 6.]
[7. 8. 9.]]
[[9. 9. 9.]
[9. 9. 9.]
[9. 9. 9.]]]
四维矩阵
四维矩阵类似于三维矩阵
a = tf.constant([1.,2,3,4,5,6,7,8,9],shape=[2,3,3,2])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(a))
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]
如是三维数组,则结果如下:
a = tf.constant([1.,1,2,2,3,3,4,4],shape=[2,2,2])
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print("初始矩阵:")
print(sess.run(a))
print("reduce_mean(a):")
print(sess.run(tf.reduce_mean(a)))
print("tf.reduce_mean(a, 0):")
print(sess.run(tf.reduce_mean(a, 0)))
print("tf.reduce_mean(a, 1)")
print(sess.run(tf.reduce_mean(a, 1)))
print("tf.reduce_mean(a, 2)")
print(sess.run(tf.reduce_mean(a, 2)))
print("\n")
发现,
当axis
参数为NULL时,依然计算整个数组的均值:(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维的,如k=3.
tf.reduce_mean(x, axis=k-1)的结果是对最里面一维所有元素进行求平均数。
tf.reduce_mean(x, axis=k-2)是对倒数第二层里的向量对应的元素求平均数。
tf.reduce_mean(x, axis=k-3)把倒数第三层的每个向量对应元素求平均数。
因此,当k=3,axis=2时,对最里面的所有一维元素求平均数,我们的最内层就是(1,1),(2,2),(3,3),(4,4),第一个数字为(1+1)/2=1;
当k=3,axis=1时,对倒数第二层的向量所对应的元素求平均数,([1,1],[2,2])和([3, 3],[4, 4]),第一个数字为(1+2)/2=1.5;
当k=3,axis=2时,对倒数第三层的向量所对应的元素求平均数,([[1, 1], [2, 2]])([[3, 3], [4, 4]]),第一个数字为(1+3)/2=2;
四维矩阵也是类似的自己可以尝试算一下,加深理解。
参考:https://www.cnblogs.com/rossoneri/p/8029940.html
https://www.zhihu.com/question/51325408/answer/238082462
附加:关于类似于tf.reshape(input,[-1,28,28,1])这样的函数:
是将原来的input这个张量的shape变成[-1,28,28,1]这个维数,其中的-1表示系统自动计算出在最层的维度。