Я пытался воспроизвести ваше предупреждение, но не смог. Однако я мог бы получить такое же предупреждение, создав, если бы заменил списки в thing
тензорами.
Я go объясню, почему лучше использовать x.clone().detach()
, а не torch.tensor(x)
для сделать копию:
В моей версии pytorch использование torch.tensor
будет работать для создания копии, которая больше не связана с вычислительным графом и не занимает одно и то же место в памяти. Однако это поведение может измениться в будущих версиях, поэтому вы должны использовать команду, которая останется действительной. Я проиллюстрирую проблемы, возникающие из-за того, что заметка отключается или занимает одно и то же место в памяти.
Не отсоединяется:
x = torch.tensor([0.],requires_grad=True)
y = x.clone()
y[0] = 1
z = 2 * y
z.backward()
print(x, x.grad)
tensor([0.], requires_grad=True) tensor([0.])
Как вы можно увидеть, что градиент x обновляется, пока вычисление выполняется для y, но изменение значения y не изменит значение x, потому что они не занимают одно и то же пространство памяти.
Занимает то же пространство памяти:
x = torch.tensor([0.],requires_grad=True)
y = x.detach().requires_grad_(True)
z = 2 * y
z.backward()
y[0] = 1
print(x, x.grad)
tensor([1.], requires_grad=True) None
В этом случае градиенты не обновляются, но изменение значения y изменяет значение x, поскольку они занимают то же пространство памяти.
Лучшая практика:
Как указано в предупреждении, лучше всего как отсоединить, так и клонировать тензор:
x = torch.tensor([0.],requires_grad=True)
y = x.clone().detach().requires_grad_(True)
z = 2 * y
z.backward()
y[0] = 1
print(x, x.grad)
tensor([0.], requires_grad=True) None
Это гарантирует, что будущие модификации и вычисления из y
не повлияют на x