如何在 Pytorch 模型中获得中间输出梯度

How to get intermediate output grad in Pytorch model

我们可以通过 loss = loss_fn(y_pred, y_true) 得到最后一层的损失,并得到 loss: Tensor

然后我们调用loss.backward()做反向传播

optimizer.step() 之后我们可以看到更新的 model.parameters()

以下面的例子

y = Model1(x) # with optimizer1
z = Model2(y) # with optimizer2
loss = loss_fn(z, z_true)
loss.backward()
optimizer2.optimize() # update Model2 parameters

# in order to update Model1 parameters I think we should do
y.backward(grad_tensor=the_output_gradient_from_Model2)
optimizer1.optimize()

如何得到中间反向传播结果?例如输出 grad 的梯度,将由 y_pred.backward(grad_tensor=grad).

更新:解决方案是设置 required_grad=True 并取 Tensor x.grad。感谢您的回答。

PS:场景是我在做联邦学习,模型被分成两部分。第一部分接受输入并转发到第二部分。并且它需要第二部分计算损失并将损失反向传播到第一部分,以便第一部分接受损失并进行自己的反向传播。

当你说“丢失特定层”时,我会假设你指的是中间梯度

您可以通过访问需要梯度计算的模型参数的 grad 属性来访问与输出损失相关的层梯度。

这是一个简单的设置:

>>> f = nn.Sequential(
       nn.Linear(10,5), 
       nn.Linear(5,2), 
       nn.Linear(2, 2, bias=False), 
       nn.Sigmoid())

>>> x = torch.rand(3, 10).requires_grad_(True)
>>> f(x).mean().backward()

浏览每层的所有参数:

>>> for n, c in f.named_children():
...    for p in c.parameters():
...       print(f'<{n}>:{p.grad}')

<0>:tensor([[-0.0054, -0.0034, -0.0028, -0.0058, -0.0073, -0.0066, -0.0037, -0.0044, 
             -0.0035, -0.0051],
            [ 0.0037,  0.0023,  0.0019,  0.0040,  0.0050,  0.0045,  0.0025,  0.0030,
              0.0024,  0.0035],
            [-0.0016, -0.0010, -0.0008, -0.0017, -0.0022, -0.0020, -0.0011, -0.0013,
             -0.0010, -0.0015],
            [ 0.0095,  0.0060,  0.0049,  0.0102,  0.0129,  0.0116,  0.0066,  0.0077,
              0.0063,  0.0091],
            [ 0.0005,  0.0003,  0.0002,  0.0005,  0.0006,  0.0006,  0.0003,  0.0004,
              0.0003,  0.0004]])
<0>:tensor([-0.0090,  0.0062, -0.0027,  0.0160,  0.0008])
<1>:tensor([[-0.0035,  0.0035, -0.0026, -0.0106, -0.0002],
            [-0.0020,  0.0020, -0.0015, -0.0061, -0.0001]])
<1>:tensor([-0.0289, -0.0166])
<2>:tensor([[0.0355, 0.0420],
            [0.0354, 0.0418]])

补充梯度相关的答案,应该说你不能得到层的loss,loss是模型级别的概念,一般来说,你可以'说,哪一层负责错误。看,如果模型足够深,可以冻结任何模型层,它仍然可以训练到高精度。