TensorFlow2.0学习笔记(四)合并与分割

一、合并

1.1 概念

       合并是指将多个张量在某个维度上合并为一个张量。以某学校班级成绩册数据为例,设张量𝑨保存了某学校 1~4 号班级的成绩册,每个班级 35 个学生,共 8 门科目成绩,则张量𝑨的 shape 为 [4,35,8];同样的方式,张量𝑩保存了其它 6 个班级的成绩册,shape 为 [6,35,8]。通过合并这 2 份成绩册,便可得到学校所有班级的成绩册,记为张量𝑪,shape 应 为[10,35,8],其中,10 代表 10 个班级,35 代表 35 个学生,8 代表 8 门科目。这就是张量合并的意义所在。

1.2 实现

       张量的合并可以使用拼接(Concatenate)和堆叠(Stack)操作实现,拼接操作并不会产生新的维度,仅在现有的维度上合并,而堆叠会创建新维度。选择使用拼接还是堆叠操作来合并张量,取决于具体的场景是否需要创建新维度。

1.2.1 拼接

       拼接在 TensorFlow 中,可以通过 tf.concat(tensors, axis)函数拼接张量,其中参数tensors 保存了所有需要合并的张量 List,axis 参数指定需要合并的维度索引。 例子:

In [1]:
a = tf.random.normal([4,35,8]) # 模拟成绩册 A b = tf.random.normal([6,35,8]) # 模拟成绩册 B
tf.concat([a,b],axis=0) # 拼接合并成绩册
Out[1]:
<tf.Tensor: id=13, shape=(10, 35, 8), dtype=float32, numpy=
array([[[ 1.95299834e-01, 6.87859178e-01, -5.80048323e-01, ...,
 1.29430830e+00, 2.56610274e-01, -1.27798581e+00],
 [ 4.29753691e-01, 9.11329567e-01, -4.47975427e-01, ...,

从语法上来说,拼接合并操作可以在任意的维度上进行,唯一的约束是非合并维度的长度必须一致。比如 shape 为[4,32,8]和 shape 为[6,35,8]的张量不能直接在班级维度上进行合并,因为学生数量维度的长度并不一致,一个为 32,另一个为 35.

1.2.2 堆叠

       堆叠操作直接在现有维度上合并数据,并不会创建新的维度。如果在合并数据时,希望创建一个新的维度,则需要使用 tf.stack 操作。考虑张量𝑨保存了某个班级的成绩册,shape 为[35,8],张量𝑩保存了另一个班级的成绩册,shape 为[35,8]。合并这 2 个班级的数据时,则需要创建一个新维度,定义为班级维度,新维度可以选择放置在任意位置,一般根据大小维度的经验法则,将较大概念的班级维度放置在学生维度之前,则合并后的张量的新 shape 应为[2,35,8]。

       使用 tf.stack(tensors, axis)可以堆叠方式合并多个张量,通过 tensors 列表表示,参数axis 指定新维度插入的位置,axis 的用法与 tf.expand_dims 的一致,当axis ≥ 0时,在 axis之前插入;当axis < 0时,在 axis 之后插入新维度。例如:

In [4]:
a = tf.random.normal([35,8])
b = tf.random.normal([35,8])
tf.stack([a,b],axis=0) # 堆叠合并为 2 个班级,班级维度插入在最前
Out[4]:
<tf.Tensor: id=55, shape=(2, 35, 8), dtype=float32, numpy=
array([[[ 3.68728966e-01, -8.54765773e-01, -4.77824420e-01,
 -3.83714020e-01, -1.73216307e+00, 2.03872994e-02,
 2.63810277e+00, -1.12998331e+00],

       tf.stack 也需要满足张量堆叠合并条件,它需要所有待合并的张量 shape 完全一致才可合并

二、分割

2.1 概念

       合并操作的逆过程就是分割,将一个张量分拆为多个张量。继续考虑成绩册的例子,我们得到整个学校的成绩册张量,shape 为[10,35,8],现在需要将数据在班级维度切割为10 个张量,每个张量保存了对应班级的成绩册数据。

2.2 实现

2.2.1 tf.split

       通过 tf.split(x, num_or_size_splits, axis)可以完成张量的分割操作,参数意义如下:

❑ x 参数:待分割张量。

❑ num_or_size_splits 参数:切割方案。当 num_or_size_splits 为单个数值时,如 10,表示等长切割为 10 份;当num_or_size_splits 为 List 时,List 的每个元素表示每份的长度,如[2,4,2,2]表示切割为 4 份,每份的长度依次是 2、4、2、2。

❑ axis 参数:指定分割的维度索引号。
例子:

In [8]:
x = tf.random.normal([10,35,8])
# 等长切割为 10 份
result = tf.split(x, num_or_size_splits=10, axis=0)
len(result) # 返回的列表为 10 个张量的列表
Out[8]: 10

2.2.2 tf.unstack

       如果希望在某个维度上全部按长度为 1 的方式分割,还可以使用 tf.unstack(x,axis)函数。这种方式是 tf.split 的一种特殊情况,切割长度固定为 1,只需要指定切割维度的索引号即可。

In [11]: x = tf.random.normal([10,35,8])
result = tf.unstack(x,axis=0) # Unstack 为长度为 1 的张量
len(result) # 返回 10 个张量的列表
Out[11]: 10
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值