Можем ли мы использовать Pytorch Scatter_ на GPU - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь выполнить одно горячее кодирование для некоторых данных с помощью pyTorch в режиме графического процессора, однако это продолжает давать мне исключение.Кто-нибудь может мне помочь?

Вот один пример:

def char_OneHotEncoding(x):
    coded = torch.zeros(x.shape[0], x.shape[1], 101)
    for i in range(x.shape[1]):
        coded[:,i] = scatter(x[:,i])
    return coded


def scatter(x):
    return torch.zeros(x.shape[0], 101).scatter_(1, x.view(-1,1), 1)

Так что, если я дам ему тензор на GPU, он будет выглядеть так:

x_train = [[ 0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0],
       [14, 13, 83, 18, 14],
       [ 0,  0,  0,  0,  0]]
print(char_OneHotEncoding(torch.tensor(x_train, dtype=torch.long).cuda()).shape)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-62-95c0c4ade406> in <module>()
      4        [14, 13, 83, 18, 14],
      5        [ 0,  0,  0,  0,  0]]
----> 6 print(char_OneHotEncoding(torch.tensor(x_train, dtype=torch.long).cuda()).shape)
      7 x_train[:5, maxlen:maxlen+5]

<ipython-input-53-055f1bf71306> in char_OneHotEncoding(x)
      2     coded = torch.zeros(x.shape[0], x.shape[1], 101)
      3     for i in range(x.shape[1]):
----> 4         coded[:,i] = scatter(x[:,i])
      5     return coded
      6 

<ipython-input-53-055f1bf71306> in scatter(x)
      7 
      8 def scatter(x):
----> 9     return torch.zeros(x.shape[0], 101).scatter_(1, x.view(-1,1), 1)

RuntimeError: Expected object of backend CPU but got backend CUDA for argument #3 'index'

Кстати, если мы просто удалим .cuda() здесь, все пойдет хорошо

print(char_OneHotEncoding(torch.tensor(x_train, dtype=torch.long)).shape)
torch.Size([5, 5, 101])

1 Ответ

0 голосов
/ 01 февраля 2019

Да, это возможно.Обращаем ваше внимание, что все тензоры на GPU.В частности, по умолчанию такие конструкторы, как torch.zeros, выделяются на CPU, что приведет к такого рода несоответствиям.Ваш код может быть исправлен путем построения с помощью device=x.device, как показано ниже

import torch

 def char_OneHotEncoding(x):
     coded = torch.zeros(x.shape[0], x.shape[1], 101, device=x.device)
     for i in range(x.shape[1]):
         coded[:,i] = scatter(x[:,i])
     return coded


 def scatter(x):
     return torch.zeros(x.shape[0], 101, device=x.device).scatter_(1, x.view(-1,1), 1)

 x_train = torch.tensor([
     [ 0,  0,  0,  0,  0],
     [ 0,  0,  0,  0,  0],
     [ 0,  0,  0,  0,  0],
     [14, 13, 83, 18, 14],
     [ 0,  0,  0,  0,  0]
 ], dtype=torch.long, device='cuda')

 print(char_OneHotEncoding(x_train).shape)

Другой альтернативой являются конструкторы с именем xxx_like, например zeros_like, хотя в этом случае, так каквам нужны формы, отличные от x, я нашел device=x.device более читабельным.

...