填充和屏蔽批处理数据集
Padding and Masking a batch dataset
在表示自然语言的多个字符串时,每个字符串中的字符数可能不相等。然后,return 结果可以放在 tf.RaggedTensor
中,其中最里面维度的长度根据每个字符串中的字符数而变化:
rtensor = tf.ragged.constant([
[1, 2],
[3, 4, 5],
[6]
])
rtensor
#<tf.RaggedTensor [[1, 2], [3, 4, 5], [6]]>
反过来,应用 to_tensor
方法,将 RaggedTensor
转换为常规 tf.Tensor
,然后应用填充操作:
batch_size=3
max_length=8
tensor = rtensor.to_tensor(default_value=0, shape=(batch_size, max_length))
#<tf.Tensor: shape=(3, 8), dtype=int32, numpy=
#array([[1, 2, 0, 0, 0, 0, 0, 0],
# [3, 4, 5, 0, 0, 0, 0, 0],
# [6, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)>
现在,有没有一种方法可以生成一个附加张量来显示什么是原始数据,什么是填充?对于上面的示例,它将是:
<tf.Tensor: shape=(3, 8), dtype=int32, numpy=
array([[1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)>
正如 thusv89 所建议的,您可以简单地检查非零值。它可以像转换为布尔值和返回一样简单。
import tensorflow as tf
rtensor = tf.ragged.constant([[1, 2],
[3, 4, 5],
[6]])
batch_size = 3
max_length = 8
tensor = rtensor.to_tensor(default_value=0, shape=(batch_size, max_length))
mask = tf.dtypes.cast(tf.dtypes.cast(tensor, tf.bool), tensor.dtype)
print(mask.numpy())
# [[1 1 0 0 0 0 0 0]
# [1 1 1 0 0 0 0 0]
# [1 0 0 0 0 0 0 0]]
唯一可能的缺点是您最初可能有 0
个值。转换为张量时,您可以使用其他一些值作为默认值,例如 -1
,如果您知道您的数据总是非负的:
tensor = rtensor.to_tensor(default_value=-1, shape=(batch_size, max_length))
mask = tf.dtypes.cast(tensor >= 0, tensor.dtype)
但是如果你想让你的掩码适用于你拥有的任何值,你也可以只使用 tf.ones_like
和参差不齐的张量:
rtensor_ones = tf.ones_like(rtensor)
mask = rtensor_ones.to_tensor(default_value=0, shape=(batch_size, max_length))
这样 mask
将始终是 rtensor
具有值的地方。
在表示自然语言的多个字符串时,每个字符串中的字符数可能不相等。然后,return 结果可以放在 tf.RaggedTensor
中,其中最里面维度的长度根据每个字符串中的字符数而变化:
rtensor = tf.ragged.constant([
[1, 2],
[3, 4, 5],
[6]
])
rtensor
#<tf.RaggedTensor [[1, 2], [3, 4, 5], [6]]>
反过来,应用 to_tensor
方法,将 RaggedTensor
转换为常规 tf.Tensor
,然后应用填充操作:
batch_size=3
max_length=8
tensor = rtensor.to_tensor(default_value=0, shape=(batch_size, max_length))
#<tf.Tensor: shape=(3, 8), dtype=int32, numpy=
#array([[1, 2, 0, 0, 0, 0, 0, 0],
# [3, 4, 5, 0, 0, 0, 0, 0],
# [6, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)>
现在,有没有一种方法可以生成一个附加张量来显示什么是原始数据,什么是填充?对于上面的示例,它将是:
<tf.Tensor: shape=(3, 8), dtype=int32, numpy=
array([[1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)>
正如 thusv89 所建议的,您可以简单地检查非零值。它可以像转换为布尔值和返回一样简单。
import tensorflow as tf
rtensor = tf.ragged.constant([[1, 2],
[3, 4, 5],
[6]])
batch_size = 3
max_length = 8
tensor = rtensor.to_tensor(default_value=0, shape=(batch_size, max_length))
mask = tf.dtypes.cast(tf.dtypes.cast(tensor, tf.bool), tensor.dtype)
print(mask.numpy())
# [[1 1 0 0 0 0 0 0]
# [1 1 1 0 0 0 0 0]
# [1 0 0 0 0 0 0 0]]
唯一可能的缺点是您最初可能有 0
个值。转换为张量时,您可以使用其他一些值作为默认值,例如 -1
,如果您知道您的数据总是非负的:
tensor = rtensor.to_tensor(default_value=-1, shape=(batch_size, max_length))
mask = tf.dtypes.cast(tensor >= 0, tensor.dtype)
但是如果你想让你的掩码适用于你拥有的任何值,你也可以只使用 tf.ones_like
和参差不齐的张量:
rtensor_ones = tf.ones_like(rtensor)
mask = rtensor_ones.to_tensor(default_value=0, shape=(batch_size, max_length))
这样 mask
将始终是 rtensor
具有值的地方。