根据输入值

时间:2017-11-06 02:54:42

标签: python tensorflow

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张量

1 个答案:

答案 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]]