首页 > 解决方案 > 在 pytorch 中使用 Scipy 函数时获取渐变的问题

问题描述

我已经浏览了这个 pytorch 页面上的示例:https ://pytorch.org/tutorials/advanced/numpy_extensions_tutorial.html

在第二个示例中,他们使用了 scipy 函数scipy.signal.convolve2d,我正在尝试使用scipy.optimize.quad

这是示例中 pytorch 模块中的前向函数,其中输入是需要 grad 的张量,在使用此函数获取输出后,它们仍然能够计算输入变量的梯度。这就是我想要做的。注意detach这里在输入上的使用。

class ScipyConv2dFunction(Function):
    @staticmethod
    def forward(ctx, input, filter, bias):
        # detach so we can cast to NumPy
        input, filter, bias = input.detach(), filter.detach(), bias.detach()
        result = correlate2d(input.numpy(), filter.numpy(), mode='valid')
        result += bias.numpy()
        ctx.save_for_backward(input, filter, bias)
        return torch.as_tensor(result, dtype=input.dtype)

示例代码:

module = ScipyConv2d(3, 3)
print("Filter and bias: ", list(module.parameters()))
input = torch.randn(10, 10, requires_grad=True)
output = module(input)
print("Output from the convolution: ", output)
output.backward(torch.randn(8, 8))
print("Gradient for the input map: ", input.grad)

所以我觉得我正在尝试做同样的事情,除了使用不同的 scipy 函数,quad我认为它应该可以工作。这是代码

t_list = torch.tensor([0])
U = torch.rand(1, requires_grad=True )

def pytorch_objective(u):
  global U
  return torch.log(U) + torch.as_tensor( integrate.quad(func, t_list[-1].numpy() , u.detach().numpy() )[0] )

initial_x = torch.tensor([4.], requires_grad = True) 
value = pytorch_objective(initial_x)
value.backward()
print(initial_x.grad)

最后打印出来None。我可以确认,如果我将目标函数简化为不使用 scipy,我们就不用detach张量,只做一些基本的计算,梯度按预期工作。当然,我认为当我们detach使用变量u( initial_x) 时,我们似乎会失去它的梯度。

有谁知道我在这里是否走错了路?

标签: pythonscipypytorchgradient

解决方案


推荐阅读