【问题标题】:How to calculate Gradient of the loss with respect to input?如何计算相对于输入的损失梯度?
【发布时间】:2021-07-12 06:01:43
【问题描述】:

我有一个预训练的 PyTorch 模型。我需要使用此模型计算损失相对于网络输入的梯度(无需再次训练,仅使用预训练模型)。

我写了以下代码,但我不确定它是否正确。

    test_X, test_y = load_data(mode='test')
    testset_original = MyDataset(test_X, test_y, transform=default_transform)
    testloader = DataLoader(testset_original, batch_size=32, shuffle=True)

    model = MyModel(device=device).to(device)
    checkpoint = torch.load('checkpoint.pt')
    model.load_state_dict(checkpoint['model_state_dict'])

    gradient_losses = []
    for i, data in enumerate(testloader):
        inputs, labels = data
        inputs= inputs.to(device)
        labels = labels.to(device)
        inputs.requires_grad = True
        output = model(inputs)
        loss = loss_function(output)
        loss.backward()
        gradient_losses.append(inputs.grad)

我的问题是,这个列表 gradient_losses 是否真的存储了我想要存储的内容?如果不是,那么正确的做法是什么?

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    这个列表 gradient_losses 是否实际存储了我希望存储的内容?

    是的,如果您希望获得损失相对于输入的导数,那么这似乎是正确的方法。这是最小的示例,以f(x) = a*x 为例。然后df/dx = a

    >>> x = torch.rand(10, requires_grad=True)
    >>> y = torch.rand(10)
    >>> a = torch.tensor([3.], requires_grad=True)
    
    >>> loss = a*x - y
    >>> loss.mean().backward()
    
    >>> x.grad
    tensor([0.3000, 0.3000, ..., 0.3000, 0.3000])
    

    在这种情况下等于a / len(x)

    请注意,您使用input.grad 提取的每个梯度都将在整个批次中进行平均,而不是每个单独输入的梯度。


    此外,您不需要 .clone() 输入梯度,因为它们不是模型的一部分,不会被 model.zero_grad() 归零。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-08
      • 2018-04-13
      • 2016-07-01
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      相关资源
      最近更新 更多