广播和连接参差不齐的张量

Jul*_*tor 5 python concatenation ragged tensorflow ragged-tensors

我有一个参差不齐的尺寸张量[BATCH_SIZE, TIME_STEPS, EMBEDDING_DIM]。我想用来自另一个 shape 张量的数据来扩充最后一个轴[BATCH_SIZE, AUG_DIM]。给定示例的每个时间步都增加了相同的值。

如果张量没有TIME_STEPS因每个示例的变化而参差不齐,我可以简单地重塑第二个张量,tf.repeat然后使用tf.concat

import tensorflow as tf


# create data
# shape: [BATCH_SIZE, TIME_STEPS, EMBEDDING_DIM]
emb = tf.constant([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [0, 0, 0]]])
# shape: [BATCH_SIZE, 1, AUG_DIM]
aug = tf.constant([[[8]], [[9]]])

# concat
aug = tf.repeat(aug, emb.shape[1], axis=1)
emb_aug = tf.concat([emb, aug], axis=-1)
Run Code Online (Sandbox Code Playgroud)

这在参差不齐时不起作用,emb因为它emb.shape[1]是未知的并且因示例而异:

# rag and remove padding
emb = tf.RaggedTensor.from_tensor(emb, padding=(0, 0, 0))

# reshape for augmentation - this doesn't work
aug = tf.repeat(aug, emb.shape[1], axis=1)
Run Code Online (Sandbox Code Playgroud)

ValueError: 尝试将具有不受支持类型 (<class 'NoneType'>) 的值 (None) 转换为张量。

目标是创建一个emb_aug看起来像这样的参差不齐的张量:

<tf.RaggedTensor [[[1, 2, 3, 8], [4, 5, 6, 8]], [[1, 2, 3 ,9]]]>
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

gob*_*s14 3

最简单的方法是通过使用使不规则张量成为常规张量tf.RaggedTensor.to_tensor(),然后执行其余的解决方案。我假设你需要张量保持不规则。关键是找到row_lengths您的不规则张量中每个批次的 ,然后使用此信息使您的增强张量变得不规则。

例子

import tensorflow as tf


# data
emb = tf.constant([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [0, 0, 0]]])
aug = tf.constant([[[8]], [[9]]])

# make embeddings ragged for testing
emb_r = tf.RaggedTensor.from_tensor(emb, padding=(0, 0, 0))

print(emb_r.shape)
# (2, None, 3)
Run Code Online (Sandbox Code Playgroud)

row_lengths在这里,我们将使用和的组合sequence_mask来创建一个新的不规则张量。

# find the row lengths of the embeddings
rl = emb_r.row_lengths()

print(rl)
# tf.Tensor([2 1], shape=(2,), dtype=int64)

# find the biggest row length
max_rl = tf.math.reduce_max(rl)

print(max_rl)
# tf.Tensor(2, shape=(), dtype=int64)

# repeat the augmented data `max_rl` number of times
aug_t = tf.repeat(aug, repeats=max_rl, axis=1)

print(aug_t)
# tf.Tensor(
# [[[8]
#   [8]]
# 
#  [[9]
#   [9]]], shape=(2, 2, 1), dtype=int32)

# create a mask
msk = tf.sequence_mask(rl)

print(msk)
# tf.Tensor(
# [[ True  True]
#  [ True False]], shape=(2, 2), dtype=bool)
Run Code Online (Sandbox Code Playgroud)

从这里我们可以使用tf.ragged.boolean_mask使增强数据变得不规则

# make the augmented data a ragged tensor
aug_r = tf.ragged.boolean_mask(aug_t, msk)
print(aug_r)
# <tf.RaggedTensor [[[8], [8]], [[9]]]>

# concatenate!
output = tf.concat([emb_r, aug_r], 2)
print(output)
# <tf.RaggedTensor [[[1, 2, 3, 8], [4, 5, 6, 8]], [[1, 2, 3, 9]]]>
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到支持不规则张量的张量流方法列表