Что означает суффикс подчеркивания в функциях PyTorch? - PullRequest
0 голосов
/ 22 октября 2018

В PyTorch существует много методов тензора в двух версиях - один с суффиксом подчеркивания и один без.Если я опробую их, они, кажется, делают то же самое:

In [1]: import torch

In [2]: a = torch.tensor([2, 4, 6])

In [3]: a.add(10)
Out[3]: tensor([12, 14, 16])

In [4]: a.add_(10)
Out[4]: tensor([12, 14, 16])

В чем разница между

  • torch.add и torch.add_
  • torch.sub и torch.sub_
  • ... и так далее?

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Вы уже ответили на свой вопрос, что подчеркивание указывает на операции на месте в PyTorch.Однако я хочу кратко указать, почему операции на месте могут быть проблематичными:

  • Прежде всего на сайтах PyTorch рекомендуется не использовать на местеоперации в большинстве случаев.Если не работать под сильным давлением памяти, более эффективно в большинстве случаев не использует операции на месте .
    https://pytorch.org/docs/stable/notes/autograd.html#in-place-operations-with-autograd

  • Во-вторых, естьМогут возникнуть проблемы с вычислением градиентов при использовании операций на месте:

    Каждый тензор сохраняет счетчик версий, который увеличивается каждый раз, когда он помечается как грязный в любой операции.Когда функция сохраняет какие-либо тензоры для обратного, также сохраняется счетчик версий содержащего их тензора.Как только вы получаете доступ к self.saved_tensors, оно проверяется, и если оно больше, чем сохраненное значение, возникает ошибка.Это гарантирует, что если вы используете функции на месте и не видите никаких ошибок, вы можете быть уверены, что вычисленные градиенты верны. Тот же источник, что и выше.

Вот пример и немного измененный пример, взятый из опубликованного вами ответа:

Первая версия на месте:

import torch
a = torch.tensor([2, 4, 6], requires_grad=True, dtype=torch.float)
adding_tensor = torch.rand(3)
b = a.add_(adding_tensor)
c = torch.sum(b)
c.backward()
print(c.grad_fn)

Что приводит к этой ошибке:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-27-c38b252ffe5f> in <module>
      2 a = torch.tensor([2, 4, 6], requires_grad=True, dtype=torch.float)
      3 adding_tensor = torch.rand(3)
----> 4 b = a.add_(adding_tensor)
      5 c = torch.sum(b)
      6 c.backward()

RuntimeError: a leaf Variable that requires grad has been used in an in-place operation.

Во-вторых, не на месте версия:

import torch
a = torch.tensor([2, 4, 6], requires_grad=True, dtype=torch.float)
adding_tensor = torch.rand(3)
b = a.add(adding_tensor)
c = torch.sum(b)
c.backward()
print(c.grad_fn)

Что работаетпросто отлично - вывод:

<SumBackward0 object at 0x7f06b27a1da0>

Так что в качестве отрывка я просто хотел указать на осторожное использование операций на месте в PyTorch.

0 голосов
/ 22 октября 2018

Согласно документации , методы, заканчивающиеся подчеркиванием, изменяют тензор на месте .Это означает, что при выполнении операции не выделяется никакой новой памяти, что в целом повышает производительность , но может привести к проблемам и ухудшению производительности вPyTorch .

In [2]: a = torch.tensor([2, 4, 6])

тензор.адд () :

In [3]: b = a.add(10)

In [4]: a is b
Out[4]: False # b is a new tensor, new memory was allocated

тензор._адд () :

In [3]: b = a.add_(10)

In [4]: a is b
Out[4]: True # Same object, no new memory was allocated

Обратите внимание, что операторы + и += также являются двумя различными реализациями .+ создает новый тензор с помощью .add(), а += изменяет тензор с помощью .add_()

In [2]: a = torch.tensor([2, 4, 6])

In [3]: id(a)
Out[3]: 140250660654104

In [4]: a += 10

In [5]: id(a)
Out[5]: 140250660654104 # Still the same object, no memory allocation was required

In [6]: a = a + 10

In [7]: id(a)
Out[7]: 140250649668272 # New object was created
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...