如何在 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是模型级别的概念,一般来说,你可以'说,哪一层负责错误。看,如果模型足够深,可以冻结任何模型层,它仍然可以训练到高精度。
我们可以通过 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是模型级别的概念,一般来说,你可以'说,哪一层负责错误。看,如果模型足够深,可以冻结任何模型层,它仍然可以训练到高精度。