tensorflow 对tensor维度的理解和操作

维度的意义

tensorflow中经常对tensor的维度和维度操作感觉特别晕,今天做一个整理。

首先tensor 的维度从外向里依次是第0维,第1维,第2维。。。。

例如

aaa = tf.constant([[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]

最外层的括号里有2个元素[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]和[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]

上面这2个元素分别有3个元素

最里面的括号中有6个元素。所以这个tensor的形状就是[2,3,6],判断一个tensor形状,只需要具体到一个元素就可以了。

获取tensor的维度

获取tensor维度有2种方法

tensor.get_shape(),这个方法返回一个tensorshape 对象。可以通过as_list() 直接转化为一个list

tf.shape(tensor)  这个方法返回一个形状的tensor,只能通过session run的方法获取其中的数值。

aaa = tf.constant([[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]
print(aaa.get_shape().as_list())
with tf.session() as sess:
    sess.run(tf.shape(aaa))

在实际使用中可以根据需要自行选取。

然后接下来就是对维度的操作。

对维度的操作,虽然非常多,倒也有规律可循。 维度操作中经常有一个必须的参数,就是对第几维进行操作,

例如

tf.reduce_sum(input,[0])

tf.tile(input,[2])

tf.concat(input,[1])

分别对第0,2,1维操作。所以有这么一个规律:

对第几维操作,第几维就会发生变化

对第几维操作,第几维就会发生变化

对第几维操作,第几维就会发生变化

这个变化有可能是维度的消失,维度长度的变化,维度的插入等。

记住这个规律,就能屡试不爽。下面来看几个命令

tf.expand_dims扩展维度

扩展维度就是在第n个维度括号的外面增加一个维度,即把第n维的变成一个元素。

如果变换之前的维度是[a,b,c ..... ] 

那么tf.expand_dims(aaa,[0])) 之后就是[1,a,b,c ..... ] 

那么tf.expand_dims(aaa,[1])) 之后就是[a,1,b,c ..... ] 

这也符合刚才的规律,对哪个维度使用expand_dims,哪个维度就会插入1维。

例如:tf.expand_dims(aaa,[0]))就是在第0维外面加一个括号

hhh = tf.expand_dims(aaa,[0])
扩展前
[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]
扩展后
【[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]】

如果扩展第一维,那么需要第1维外面加一个括号,因为第一维有2个元素,所以2个元素都要加

hhh = tf.expand_dims(aaa,[1])
扩展前
[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]
扩展后,为了方便了解,新增的维度括号用中文括号【】表示
[【[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]】,【[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]】]

tf.squeeze

去掉长度是1的维度,如果该维度长度不是1,则报错。例如

aaa = [[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]]
hhh = tf.expand_dims(aaa,[0])
结果
[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]

这也符合刚才的规律,aaaa原维度[1,2,3,6],新的维度[2,3,6],第0维度被删除。

tf.reduce_sum,tf.reduce_mean,tf.reduce_max,tf.reduce_min

这四个命令都非常类似,都是通过某种方法使维度降低,用法非常基础,就不解释了。

我们来看

aaa = tf.constant([[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]
kkk = tf.tile(aaa,[2,1,1]))
with tf.Session() as sess:
    print(sess.run(kkk))
结果
[[[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]
 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]
 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]
 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]]

原来形状维[2,3,6] ,结果的形状 [3,6] . 第0维消失了。那怎么样才能让第0维小时呢,通过对第0维的所有元素进行某种操作(例如求和,求平均,求最大,求最小)把第0维长度变成1,然后再把第0维删掉。

tf.tile(input)

把原来的tensor在某些维度上复制若干次。tile命令的参数和之前的几个命令略有不同,第二个参数是分别在每个维度复制几次。

tf.tile(input,[n1,n2,n3.....])  表示把原tensor在第0维变成原来的n1倍,第1维变成原来的n2倍....。例如

aaa = [[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]]
hhh =  tf.tile(aaa,[2,1,1])
结果
[[[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]
 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]
 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]
 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]]

在这段代码中,第0维长度变成了原来的2倍,第1维和第2维长度都无变化。所以最后的结果tensor形状是[4,3,6]。同样符合那个规律

tf.concat

2个tensor进行拼接,用法如下

tf.concat([tensor1,tensor2],axis)

要求2个拼接的tensor在拼接的维度尺寸可以不同,例如]4行9列和4行1列 [4,9] 和 [4,1] 可以在第1维进行拼接。但是非拼接的维度,形状必须相同。4行和5行的就拼不到一块

例如

aaa = [[[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]],[[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3]]]]
kkk =  tf.tile(aaa,[2,1,1])
lll = tf.concat([aaa,kkk],0)
结果
[[[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]

 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]

 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]

 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]

 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]

 [[1 1 1 1 1 1]
  [2 2 2 2 2 2]
  [3 3 3 3 3 3]]]

拼接后的形状为[6,3,6]  符合规律

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值