【发布时间】:2021-05-11 07:58:50
【问题描述】:
第一季度。
我正在尝试使用 pytorch 制作我的自定义 autograd 函数。
但是我在使用 y = x / sum(x, dim=0) 进行分析反向传播时遇到了问题
其中张量 x 的大小是(高度,宽度)(x 是二维的)。
这是我的代码
class MyFunc(torch.autograd.Function):
@staticmethod
def forward(ctx, input):
ctx.save_for_backward(input)
input = input / torch.sum(input, dim=0)
return input
@staticmethod
def backward(ctx, grad_output):
input = ctx.saved_tensors[0]
H, W = input.size()
sum = torch.sum(input, dim=0)
grad_input = grad_output * (1/sum - input*1/sum**2)
return grad_input
我用 (torch.autograd import) gradcheck 来比较雅可比矩阵,
from torch.autograd import gradcheck
func = MyFunc.apply
input = (torch.randn(3,3,dtype=torch.double,requires_grad=True))
test = gradcheck(func, input)
结果是
请有人帮我得到正确的反向传播结果
谢谢!
第二季度。
感谢您的回答!
由于您的帮助,我可以在 (H,W) 张量的情况下实现反向传播。
但是,当我在 (N,H,W) 张量的情况下实现反向传播时,我遇到了一个问题。 我认为问题在于初始化新张量。
这是我的新代码
import torch
import torch.nn as nn
import torch.nn.functional as F
class MyFunc(torch.autograd.Function):
@staticmethod
def forward(ctx, input):
ctx.save_for_backward(input)
N = input.size(0)
for n in range(N):
input[n] /= torch.sum(input[n], dim=0)
return input
@staticmethod
def backward(ctx, grad_output):
input = ctx.saved_tensors[0]
N, H, W = input.size()
I = torch.eye(H).unsqueeze(-1)
sum = input.sum(1)
grad_input = torch.zeros((N,H,W), dtype = torch.double, requires_grad=True)
for n in range(N):
grad_input[n] = ((sum[n] * I - input[n]) * grad_output[n] / sum[n]**2).sum(1)
return grad_input
Gradcheck 代码是
from torch.autograd import gradcheck
func = MyFunc.apply
input = (torch.rand(2,2,2,dtype=torch.double,requires_grad=True))
test = gradcheck(func, input)
print(test)
结果是 enter image description here
不知道为什么会出现错误...
您的帮助将对我实现自己的卷积网络非常有帮助。
谢谢!祝你有美好的一天。
【问题讨论】:
-
为什么要自己实现backward pass?
-
@Ivan 因为我想做自己的卷积网络