Бэкпроп через Pytorch элементную операцию, если вход содержит NaN - PullRequest
0 голосов
/ 25 июня 2019

Предположим, я хотел бы вычислить поэлементное отношение между двумя тензорами. Если один из тензоров содержит NaN, полученный коэффициент также будет содержать NaN, и это я понимаю. Но почему градиент становится несуществующим для всей операции? И как я могу сохранить градиент для не-NaN записей?

Например:

>>> x = torch.tensor([1.0, np.NaN])
>>> y = torch.tensor([2.0, 3.0])
>>> z = torch.div(y, x)
>>> z
tensor([2., nan])
>>> z.backward()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/torch/tensor.py", line 107, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/usr/local/lib/python3.6/dist-packages/torch/autograd/__init__.py", line 93, in backward
    allow_unreachable=True)  # allow_unreachable flag
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

Ответы [ 2 ]

1 голос
/ 26 июня 2019

В вашем коде много ошибок, которые я настоящим исправляю в надежде просветить вас:)

  • RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn НЕ из-за NaN.Это потому, что ни одна из ваших входных переменных не требует градиента, поэтому у z нет возможности вызвать backward().Вам нужно где-то запустить дерево обратного распространения.
  • Вы не можете просто .backward() для тензора с несколькими значениями.Сначала вам нужно набрать sum() или аналогичную операцию, но в вашем случае вы получите NaN.Вы можете распространять обе части z по отдельности, вызывая .backward(torch.Tensor([1.0,1.0])).

Поэтому, если вы исправите все ошибки, он должен работать:

import torch
import numpy as np

x = torch.tensor([1.0, np.NaN], requires_grad=True)
y = torch.tensor([2.0, 3.0])
z = torch.div(y, x)

z.backward(torch.Tensor([1.0,1.0]))
print(x.grad)
tensor([-2., nan])
0 голосов
/ 26 июня 2019

Просто небольшая настройка:

import torch
import numpy as np
x = torch.tensor([1.0, np.NaN], requires_grad=True)
y = torch.tensor([2.0, 3.0])
z = torch.div(y, x)
z #tensor([2., nan], grad_fn=<DivBackward0>)

Другими словами, вы должны сказать, что вам требуется вычисление градиента, иначе тензор будет без функции града.

...