赞
踩
一张图可以由高度(height),宽度(width),通道数(channels)表示。一个三维的tensor可以明确表示图中的任意一点。
图片1:
上图图片形状为:(4,4,3), 每个数字代表图像像素值。在tensorflow中输入数据的形状为[batch, height, width, channels],batch为图片数量用于批量训练(mini_batch)。下面用tf.reduce_mean解析这个四维的tensor。
tf.reduce_mean(
input_tensor,
axis=None,
keep_dims=False,
name=None,
reduction_indices=None
)
这个操作将会计算维度axis上的平均值。
import tensorflow as tf
tensor_one = tf.constant([1., 2.])
with tf.Session() as sess:
a = tf.reduce_mean(tensor_one, 0)
print("tensor_one:\n",sess.run(a))
tensor_one是一个一维的向量,即只有第0维。并且在该维度上只有两个值1,2。不难看出结果就是1.5。一维的tensor在图中表示通道方向上的维度和值。如tensor_one: [1., 2.] 表示在一张图中某一个位置上两个通道上的值。如图片1中可以找到某个位置(右上角)的值为[0, 5, 2],但是这个[0, 5, 2]并不能描述一个准确的位置,它只描述了在图片1中有这个值。那如何描述一个准确的位置呢?我们再加一个维度。
tensor_two = tf.constant([[1., 2.]])
with tf.Session() as sess:
a = tf.reduce_mean(tensor_two, 0)
b = tf.reduce_mean(tensor_two, 1)
print("tensor_two a:\n",sess.run(a)) #[1, 2]
print("tensor_two b:\n",sess.run(b)) #[1.5]
tensor_two有两个维度,第0维的值是[1, 2],第一维的值是1 和 2。注意这其中的区别,一个是向量一个是数值。所以很容易理解操作 a 的结果是[1, 2],因为这个维度只有一个值,平均值就是它自己。b 的结果是1.5,同一维的运算结果。tensor_two:[[1, 2]]表示图中某一行的第0个像素位置在通道方向上的两个值。如图1中可以找到某一行中有第0个和第1个像素值为[[1,3,4],[2, 0, 2]]。显然二维向量只能描述图中某一行中的点,不能描述具体是哪一行。所以再加一个维度。
我们尝试一个稍微复杂的情况:
tensor_three = tf.constant([[[2., 4.,4.],[4., 6., 4.]],[[3., 3., 3.], [4., 3., 6.]]])
with tf.Session() as sess:
a = tf.reduce_mean(tensor_three, 0)
b = tf.reduce_mean(tensor_three, 1)
c = tf.reduce_mean(tensor_three, 2)
print("tensor_three a:\n",sess.run(a)) #[[2.5, 3.5, 3.5],[4., 4.5, 5.]]
print("tensor_three b:\n",sess.run(b)) #[[3.,5., 4.],[3.5, 3., 4.5]]
print("tensor_three c:\n",sess.run(c)) #[[3.333, 4.666],[3., 4.333]]
tensor_three有三个维度,第0维有两个值,分别是 [[2., 4., 4.],[4., 6., 6.]] 和 [[3., 3., 3.], [4., 3., 6.]],表示图的第0行和第1行。其中[2., 4., 4.]描述了第0行第0个像素点在通道方向上的三个值 2 , 4 和 4。到此三维向量已经可以描述图中唯一位置。如图1中左上角的位置可以描述为:[[[1, 3, 4]]]。
下面我们用图片展示上面的操作结果:
图2
上图便是tensor_three。从图中可以明显看出来,求第0维度的平均值:
[[(2 + 3)/2, (4 + 3)/2, (4 + 3)/2],[(4 + 4)/2, (6 + 3)/2, (4 + 6)/2]]
同理求第1维度上的平均值:
[[(2 + 4)/2, (4 + 6)/2, (4 + 4)/2],[(3 + 4)/2, (3 + 3)/2, (3 + 6)/2]]
第2维度的平均值:
[[(2 + 4 + 4)/2, (4 + 6 + 4)/2],[(3 + 3 + 3)/2, (4 + 3 + 6)/2]]
实质上这是一种降维操作,把三维的数据通过平均算法压缩成二维。
tensor_four = tf.constant([ [[[2., 4.,4.],[4., 6., 4.]],[[3., 3., 3.], [4., 3., 6.]]], [[[2., 4.,4.],[4., 6., 4.]],[[3., 3., 3.], [4., 3., 6.]]]])
with tf.Session() as sess:
a = tf.reduce_mean(tensor_four, 0)
b = tf.reduce_mean(tensor_four, 1)
c = tf.reduce_mean(tensor_four, 2)
d = tf.reduce_mean(tensor_four, 3)
print("tensor_four a:\n",sess.run(a)) #
print("tensor_four b:\n",sess.run(b)) #[[[2.5, 3.5, 3.5],[4., 4.5, 5.]],[[2.5, 3.5, 3.5],[4., 4.5, 5.]]]
print("tensor_four c:\n",sess.run(c)) #[[[3.,5., 4.],[3.5, 3., 4.5]],[[3.,5., 4.],[3.5, 3., 4.5]]]
print("tensor_four d:\n",sess.run(d)) #[[[3.333, 4.666],[3., 4.333]],[[3.333, 4.666],[3., 4.333]]]
四维可以理解为增加了三维图的数量(假设我们讨论的最高维度就是四维)。如上代码所示,tensor_four其实是两个tensor_three。
上面说了这是一个降维操作,所以0维度的平均值将是在第0维度方向降维。实际上就是将两张图压缩为一张图。所以它的结果将是一个tensor_three,只是其中的值是经过运算改变了(本例中并没有变,因为两张图完全一样)。
0维度的平均值:
[ [[(2 + 2)/2, (4 + 4)/2, (4 + 4)/2],[(4 + 4)/2, (6 + 6)/2, (4 + 4)/2]], [[(3 + 3)/2, (3 + 3)/2, (3 + 3)/2],[(4 + 4)/2, (3 + 3)/2, (6 + 6)/2]]]
1维和2,3维度的平均值和上面介绍的一样,只是多加了一个维度,这里不再多讲。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。