增加一个常数正损失和常数负损失会导致梯度消失吗?

我想问一个关于使用两种损失来训练一个模型的问题。
我打算生成一些特定类型的问题句子。
为此,我使用了
(1) 一个普通的GAN来生成普通的问题空间。然后
(2) 一个辅助分类器,让生成器专注于生成那类问题。

通过预实验,当我在生成器-判别器损失(loss_G_D)上使用BCELoss()时,损失值大约是3。
而当我在生成器-分类器损失(loss_G_C)上使用-Entropy时,损失值总是负的,并且非常大,例如-300。
为了不让它们相互影响训练过程,我使用了这种训练方法。

optimizer.zero_grad()loss_G_D = BCELoss(discriminator(generated_data))loss_G_D.backward()optimizer.step()optimizer.zero_grad()loss_G_C = -Entropy(classifier(generated_data))loss_G_C.backward()optimizer.step()

然而,这种训练过程有点慢,并且似乎让网络训练在“来回”进行。因此,一位朋友建议我使用这种方法:

optimizer.zero_grad()loss_G_D = BCELoss(discriminator(generated_data))loss_G_C = -Entropy(classifier(generated_data))loss = loss_G_D+loss_G_C# 如果你担心规模,可以给一些权重,比如# loss = loss_G_D+0.01*loss_G_Closs.backward()optimizer.step()

我觉得这有道理。然而,就像loss_G_D是3,loss_G_C是-300,将它们相加不会导致梯度消失吗?因为使用loss = loss_G_D+0.01*loss_G_C=0?
或者我可以说因为它们是考虑总是正的和负的不同类型的损失,我们不应该将它们相加?
(附注:我想也许将-Entropy损失映射到一个总是正的激活函数,然后将两个损失相加会有效?)


回答:

不会的。在你的情况下,是总损失在“消失”,而不是梯度。梯度只是从两个损失计算出的两个独立梯度的总和。因为一种损失只在classifier上实施,另一种只在discriminator上实施,因此前者的反向传播应该只为classifier分配梯度,而后者的反向传播应该只为discriminator分配梯度。所以它们不会相互影响。

让我用一个简单的例子来解释。假设你只有两个参数xy。你希望通过实施损失L_x = abs(x)使x尽可能小。同时,你也希望通过实施L_y=-abs(y)使y尽可能大。所以总损失实际上是L=abs(x)-abs(y)。假设我们最初有x=y=1。那么梯度是(dL/dx,dL/dy)=(1,-1),而损失是L=0

更具体地说,在(x,y)=(1,1)时,L_x=1给出的梯度是(d(L_x)/dx,d(L_x)/y)=(1,0),而L_y=-1给出的梯度是(d(L_y)/dx,d(L_y)/y)=(0,-1)。你会看到,即使L_xL_y相互抵消,它们的梯度并不会。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注