如何解决为自定义损失函数实现反向传播
我有一个具有向量输出的神经网络 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()
据我所知,取损失函数相对于参数的梯度。但是我可以在使用我自己的损失函数的同时调用它吗(大概程序不知道梯度方程是什么)。我是否还必须实现另一个方法/子程序才能找到梯度?
这让我想到了另一个问题:如果我确实想为我的损失函数实现梯度计算,我还需要神经网络参数的梯度。我如何获得那些?有这个功能吗?
解决方法
只要您从输入开始到损失函数的所有步骤都涉及对 PyTorch 的张量的可微操作,您就不需要做任何额外的事情。 PyTorch 构建了一个计算图来跟踪每个操作、其输入和梯度。因此,在您的自定义损失上调用 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/activity_main_bottom_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/white"
android:elevation="4dp"
app:itemIconSize="20dp"
app:itemIconTint="@color/selector_item_primary_color"
app:itemTextColor="@color/selector_item_primary_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
仍然会通过图形正确地传播梯度。来自 PyTorch 教程的 A Gentle Introduction to torch.autograd 可能是有用的参考。
后向传递后,如果需要直接访问梯度进行进一步处理,可以使用 loss.backward()
属性(所以 .grad
表示图中的张量 t.grad
) .
最后,如果您有一个特定的用例来查找使用 PyTorch 的张量实现的任意可微函数相对于其输入之一的梯度(例如,相对于网络中特定权重的损失梯度),您可以使用 torch.autograd.grad
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。