Обрезать SVD-декомпозицию тензора Pytorch без передачи на процессор

Я обучаю модель в Pytorch и хочу использовать усеченное SVD-разложение входных данных. Для расчета SVD я передаю входную ведьму Pytorch Cuda Tensor в ЦП и, используя TruncatedSVD из scikit-learn, выполняю усечение, после чего я передаю результат обратно в графический процессор. Ниже приведен код моей модели:

 class ImgEmb(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(ImgEmb, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.drop = nn.Dropout(0.2)
        self.mlp = nn.Linear(input_size/2, hidden_size)
        self.relu = nn.Tanh()
        self.svd = TruncatedSVD(n_components=input_size/2)

    def forward(self, input):
        svd=self.svd.fit_transform(input.cpu())
        svd_tensor=torch.from_numpy(svd)
        svd_tensor=svd_tensor.cuda()
        mlp=self.mlp(svd_tensor)
        res = self.relu(mlp)
        return res

Интересно, есть ли способ реализовать усеченный SVD без передачи туда и обратно на GPU? (Потому что это очень трудоемко и совершенно неэффективно)


person Marzi Heidari    schedule 20.09.2019    source источник


Ответы (2)


Вы можете напрямую использовать SVD PyTorch и усечь его вручную, или вы можете использовать усеченный SVD из TensorLy , с бэкэндом PyTorch:

import tensorly as tl
tl.set_backend('pytorch')

U, S, V = tl.truncated_svd(matrix, n_eigenvecs=10)

Однако GPU SVD не очень хорошо масштабируется на больших матрицах. Вы также можете использовать частичный svd TensorLy, который по-прежнему будет копировать ваш ввод в ЦП, но будет намного быстрее, если вы сохраните только несколько собственных значений, поскольку он будет использовать разреженное собственное разложение. В усеченном SVD Scikit-learn вы также можете использовать «algorithm = arpack», чтобы использовать разреженный SVD Scipy, который снова может быть быстрее, если вам нужно всего несколько компонентов.

person Jean    schedule 04.10.2019

Как преобразовать тензорный CUDA в CPU?

Если у вас есть тензор CUDA, вы можете передать его в CPU с помощью этой инструкции:

y_vel это тензор pytorch в cuda.

y_val = y_val.cpu().data.numpy()
person Wojciech Moszczyński    schedule 17.09.2020