How to mask/threshod a tensor

I have a tensor of size BxCxHxW
i want to mask the values in each channel as if they are larger than 0.25*mean of that channel the value be 1 and if they are lower than that the value be 0.
How we can do it fast in pytorch?

Thanks a lot in advance :slight_smile:

1 Like

Assuming you would like to create a mask of shape [B, C], would this work?

B, C, H, W = 10, 3, 4, 4
x = torch.randn(B, C, H, W)
y = torch.where(x > x.view(B, C, -1).mean(2)[:, :, None, None], torch.tensor([1.]), torch.tensor([0.]))
10 Likes

Yes :slight_smile: that is working great!! :tada::pray:t2::+1:t2:

but i have two questions,

can you explain this part of your code: x.view(B, C, -1).mean(2)[:, :, None, None], I mean why did you use โ€˜Noneโ€™?

Also do you know another way to do without using torch.where ? for this project im using pytorch 0.3 and it does not have the where function

Great!

Iโ€™ve used None to unsqueeze the tensor. Alternatively, you could use .mean(2).unsqueeze(2).unsqueeze(3), but I prefer to use this notation if I need to add more than one dimension.
In older versions this will probably work:

z = x.clone()
z[x > x.view(B, C, -1).mean(2)[:, :, None, None]] = 1.
z[x <= x.view(B, C, -1).mean(2)[:, :, None, None]] = 0.

Iโ€™ve compared it to the first solution and it yields the same result.

1 Like

@ptrblck
Sorry for coming back, I faced an error on your last answer for old version of pytorch (0.3.0)
so it works when i test, but when my input is [torch.cuda.FloatTensor of size 1x1024x50x89 (GPU 0)] it trowed me an error that *** AssertionError: MaskedFill can't differentiate the mask and i had to change the lst two lines to:

       z = (x > x.view(B, C, -1).mean(2)[:, :, None, None]).float()
       z = (x <= x.view(B, C, -1).mean(2)[:, :, None, None]).float()