PyTorch是否等效于numpy.unpackbits?

时间:2019-09-10 12:55:00

标签: pytorch

我正在训练GPU上的神经网络。它使用了很多二进制输入功能。

由于将数据移至GPU或从GPU移出数据非常昂贵,因此我正在寻找使初始表示更为紧凑的方法。现在,我将功能编码为 int8 ,将其移至GPU上,然后然后展开为 float32

# create int8
features = torch.zeros(*dims, dtype=torch.int8)

# fill in some data (set some features to 1.)
…

# move int8 to GPU
features = features.to(device=cuda, non_blocking=True)

# expand int8 as float32
features = features.to(dtype=float32)

现在,我正在寻找将这些二进制特征压缩为位而不是字节的方法。

NumPy具有函数http://192.168.0.4:9200/http://192.168.0.4:9200/

>>> a = np.array([[2], [7], [23]], dtype=np.uint8)
>>> b = np.unpackbits(a, axis=1)
>>> b
array([[0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)

有什么方法可以解压缩GPU上的PyTorch中的位?

2 个答案:

答案 0 :(得分:1)

在编写此答案时,没有类似的功能。但是,一种解决方法是使用torch.from_numpy,如下所示:

In[2]: import numpy as np
In[3]: a = np.array([[2], [7], [23]], dtype=np.uint8)
In[4]: b = np.unpackbits(a, axis=1)
In[5]: b
Out[5]: 
array([[0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
In[6]: import torch
In[7]: torch.from_numpy(b)
Out[7]: 
tensor([[0, 0, 0, 0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0, 1, 1, 1],
        [0, 0, 0, 1, 0, 1, 1, 1]], dtype=torch.uint8)

答案 1 :(得分:1)

您可以使用DLPack将Pytorch张量转换为CuPy数组,然后使用cupy.unpackbits

import cupy
import torch

from torch.utils.dlpack import to_dlpack
from torch.utils.dlpack import from_dlpack

# Create a PyTorch tensor.
tx = torch.cuda.ByteTensor([1, 2, 3, 4])

# Convert it into a DLPack tensor.
dx = to_dlpack(tx)

# Convert it into a CuPy array.
cx = cupy.fromDlpack(dx)

# Unpack bits (does not support axis, so flatten/reshape as needed)
cx_bits = cupy.unpackbits(cx).reshape(-1, 8)

# Convert it back to a PyTorch tensor.
tx_bits = from_dlpack(cx_bits.toDlpack())

更新:我实际上不确定DLPack是否必要:

>>> t = torch.cuda.ByteTensor([[2], [22], [222]])
>>> t_bits = torch.as_tensor(cupy.unpackbits(cupy.asarray(t)).reshape(-1, 8), device="cuda")
>>>
>>> t_bits
tensor([[0, 0, 0, 0, 0, 0, 1, 0],
        [0, 0, 0, 1, 0, 1, 1, 0],
        [1, 1, 0, 1, 1, 1, 1, 0]], device='cuda:0', dtype=torch.uint8)