Изменение размера тензора PyTorch с постепенным уменьшением размера - PullRequest
3 голосов
/ 13 марта 2020

Я пытаюсь уменьшить тензор, скажем, с (3,3) до (1, 1), но я хочу сохранить исходный тензор:

import torch

a = torch.rand(3, 3)
a_copy = a.clone()
a_copy.resize_(1, 1)

Мне нужно requires_grad=True в моем исходном тензоре, но PyTorch запрещает мне изменять размер копии:

a = torch.rand(3, 3, requires_grad=True)
a_copy = a.clone()
a_copy.resize_(1, 1)

Выдает ошибку:

Traceback (most recent call last):
  File "pytorch_test.py", line 7, in <module>
    a_copy.resize_(1, 1)
RuntimeError: cannot resize variables that require grad

Клонировать и отсоединить

Я пытался .clone() и .detach() а также:

a = torch.rand(3, 3, requires_grad=True)
a_copy = a.clone().detach()

with torch.no_grad():
    a_copy.resize_(1, 1)

, который вместо этого выдает эту ошибку:

Traceback (most recent call last):
  File "pytorch_test.py", line 14, in <module>
    a_copy.resize_(1, 1)
RuntimeError: set_sizes_contiguous is not allowed on a Tensor created from .data or .detach().
If your intent is to change the metadata of a Tensor (such as sizes / strides / storage / storage_offset)
without autograd tracking the change, remove the .data / .detach() call and wrap the change in a `with torch.no_grad():` block.
For example, change:
    x.data.set_(y)
to:
    with torch.no_grad():
        x.set_(y)

Такое поведение было указано в документах и # 15070 .

С no_grad()

Итак, следуя тому, что они сказали в сообщении об ошибке, я удалил .detach() и вместо него использовал no_grad():

a = torch.rand(3, 3, requires_grad=True)
a_copy = a.clone()

with torch.no_grad():
    a_copy.resize_(1, 1)

Но все равно выдает ошибку об grad:

Traceback (most recent call last):
  File "pytorch_test.py", line 21, in <module>
    a_copy.resize_(1, 1)
RuntimeError: cannot resize variables that require grad

Подобные вопросы

Я смотрел на Изменить размер PyTorch Tensor , но в этом примере этот тензор сохраняет все оригинальные ценности. Я также посмотрел на Pytorch предпочтительный способ копирования тензора , который я использую для копирования тензора.

Я использую PyTorch версии 1.4.0

1 Ответ

0 голосов
/ 13 марта 2020

Я думаю, что вы должны сначала отсоединить, а затем клонировать:

a = torch.rand(3, 3, requires_grad=True)
a_copy = a.detach().clone()
a_copy.resize_(1, 1)

Примечание: a.detach() возвращает новый тензор, отсоединенный от текущего графика (он не отсоединяется a сам по графику, как a.detach_()). Но поскольку он совместно использует хранилище с a, вы также должны его клонировать. Таким образом, все, что вы делаете с a_copy, не повлияет на a. Однако я не уверен, почему a.detach().clone() работает, но a.clone().detach() выдает ошибку.

Редактировать :

Следующий код также работает (что, вероятно, является лучшим решением) :

a = torch.rand(3, 3, requires_grad=True)

with torch.no_grad():
    a_copy = a.clone()
    a_copy.resize_(1, 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...