将整数转换为二进制位的PyTorch张量

6

给定一个数字和编码长度,如何将该数字转换为其二进制表示形式的张量?

例如,给定数字 6 和宽度 8,如何获取张量:

(0, 0, 0, 0, 0, 1, 1, 0)

4个回答

17

def binary(x, bits):
    mask = 2**torch.arange(bits).to(x.device, x.dtype)
    return x.unsqueeze(-1).bitwise_and(mask).ne(0).byte()

如果您想要颠倒比特的顺序,可以使用 torch.arange(bits-1,-1,-1) 进行操作。


4
这非常优雅。 - Tom Hanks

8

Tiana的答案很好。顺便说一句,要将Tiana的2进制结果转换回10进制数字,可以按照以下方式进行:

import torch
import numpy as np


def dec2bin(x, bits):
    # mask = 2 ** torch.arange(bits).to(x.device, x.dtype)
    mask = 2 ** torch.arange(bits - 1, -1, -1).to(x.device, x.dtype)
    return x.unsqueeze(-1).bitwise_and(mask).ne(0).float()


def bin2dec(b, bits):
    mask = 2 ** torch.arange(bits - 1, -1, -1).to(b.device, b.dtype)
    return torch.sum(mask * b, -1)


if __name__ == '__main__':
    NUM_BITS = 7
    d = torch.randint(0, 16, (3, 6))
    b = dec2bin(d, NUM_BITS)
    # print(d)
    # print(b)
    # print(b.shape)
    # print("num of total bits: {}".format(np.prod(b.shape)))

    d_rec = bin2dec(b, NUM_BITS)

    # print(d_rec)
    print(abs(d - d_rec).max())  # should be 0.

为什么根据参考答案使用.float()而不是.byte() - Tom Hale
通常情况下,您可以在这里使用.byte()。我使用.float()是因为我需要将结果传递给第三方评估程序,该程序需要以float格式表示位。无论如何,所有数字仍然是01 - Tom Hanks
好答案,但实际上与十进制无关... 输入张量 'x' 已经是二进制的,该函数将其位放入单独的张量中,而不是转换其基数! - etham

0
如果输入是无符号字节,输出宽度为8位:
>>> binary = np.unpackbits(np.array([0xaa, 0xf0], dtype=np.uint8))
>>> print(torch.tensor(binary))
tensor([1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0], dtype=torch.uint8)

请注意unpackbits()仅适用于np.uint8

-1
def decimal_to_binary_tensor(value, width=0):
    string = format(value, '0{}b'.format(width))
    binary = [0 if c == '0' else 1 for c in string]
    return torch.tensor(binary, dtype=torch.uint8)

例子:

>>> print(decimal_to_binary_tensor(6, width=8))
tensor([0, 0, 0, 0, 0, 1, 1, 0], dtype=torch.uint8)

>>> print(decimal_to_binary_tensor(6))
tensor([1, 1, 0], dtype=torch.uint8)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接