为自定义损失函数实现反向传播
Implementing Backprop for custom loss functions
我有一个具有矢量输出的神经网络 Network
。我不想使用典型的损失函数,而是想实现自己的损失函数,它是某些 class 中的一种方法。这看起来像:
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()
据我了解,采用损失函数相对于参数的梯度。但是我仍然可以在使用我自己的损失函数时调用它吗(大概程序不知道梯度方程是什么)。我是否还必须实施另一个 method/subroutine 才能找到梯度?
这引出了我的另一个问题:如果我想为我的损失函数实现梯度计算,我还需要神经网络参数的梯度。我如何获得那些?有那个功能吗?
只要你从输入开始到损失函数的所有步骤都涉及对 PyTorch 的张量的可微操作,你就不需要做任何额外的事情。 PyTorch 构建了一个计算图来跟踪每个操作、它的输入和梯度。因此,对您的自定义损失调用 loss.backward()
仍会通过图表正确传播梯度。 A Gentle Introduction to torch.autograd 来自 PyTorch 教程可能是有用的参考。
反向传递后,如果需要直接访问梯度以进行进一步处理,可以使用 .grad
属性(因此 t.grad
for tensor t
in the图)。
最后,如果您有一个特定的用例来查找使用 PyTorch 的张量实现的任意可微函数相对于其输入之一的梯度(例如,损失相对于网络中特定权重的梯度) , 你可以使用 torch.autograd.grad
.
我有一个具有矢量输出的神经网络 Network
。我不想使用典型的损失函数,而是想实现自己的损失函数,它是某些 class 中的一种方法。这看起来像:
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()
据我了解,采用损失函数相对于参数的梯度。但是我仍然可以在使用我自己的损失函数时调用它吗(大概程序不知道梯度方程是什么)。我是否还必须实施另一个 method/subroutine 才能找到梯度?
这引出了我的另一个问题:如果我想为我的损失函数实现梯度计算,我还需要神经网络参数的梯度。我如何获得那些?有那个功能吗?
只要你从输入开始到损失函数的所有步骤都涉及对 PyTorch 的张量的可微操作,你就不需要做任何额外的事情。 PyTorch 构建了一个计算图来跟踪每个操作、它的输入和梯度。因此,对您的自定义损失调用 loss.backward()
仍会通过图表正确传播梯度。 A Gentle Introduction to torch.autograd 来自 PyTorch 教程可能是有用的参考。
反向传递后,如果需要直接访问梯度以进行进一步处理,可以使用 .grad
属性(因此 t.grad
for tensor t
in the图)。
最后,如果您有一个特定的用例来查找使用 PyTorch 的张量实现的任意可微函数相对于其输入之一的梯度(例如,损失相对于网络中特定权重的梯度) , 你可以使用 torch.autograd.grad
.