【发布时间】:2019-07-02 08:56:32
【问题描述】:
我正在学习 Defining new autograd functions 上的 PyTorch 教程。我要实现的 autograd 函数是 torch.nn.functional.max_pool1d 的包装器。这是我目前所拥有的:
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.autograd as tag
class SquareAndMaxPool1d(tag.Function):
@staticmethod
def forward(ctx, input, kernel_size, stride=None, padding=0, dilation=1, \
return_indices=False, ceil_mode=False):
ctx.save_for_backward( input )
inputC = input.clone() #copy input
inputC *= inputC
output = F.max_pool1d(inputC, kernel_size, stride=stride, \
padding=padding, dilation=dilation, \
return_indices=return_indices, \
ceil_mode=ceil_mode)
return output
@staticmethod
def backward(ctx, grad_output):
input, = ctx.saved_tensors
grad_input = get_max_pool1d_grad_somehow(grad_output)
return 2.0*input*grad_input
我的问题是:如何获得包装函数的渐变?鉴于我提供的示例非常简单,我知道可能还有其他方法可以做到这一点,但我想做的适合这个框架,并且需要我实现一个 autograd 函数。
编辑:检查this blog post 后,我决定为backward 尝试以下操作:
def backward(ctx, grad_output):
input, output = ctx.saved_tensors
grad_input = output.backward(grad_output)
return 2.0*input*grad_input
将output 添加到已保存的变量中。然后我运行以下代码:
x = np.random.randn(1,1,5)
xT = torch.from_numpy(x)
xT.requires_grad=True
f = SquareAndMaxPool1d.apply
s = torch.sum(f(xT,2))
s.backward()
我得到Bus error: 10。
假设xT 是tensor([[[ 1.69533562, -0.21779421, 2.28693953, -0.86688095, -1.01033497]]], dtype=torch.float64),那么我希望在调用s.backward() 后发现xT.grad 是tensor([[[ 3.39067124, -0. , 9.14775812, -0. , -2.02066994]]], dtype=torch.float64)(即2*x*grad_of_max_pool,grad_of_max_pool 包含tensor([[[1., 0., 2., 0., 1.]]], dtype=torch.float64))。
我知道为什么我会收到Bus error: 10。上面的代码似乎导致我的backward 在grad_input = output.backward(grad_output) 的递归调用。所以我需要找到其他方法来获得max_pool1d的渐变。我知道如何在纯 Python 中实现这一点,但结果会比我可以包装库代码慢得多。
【问题讨论】:
-
“获取渐变”是什么意思?实施?计算?
-
@Jatentaki 我的意思是我相信 PyTorch 有一种方法来计算有问题的梯度,给定正确的函数调用。我很难弄清楚那个电话可能是什么。我刚刚为失败的问题添加了一个尝试的解决方案。希望这可以解决问题。
标签: python-3.x pytorch autograd