Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binary mask in Tensorflow

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.

like image 564
Markus Woodson Avatar asked Nov 05 '16 22:11

Markus Woodson


People also ask

What is TF Boolean_mask?

boolean_mask , which can be applied to both dense and ragged tensors, and can be used if you need to preserve the masked dimensions of tensor (rather than flattening them, as tf. boolean_mask does).

How do you make a boolean mask?

To create a boolean mask from an array, use the ma. make_mask() method in Python Numpy. The function can accept any sequence that is convertible to integers, or nomask. Does not require that contents must be 0s and 1s, values of 0 are interpreted as False, everything else as True.

What is padding in Tensorflow?

Padding means adding values before and after Tensor values. Method Used: tf. pad: This method accepts input tensor and padding tensor with other optional arguments and returns a Tensor with added padding and same type as input Tensor.

What is TF Ones_like?

Used in the notebooksGiven a single tensor ( tensor ), this operation returns a tensor of the same type and shape as tensor with all elements set to 1.


3 Answers

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())
like image 92
AlexP Avatar answered Oct 19 '22 04:10

AlexP


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

like image 41
sturgemeister Avatar answered Oct 19 '22 04:10

sturgemeister


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())

like image 20
David Wong Avatar answered Oct 19 '22 03:10

David Wong