我对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