tensorflow tutorial给出的示例显示可以创建掩码:
tf.sequence_mask([1, 3, 2], 5) # [[True, False, False, False, False],
# [True, True, True, False, False],
# [True, True, False, False, False]]
如果我想根据批次的值创建动态遮罩怎么办?如果我的输入是[[1,0,2,3,4],[2,3,4,4,4],[2,3,4,5,4]],我想掩饰一切直到前4个为真,前4个之后的所有内容都为假,结果掩码应为:
[[True, True, True, True, True],
[True, True, True, False, False],
[True, True, True, False, False]]
我正在尝试将此作为权重应用于我的sequence_loss张量
答案 0 :(得分:3)
import tensorflow as tf
x = tf.constant([[1, 0, 2, 3, 4], [2, 3, 4, 4, 4], [2, 3, 4, 5, 4]])
cond = tf.cast(tf.equal(x, 4), tf.int8)
idx4_ = tf.reshape(tf.argmax(cond, axis=1, output_type=tf.int32), (-1,1))
如果所有行至少有一个等于4的值,则为可选:
idx4 = tf.where(
tf.equal(tf.reduce_max(cond, axis=1, keep_dims=True), 1),
idx4_,
tf.constant(-1, shape=idx4_.shape)
)
通过将前4个索引与1d范围索引进行比较来创建掩码:
mask = idx4 >= tf.range(x.shape[1])
with tf.Session() as sess:
print(sess.run(mask))
#[[ True True True True True]
# [ True True True False False]
# [ True True True False False]]
或使用sequence_mask
:
import tensorflow as tf
x = tf.constant([[1, 0, 2, 3, 4], [2, 3, 4, 4, 4], [2, 3, 4, 5, 4]])
cond = tf.cast(tf.equal(x, 4), tf.int8)
idx4_ = tf.argmax(cond, axis=1, output_type=tf.int32)
idx4 = tf.where(
tf.equal(tf.reduce_max(cond, axis=1), 1),
idx4_,
tf.constant(-1, shape=idx4_.shape)
)
with tf.Session() as sess:
print(sess.run(tf.sequence_mask(idx4+1, x.shape[1])))
#[[ True True True True True]
# [ True True True False False]
# [ True True True False False]]
如果x是预先形状未知的占位符:
import tensorflow as tf
x = tf.placeholder(tf.int32, shape=[None,None])
cond = tf.cast(tf.equal(x, 4), tf.int8)
idx4_ = tf.argmax(cond, axis=1, output_type=tf.int32)
idx4 = tf.where(
tf.equal(tf.reduce_max(cond, axis=1), 1),
idx4_,
tf.fill(tf.shape(idx4_), -1)
)
mask = tf.sequence_mask(idx4+1, tf.shape(x)[-1])
with tf.Session() as sess:
print(sess.run(mask, {x: [[1, 0, 2, 3, 4], [2, 3, 4, 4, 4], [2, 3, 4, 5, 4]]}))
#[[ True True True True True]
# [ True True True False False]
# [ True True True False False]]