In the following example I have a Tensor with the Dimensions CxWxH with C = 3, W = 2 and H = 2. So I follow the dimensions as an example conv2d is doing. In my later implementation C can be arbitrary value depending on a count of BBoxes in a LabelImage. What I want to achieve is that I reduce the C to 1 by the following set of rules:
If index_C == 0 Any Value above zero should be at its same W and H coordinates in the target tensor.
Else Continue with the next index_C and repeat the previous step until the last index_C.
If still zero values present put them into the target tensor in the same W and H coordinates.
Example
>>>A = torch.tensor(
[[[0, 1],
[0, 1]],
[[0, 0],
[2, 2]],
[[0, 0],
[1, 0]]]
)
>>>A.shape
torch.Size([3, 2, 2])
with a Target which looks like the following:
T = torch.tensor(
[[0,1],
[2,1]]
)
I already achieved this by using the apply_along_axis
method and a for loop, but I want to get rid of the loop with broadcasting and vectorization methods.
I achieved so far the following:
With a broadcasting check against 0 I got a True False Tensor:
>>>B = A > 0
>>>B
tensor(
[[[False, True],
[False, True]],
[[False, False],
[ True, True]],
[[False, False],
[ True, False]]]
)
which I when used to get the argmax
index which brings me relative close to my goal:
>>> C = B.long().argmax(axis=0)
>>>C
tensor([[0, 0],
[1, 0]])
So what I now only need is a one hot encoding for the indexes. I know that the implementation of Tensorflow assists using the axis
argument in their one_hot
implementation. So the issue now is the following if I use the one_hot
functional implementation I end up with the following:
>>>import torch.nn.functional as F
>>> F.one_hot(C,3)
tensor([[[1, 0, 0],
[1, 0, 0]],
[[0, 1, 0],
[1, 0, 0]]])
But what I actually needed looks like this:
tensor(
[[[0, 1],
[0, 1]],
[[0, 0],
[2, 0]],
[[0, 0],
[0, 0]]]
)
So it has the same shape as A
.
Any Hint how to achieve it without Tensorflow? Our Tensorflow guy implemented it already.