在NN训练期间最大化一种损失并最小化另一种损失的正确方法是啥?

Posted

技术标签:

【中文标题】在NN训练期间最大化一种损失并最小化另一种损失的正确方法是啥?【英文标题】:What is the correct way to maximize one loss and minimize another during NN training?在NN训练期间最大化一种损失并最小化另一种损失的正确方法是什么? 【发布时间】:2021-12-02 01:26:27 【问题描述】:

我有一个简单的神经网络:

import torch
import torch.nn as nn
import torch.optim as optim

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.fc1 = nn.Linear(1, 5)
        self.fc2 = nn.Linear(5, 10)
        self.fc3 = nn.Linear(10, 1)

    def forward(self, x):
        x = self.fc1(x)
        x = torch.relu(x)        
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Model()

opt = optim.Adam(net.parameters())

我还有一些输入功能:

features = torch.rand((3,1)) 

我可以用一个最小化的简单损失函数来正常训练它:

for i in range(10):
    opt.zero_grad()
    out = net(features)
    loss = torch.mean(torch.square(torch.tensor(5) - torch.sum(out)))
    print('loss:', loss)
    loss.backward()
    opt.step()

但是,如果我要为此添加另一个我想要最大化的损失组件--loss2:

loss2s = []
for i in range(10000):
    opt.zero_grad()
    out = net(features)
    loss1 = torch.mean(torch.square(torch.tensor(5) - torch.sum(out)))
    loss2 = torch.sum(torch.tensor([torch.sum(w_arr) for w_arr in net.parameters()]))
    loss2s.append(loss2)
    loss = loss1 + loss2
    loss.backward()
    opt.step()

由于 2 个损失的规模不同,它看起来变得不稳定。另外,我不确定这是正确的方法,因为损失如何知道最大化一个部分并最小化另一个部分。请注意,这只是一个示例,显然增加权重是没有意义的。

import matplotlib.pyplot as plt
plt.plot(loss2s, c='r')
plt.plot(loss1s, c='b')

而且我相信最小化函数是 ML 训练的常用方法,所以我不确定以某种方式将最大化问题改为最小化问题是否会更好。

【问题讨论】:

【参考方案1】:

表示“最小化”和“最大化”的标准方式是更改符号。如果完成以下操作,PyTorch 总是最小化loss

loss.backward()

所以,如果另一个loss2需要最大化,我们添加它的负数

overall_loss = loss + (- loss2)
overall_loss.backward()

因为最小化负数等于最大化原始正数。

关于“比例”,是的,比例确实很重要。通常会执行以下操作以匹配比例

overall_loss = loss + alpha * (- loss2)

其中alpha 是一个分数,表示一个损失相对于另一个损失的相对重要性。它是一个超参数,需要进行试验。


撇开技术细节不谈,由此产生的损失是否稳定在很大程度上取决于具体问题和所涉及的损失函数。如果损失矛盾,您可能会遇到不稳定。处理它们的方法本身就是一个研究问题,远远超出了这个问题的范围。

【讨论】:

知道了。关于这两种损失具有不同规模的事实?那也不重要吗? 是的,天平很重要。我已经更新了答案 非常感谢:)

以上是关于在NN训练期间最大化一种损失并最小化另一种损失的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

一文搞懂深度常用损失函数

Python sklearn 在训练期间显示损失值

代价函数

梯度下降

ML(附录1)——梯度下降

各个模型的损失函数