TensorFlow中不同形状张量沿axis=0拼接的实现疑问
嘿,作为TensorFlow新手碰到张量拼接的问题太正常了,我来帮你理清楚~
首先明确回答你的核心问题:是可以沿axis=0拼接得到形状为(60000, None, 1)的Ragged张量的,但你之前的方法可能有小细节没注意到,或者对结果的预期需要再明确。
为什么普通密集张量不能这么拼?
对于普通的密集张量(非Ragged),tf.concat有个硬性要求:除了要拼接的轴之外,其他所有维度必须完全匹配。你想沿axis=0拼接,那axis=1和axis=2的维度必须相同,但你的张量a的axis=1是943,b的是260,不匹配,所以直接用普通张量拼接会报错——这也是你尝试Ragged张量的方向是对的。
你之前的Ragged张量写法问题在哪?
你用tf.ragged.constant(a)把密集张量转成Ragged张量是可行的,但要注意:当你把形状为(30000,943,1)的密集张量转成Ragged张量时,它的行长度(axis=1)是固定的943,同理b转成后行长度是260。这时候执行tf.concat([a2, b2], axis=0)理论上是可以得到形状为(60000, None, 1)的Ragged张量的——前30000个元素的axis=1长度是943,后30000个是260。
你说“该方法并未奏效”,可能是遇到了报错?或者对结果的形状有误解?比如你是不是以为axis=1会合并成某个固定值?如果是这样的话那确实不行,因为943和260是不同的长度,只能用Ragged张量来保存这种变长的维度。
正确的Ragged张量拼接代码
这里给你一个完整的可运行示例:
import tensorflow as tf # 模拟你的两个张量 a = tf.random.uniform((30000, 943, 1), dtype=tf.float64) b = tf.random.uniform((30000, 260, 1), dtype=tf.float64) # 转换为Ragged张量(两种写法都可以,这里用更明确的from_tensor) a_ragged = tf.RaggedTensor.from_tensor(a) b_ragged = tf.RaggedTensor.from_tensor(b) # 沿axis=0拼接 c = tf.concat([a_ragged, b_ragged], axis=0) print(c.shape) # 输出: (60000, None, 1)
额外的备选方案
如果你下游任务必须用密集张量(不能用Ragged),那可以把较短的张量在axis=1维度上补零到较长的长度,再拼接:
# 把b的axis=1补零到943的长度 b_padded = tf.pad(b, [[0, 0], [0, 943 - 260], [0, 0]]) # 沿axis=0拼接得到密集张量 c_dense = tf.concat([a, b_padded], axis=0) print(c_dense.shape) # 输出: (60000, 943, 1)
另外,我也多提一句:如果你其实是想把两个张量在特征维度(axis=1)拼接,那直接用普通的tf.concat就行,因为axis=0和axis=2的维度都匹配,结果会是(30000, 1203, 1)的密集张量:
c_axis1 = tf.concat([a, b], axis=1) print(c_axis1.shape) # 输出: (30000, 1203, 1)
内容的提问来源于stack exchange,提问作者gineco

