Я совершенно новичок в pytorch, поэтому я проверял, как работает функция autograd, и обнаружил странное нелогичное поведение при использовании тензорного присваивания.Давайте предположим, что я хочу запустить следующий пример кода:
import os
import numpy as np
import torch
import torch.nn as nn
from torch import autograd
torch.set_default_tensor_type('torch.cuda.FloatTensor')
class Mult_Input(nn.Module):
def __init__(self):
super(Mult_Input, self).__init__()
def forward(self, inp_list):
print(inp_list[0].size())
inp_list[0] = inp_list[0] + inp_list[1]
inp_list[1] = inp_list[1]
inp_list[2] = inp_list[2]
return torch.stack(inp_list).sum()
real_data = [ (torch.from_numpy(np.array([1], dtype=np.float32)).cuda()),
(torch.from_numpy(np.array([1], dtype=np.float32)).cuda()),
(torch.from_numpy(np.array([1], dtype=np.float32)).cuda())
]
netD = Mult_Input()
interpolates_current =[ autograd.Variable(
real_data[idx],
requires_grad=True) for idx in range(len(real_data))]
new_d_input_data = interpolates_current
disc_interpolates = netD(new_d_input_data)
gradients = autograd.grad(outputs=disc_interpolates, inputs=new_d_input_data,
grad_outputs=torch.ones(disc_interpolates.size()),
create_graph=True, retain_graph=True, only_inputs=True)
print(gradients)
Таким образом, входные данные 1,1,1
и являются отдельными (это важно для меня), а Mult_Input
имеет простую функцию, которую я хочудифференцировать по своим входам.
Результат, на мой взгляд, правильный:
(tensor([1.]), tensor([2.]), tensor([1.]))
Таким образом, факел autograd правильно понимает назначение тензоров.
Теперь я попробую немного другой пример с pow(2)
:
class Mult_Input(nn.Module):
def __init__(self):
super(Mult_Input, self).__init__()
def forward(self, inp_list):
print(inp_list[0].size())
inp_list = [x.pow(2) for x in inp_list]
return torch.stack(inp_list).sum()
Результат снова верен:
(tensor([2.], grad_fn=<MulBackward0>), tensor([2.], grad_fn=<MulBackward0>), tensor([2.], grad_fn=<MulBackward0>))
Теперь я делаю небольшое изменение ихотите изменить элемент списка на месте:
class Mult_Input(nn.Module):
def __init__(self):
super(Mult_Input, self).__init__()
def forward(self, inp_list):
print(inp_list[0].size())
inp_list[0] = inp_list[0].pow(2)
return torch.stack(inp_list).sum()
Результат неверный :
(tensor([1.]), tensor([1.]), tensor([1.]))
Когда я делаю
inp_list[0] = inp_list[0].pow(2) + inp_list[1]
Возвращает (tensor([1.]), tensor([2.]), tensor([1.]))
игнорируя квадрат.
версия pytorch - 1.0.1.post2