猿问

Pytorch Autograd在使用.clamp而不是torch.relu时给出不同的渐变

我仍在努力理解PyTorch autograd系统。我正在努力的一件事是理解为什么,并且似乎有不同的向后传球。.clamp(min=0)nn.functional.relu()


它特别令人困惑,因为它等效于PyTorch教程中的使用,例如 https://pytorch.org/tutorials/beginner/pytorch_with_examples.html#pytorch-nn。.clamprelu


在分析具有一个隐藏层和一个relu激活(输出层中的线性)的简单全连接网络的梯度时,我发现了这一点。


据我所知,以下代码的输出应该只是零。我希望有人能向我展示我错过了什么。


import torch

dtype = torch.float


x = torch.tensor([[3,2,1],

                  [1,0,2],

                  [4,1,2],

                  [0,0,1]], dtype=dtype)


y = torch.ones(4,4)


w1_a = torch.tensor([[1,2],

                     [0,1],

                     [4,0]], dtype=dtype, requires_grad=True)

w1_b = w1_a.clone().detach()

w1_b.requires_grad = True




w2_a = torch.tensor([[-1, 1],

                     [-2, 3]], dtype=dtype, requires_grad=True)

w2_b = w2_a.clone().detach()

w2_b.requires_grad = True



y_hat_a = torch.nn.functional.relu(x.mm(w1_a)).mm(w2_a)

y_a = torch.ones_like(y_hat_a)

y_hat_b = x.mm(w1_b).clamp(min=0).mm(w2_b)

y_b = torch.ones_like(y_hat_b)


loss_a = (y_hat_a - y_a).pow(2).sum()

loss_b = (y_hat_b - y_b).pow(2).sum()


loss_a.backward()

loss_b.backward()


print(w1_a.grad - w1_b.grad)

print(w2_a.grad - w2_b.grad)


# OUT:

# tensor([[  0.,   0.],

#         [  0.,   0.],

#         [  0., -38.]])

# tensor([[0., 0.],

#         [0., 0.]])


跃然一笑
浏览 230回答 1
1回答

侃侃无极

原因是,并在 处产生不同的梯度。使用标量张量检查两个版本:与 .结果是针对该版本,但它是针对该版本。这意味着选择,而选择。clamprelu0x = 0(x.clamp(min=0) - 1.0).pow(2).backward()(relu(x) - 1.0).pow(2).backward()x.grad0relu-2clamprelux == 0 --> grad = 0clampx == 0 --> grad = 1
随时随地看视频慕课网APP

相关分类

Python
我要回答