converting tensor to one hot encoded tensor of indices

Viewed 27848

I have my label tensor of shape (1,1,128,128,128) in which the values might range from 0,24. I want to convert this to one hot encoded tensor, using the nn.fucntional.one_hot function

n = 24
one_hot = torch.nn.functional.one_hot(indices, n)

but this expects a tensor of indices, honestly, I am not sure how to get those. The only tensor I have is the label tensor of the shape described above and it contains values ranging from 1-24, not the indices

How can I get a tensor of indices from my tensor? Thanks in advance.

3 Answers

If the error you are getting is this one:

Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
RuntimeError: one_hot is only applicable to index tensor.

Maybe you just need to convert to int64:

import torch

# random Tensor with the shape you said
indices = torch.Tensor(1, 1, 128, 128, 128).random_(1, 24)
# indices.shape => torch.Size([1, 1, 128, 128, 128])
# indices.dtype => torch.float32

n = 24
one_hot = torch.nn.functional.one_hot(indices.to(torch.int64), n)
# one_hot.shape => torch.Size([1, 1, 128, 128, 128, 24])
# one_hot.dtype => torch.int64

You can use indices.long() too.

The torch.as_tensor function can also be helpful if your labels are stored in a list or numpy array:

import torch
import random

n_classes = 5
n_samples = 10

# Create list n_samples random labels (can also be numpy array)
labels = [random.randrange(n_classes) for _ in range(n_samples)]
# Convert to torch Tensor
labels_tensor = torch.as_tensor(labels)
# Create one-hot encodings of labels
one_hot = torch.nn.functional.one_hot(labels_tensor, num_classes=n_classes)
print(one_hot)

The output one_hot has shape (n_samples, n_classes) and should look something like:

tensor([[0, 0, 0, 1, 0],
        [0, 1, 0, 0, 0],
        [0, 1, 0, 0, 0],
        [0, 0, 0, 1, 0],
        [0, 0, 0, 1, 0],
        [0, 0, 0, 1, 0],
        [1, 0, 0, 0, 0],
        [1, 0, 0, 0, 0],
        [0, 0, 0, 1, 0],
        [1, 0, 0, 0, 0]])

Usually, this issue can be solved by adding long(). for example,

import torch
import torch.nn.functional as F
labels=torch.Tensor([[0, 2, 1]])
n_classes=3
encoded=F.one_hot(labels, n_classes)

It gives an error as: RuntimeError: one_hot is only applicable to index tensor. To solve this issue, use long().

import torch
import torch.nn.functional as F
labels=torch.Tensor([[0, 2, 1]]).long()
n_classes=3
encoded=F.one_hot(labels, n_classes)

Now it would be executed without errors.

Related