TensorFlow:合并与分割

一、合并

合并是指将多个张量在某个维度上合并为一个张量。
以某学校班级成绩册数据为例,设张量A 保存了某学校1-4 号班级的成绩册,每个班级35 个学生,共8 门科目,则张量A的shape 为:[4,35,8];同样的方式,张量B 保存了剩下的6 个班级的成绩册,shape 为[6,35,8]。通过合并2 个成绩册,便可得到学校所有班级的成绩册张量C,shape 应为[10,35,8]。
这就是张量合并的意义所在。

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

1. 拼接

在TensorFlow 中,可以通过tf.concat(tensors, axis),其中tensors 保存了所有需要合并的张量List,axis 指定需要合并的维度。

回到上面的例子,这里班级维度索引号为0,即axis=0,合并张量A,B 如下:
TensorFlow:合并与分割
除了可以在班级维度上进行合并,还可以在其他维度上合并张量。考虑张量A 保存了所有班级所有学生的前4 门科目成绩,shape 为[10,5,4],张量B 保存了剩下的4 门科目成绩,shape 为[10,5,4],则可以合并shape 为[10,5,8]的总成绩册张量:
TensorFlow:合并与分割
合并操作可以在任意的维度上进行,唯一的约束是非合并维度的长度必须一致

2. 堆叠

tf.concat 直接在现有维度上面合并数据,并不会创建新的维度。
如果在合并数据时,希望创建一个新的维度,则需要使用tf.stack 操作

考虑张量A 保存了某个班级的成绩册,shape 为[35,8],张量B 保存了另一个班级的成绩册,shape 为[35,8]。合并这2 个班级的数据时,需要创建一个新维度,定义为班级维度,新维度可以选择放置在任意位置,一般根据大小维度的经验法则,将较大概念的班级维度放置在学生维度之前,则合并后的张量的新shape 应为[2,35,8]。

使用 tf.stack(tensors, axis)可以合并多个张量tensors,其中axis 指定插入新维度的位置,axis 的用法与tf.expand_dims 的一致,当axis ≥ 0时,在axis 之前插入;当axis < 0时,在axis 之后插入新维度。例如shape 为[????, ????, ℎ, ????]的张量,在不同位置通过stack 操作插入新维度,axis 参数对应的插入位置设置如图
TensorFlow:合并与分割
TensorFlow:合并与分割

二、分割

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

通过 tf.split(x, axis, num_or_size_splits)可以完成张量的分割操作,其中
x:待分割张量
axis:分割的维度索引号
num_or_size_splits:切割方案。当num_or_size_splits 为单个数值时,如10,表示切割为10 份;当num_or_size_splits 为List 时,每个元素表示每份的长度,如[2,4,2,2]表示切割为4 份,每份的长度分别为2,4,2,2
TensorFlow:合并与分割
还可以进行不定长切割比如这里将 x 切割为 2 份,每份长度为[1,2]TensorFlow:合并与分割