我正在训练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中的位?
答案 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)