合并: 在 TensorFlow 中,可以通过 tf.concat(tensors, axis),其中 tensors 保存了所有需要合并的张量 List,axis 指定需要合并的维度。
import tensorflow as tf
a = tf.random.normal([4, 35, 8])
b = tf.random.normal([6, 35, 8])
tf.concat([a, b], axis=0)
<tf.Tensor: id=13, shape=(10, 35, 8), dtype=float32, numpy=
array([[[-1.64263234e-01, -1.79259729e+00, 1.61177063e+00, ...,
8.25017512e-01, 4.44114864e-01, -2.21222806e+00],
[-1.15612142e-01, -2.09971237e+00, -2.11950541e+00, ...,
1.59496918e-01, 6.07065558e-01, -1.55677330e+00],
[ 2.10887380e-02, -3.84055972e-01, -3.34402353e-01, ...,
3.51098552e-02, -8.49512517e-01, -2.47136736e+00],
...,
合并操作可以在任意维度上进行,唯一的约束是非合并的长度必须一致。
**堆叠:**如果希望在合并数据时,创建一个新的维度,可以用tf.stack来操作。
使用 tf.stack(tensors, axis)可以合并多个张量 tensors,其中 axis 指定插入新维度的位置,axis 的用法与 tf.expand_dims 的一致,当axis ≥ 0时,在 axis 之前插入;当axis < 0时,在 axis 之后插入新维度。
import tensorflow as tf
a = tf.random.normal([35, 8])
b = tf.random.normal([35, 8])
tf.stack([a, b], axis=0)
<tf.Tensor: id=26, shape=(2, 35, 8), dtype=float32, numpy=
array([[[ 6.69145286e-02, -4.48833466e-01, 1.63843274e-01,
4.60673541e-01, -2.01034522e+00, 1.91229153e+00,
1.48241258e+00, -1.27161491e+00],
[ 8.87061477e-01, -3.17032218e-01, -2.00393751e-01,
-7.19009221e-01, 2.24969029e+00, -7.32503319e-03,
-1.55386770e+00, -1.33892262e+00],
tf.stack 也需要满足张量堆叠合并条件,它需要所有合并的张量 shape 完全一致才可合并。
**分割:**通过 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
当 num_or_size_splits 为单个数值时:
x = tf.random.normal([10, 35, 8])
# 等长切割
result = tf.split(x, axis=0, num_or_size_splits=10)
# 查看切割之后结果的长度
print(len(result))
# 随便查看一个
result[0]
10
<tf.Tensor: id=156, shape=(1, 35, 8), dtype=float32, numpy=
array([[[ 8.49051535e-01, 5.52066386e-01, 1.57028139e+00,
-3.69209170e-01, -5.04426241e-01, -3.87088597e-01,
2.87624687e-01, 6.86846614e-01],
当 num_or_size_splits 为列表时:
x = tf.random.normal([10,35,8])
# 自定义长度的切割
result = tf.split(x,axis=0,num_or_size_splits=[4,2,2,2])
print(len(result))
result[0]
4
<tf.Tensor: id=198, shape=(4, 35, 8), dtype=float32, numpy=
array([[[-0.13012172, -1.1784949 , 1.1862756 , ..., -1.3953975 ,
0.6226986 , 0.5008703 ],
[ 0.60076094, 0.34617507, -1.6403588 , ..., 2.349285 ,
-0.8501324 , 0.39967436],
[-0.18285574, -0.19942562, 0.36876082, ..., -1.0590581 ,
-0.69916064, -0.04942752],
特别地,如果希望在某个维度上全部按长度为 1 的方式分割,还可以直接使用 tf.unstack(x,axis)。
x = tf.random.normal([10,35,8])
result = tf.unstack(x, axis=0)
print(len(result))
result[0]
10
<tf.Tensor: id=224, shape=(35, 8), dtype=float32, numpy=
array([[-1.38168859e+00, -2.34808564e-01, 2.39532903e-01,
-3.49951059e-01, 1.78944543e-01, -2.90860087e-01,
-1.59443510e+00, 2.04688415e-01],
可以看到第一个维度消失了,拆分成了10个张量。