7

I would like to mask every other value along a particular dimension of a Tensor but don't see a good way to generate such a mask. For example

#Masking on the 2nd dimension
a = [[1,2,3,4,5],[6,7,8,9,0]
mask = [[1,0,1,0,1],[1,1,1,1,1]]
b = a * mask #would return [[1,0,3,0,5],[6,0,8,0,0]]

Is there an easy way to generate such a mask?

Ideally I would like to do something like the following:

mask = tf.ones_like(input_tensor)
mask[:,::2] = 0
mask * input_tensor

But slice assigning doesn't seem to be as simple as in Numpy.

Markus Woodson
  • 73
  • 1
  • 1
  • 4

3 Answers3

4

Currently, Tensorflow does not support numpy-like assignment.

Here is a couple of workarounds:

tf.Variable

tf.Tensor cannot be changed, but tf.Variable can.

a = tf.constant([[1,2,3,4,5],[6,7,8,9,10]])

mask = tf.Variable(tf.ones_like(a, dtype=tf.int32))
mask = mask[0,1::2]
mask = tf.assign(mask, tf.zeros_like(mask))
# mask = [[1,0,1,0,1],[1,1,1,1,1]]

tf.InteractiveSession()
tf.global_variables_initializer().run()
print(mask.eval())

tf.sparse_to_dense()

indices = tf.range(1, 5, 2)
indices = tf.stack([tf.zeros_like(indices), indices], axis=1)
# indices = [[0,1],[0,3]]
mask = tf.sparse_to_dense(indices, a.shape, sparse_values=0, default_value=1)
# mask = [[1,0,1,0,1],[1,1,1,1,1]]

tf.InteractiveSession()
print(mask.eval())
AlexP
  • 1,416
  • 1
  • 19
  • 26
2

There's a more efficient solution, but this will certainly get the job done

myshape = myTensor.shape
# create tensors of your tensor's indices:
row_idx, col_idx = tf.meshgrid(tf.range(myshape[0]), tf.range(myshape[1]), indexing='ij')
# create boolean mask of odd numbered columns on a particular row.
mask = tf.where((row_idx == N) * (col_idx % 2 == 0), False, True)

masked = tf.boolean_mask(myTensor, mask)

in general you can adapt this method for any such index-based masks, and to rank-n tensors

sturgemeister
  • 436
  • 3
  • 9
1

You can easily programmatically create such a tensor mask using python. Then convert it to a tensor. There's no such support in the TensorFlow API. tf.tile([1,0], num_of_repeats) might be a fast way to create such mask but not that great either if you have odd number of columns.

(Btw, if you end up creating a boolean mask, use tf.boolean_mask())

David Wong
  • 748
  • 3
  • 6
  • I can guaruntee in my case that the dimension I want to mask has an even number of elements so this works perfectly. Thanks! – Markus Woodson Nov 06 '16 at 03:09
  • 5
    I don't think tf.boolean_mask() preserves the dimensions of the original tensor. It rather returns the non-masked elements in 1-d shape. – Rajarshee Mitra May 23 '17 at 08:17