【问题标题】:Implementing Backprop for custom loss functions为自定义损失函数实现反向传播
【发布时间】:2021-07-27 23:40:04
【问题描述】:

我有一个神经网络Network,它有一个向量输出。我不想使用典型的损失函数,而是想实现我自己的损失函数,它是某个类中的一种方法。这看起来像:

class whatever:
    def __init__(self, network, optimizer): 
         self.network = network
         self.optimizer = optimizer
    
    def cost_function(relevant_data):
        ...implementation of cost function with respect to output of network and relevant_data...

    def train(self, epochs, other_params):
        ...part I'm having trouble with...

我主要关心的是渐变。由于我采用的是自己的自定义损失函数,是否需要针对成本函数实现自己的梯度?

一旦我做了数学,我意识到如果成本是 J,那么就网络最后一层的梯度而言,J 的梯度是一个相当简单的函数。即,它看起来像:Equation link

如果我使用一些传统的损失函数,例如 CrossEntropy,我的后处理将如下所示:

objective = nn.CrossEntropyLoss()
for epochs:
    optimizer.zero_grad()
    output = Network(input)
    loss = objective(output, data)
    loss.backward()
    optimizer.step()

但在我的情况下,我们如何做到这一点?我的猜测是这样的:

for epochs:
     optimizer.zero_grad()
     output = Network(input)
     loss = cost_function(output, data)
     #And here is where the problem comes in
     loss.backward()
     optimizer.step()
     

loss.backward() 据我了解,它采用损失函数相对于参数的梯度。但是我是否仍然可以在使用自己的损失函数时调用它(大概程序不知道梯度方程是什么)。我是否还必须实现另一种方法/子例程才能找到渐变?

这让我想到了另一个问题:如果我确实想为我的损失函数实现梯度计算,我还需要神经网络参数的梯度。我如何获得那些?有这样的功能吗?

【问题讨论】:

    标签: python machine-learning neural-network pytorch backpropagation


    【解决方案1】:

    只要您从输入到损失函数的所有步骤都涉及对 PyTorch 张量的可微操作,您就不需要做任何额外的事情。 PyTorch 构建了一个计算图,用于跟踪每个操作、其输入和梯度。因此,在您的自定义损失上调用 loss.backward() 仍将通过图形正确传播梯度。 PyTorch 教程中的A Gentle Introduction to torch.autograd 可能是有用的参考。

    在反向传递之后,如果您需要直接访问梯度以进行进一步处理,您可以使用.grad 属性(因此图中的张量tt.grad)。

    最后,如果您有一个特定用例来查找使用 PyTorch 的张量实现的任意可微函数相对于其输入之一的梯度(例如,相对于网络中特定权重的损失梯度),您可以使用torch.autograd.grad

    【讨论】:

    • 嗯,这很整洁。谢谢!
    猜你喜欢
    • 2019-11-14
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2021-10-25
    相关资源
    最近更新 更多