Есть ли эффективный способ создать случайную битовую маску в Pytorch?


Я хочу иметь случайную битовую маску, которая имеет некоторый определенный процент 0s. функция, которую я разработал, такова:

def create_mask(shape, rate):
    """
    The idea is, you take a random permutations of numbers. You then mod then
    mod it by the [number of entries in the bitmask] / [percent of 0s you
    want]. The number of zeros will be exactly the rate of zeros need. You
    can clamp the values for a bitmask.
    """
    mask = torch.randperm(reduce(operator.mul, shape, 1)).float().cuda()
    # Mod it by the percent to get an even dist of 0s.
    mask = torch.fmod(mask, reduce(operator.mul, shape, 1) / rate)
    # Anything not zero should be put to 1
    mask = torch.clamp(mask, 0, 1)
    return mask.view(shape)

Для иллюстрации:

>>> x = create_mask((10, 10), 10)
>>> x

    1     1     1     1     1     1     1     1     1     1
    1     1     1     1     1     1     0     1     1     1
    0     1     1     1     1     0     1     1     1     1
    0     1     1     1     1     1     1     1     1     1
    1     1     1     1     1     1     1     1     1     0
    1     1     1     1     1     1     1     1     1     1
    1     1     1     0     1     1     1     0     1     1
    0     1     1     1     1     1     1     1     1     1
    1     1     1     0     1     1     0     1     1     1
    1     1     1     1     1     1     1     1     1     1
[torch.cuda.FloatTensor of size 10x10 (GPU 0)]
Основная проблема, которую я имею с этим методом, заключается в том, что он требует, чтобы rate разделил shape. Мне нужна функция, которая принимает произвольную десятичную дробь и дает приблизительно rate процентов 0s в битовой маске. Более того, я пытаюсь найти относительно эффективный способ сделать это. Следовательно, я бы предпочел не перемещать массив numpy из процессора в ГПУ. Существует ли эффективный способ сделать это, который допускает десятичную дробь rate?
2 3

2 ответа:

Для любого, кто столкнется с этим, это создаст битовую маску с приблизительно 80% нулей непосредственно на GPU. (PyTorch 0.3)

torch.cuda.FloatTensor(10, 10).uniform_() > 0.8

Используйте NumPy и cudamat:

import numpy as np
import cudamat as cm

gpuMask = cm.CUDAMatrix(np.random.choice([0, 1], size=(10,10), p=[1./2, 1./2]))

Где элементы списка являются дробными представлениями вероятностей ваших 1 и 0.