我的 WGAN 的损失在短短五个批次(不是纪元)内就跌至负无穷大。这个 WGAN 代码有什么问题吗?

问题描述 投票:0回答:1

这里是Wasserstein距离的值(也是GAN的Adversarial loss)

Epoch:0 batch_num:0 wgan_loss:-16.413176
Epoch:0 batch_num:1 wgan_loss:14472.721 
Epoch:0 batch_num:2 wgan_loss:-10957247.0
Epoch:0 batch_num:3 wgan_loss:-455000130.0 
Epoch:0 batch_num:4 wgan_loss:-3773285000.0

我尝试降低学习率,将批量大小限制为 20。

以下代码是我用于 WGAN 鉴别器的代码,它与

Gradient Reversal Layer(GRL)
集成。

此外,

calc_coeff
函数只是确定反向传播过程中反向梯度的比例。

def grl_hook(coeff):
    def fun1(grad):
        return -coeff*grad.clone()
    return fun1

def calc_coeff(iter_num, high=1.0, low=0.0, alpha=2.0, max_iter=50.0):
    return np.float(2.0 * (high - low) / (1.0 + np.exp(-alpha * iter_num / max_iter)) - (high - low) + low)

class DiscriminatorforWGAN(nn.Module):
    def __init__(self, in_feature, hidden_size):
        super(AdversarialNetworkforCDAN, self).__init__()
        self.ad_layer1 = nn.Linear(in_feature, hidden_size)
        self.ad_layer2 = nn.Linear(hidden_size, hidden_size)
        self.ad_layer3 = nn.Linear(hidden_size, 1)
        self.relu1 = nn.ReLU()
        self.relu2 = nn.ReLU()
        self.dropout1 = nn.Dropout(0.2)
        self.dropout2 = nn.Dropout(0.2)
        self.iter_num = -1
        self.alpha = 1.0
        self.low = 0.0
        self.high = 1.0
        self.max_iter = 15.0
        self.coeff = np.float(0.02)
    def forward(self, x):
        if self.training:
            self.iter_num += 1
        if self.iter_num >= self.max_iter:
            self.iter_num = self.max_iter
        coeff = calc_coeff(self.iter_num, self.high, self.low, self.alpha, self.max_iter)
        self.coeff = coeff
        x = x * 1.0
        x.register_hook(grl_hook(coeff))
        x = self.ad_layer1(x)
        x = self.relu1(x)
        x = self.dropout1(x)
        x = self.ad_layer2(x)
        x = self.relu2(x)
        x = self.dropout2(x)
        y = self.ad_layer3(x)
        return y

对于WGAN的生成器来说,它只是一个简单的基于CNN的网络。 WGAN的其他要求(例如判别器的参数钳位以及WGAN的RMSprop的选择)都已严格遵循!

我的WGAN损失如下

def wgan_loss(values_from_target_side, values_from_source_side):
    W_loss = -torch.mean(values_from_target_side) + torch.mean(values_from_source_side)
    return W_loss
deep-learning pytorch distance backpropagation generative-adversarial-network
1个回答
0
投票

根据提供的信息,我无法确定您的确切问题,但以下一些提示可能会对您有所帮助:

  1. 作者在 GitHub 评论中提到,你必须绘制损失的倒数才能从论文中获得绘图,即 Wasserstein 估计将是损失的倒数。这表明您的 WD 近似值增加而不是按预期减少。

造成这种情况的原因有多种:

  1. 你检查过鉴别器和生成器有多少个参数吗?与标准 GAN 相比,WGAN 判别器应该经过训练以实现最优性。如果生成器有更多的参数,这可能是一个问题。通常,具有大致相同数量的参数是一个很好的起点。如果不查看生成器的代码,就不可能看出“优势”是否平衡。
  2. 每次生成器更新您训练判别器运行多少次?当您希望对判别器进行最优训练时,您通常需要多次运行判别器。我训练过的模型中,每个生成器运行需要 30 次鉴别器运行才能使损失发挥作用,并且我读到过其他模型最多需要 100 次迭代。
  3. 使用梯度惩罚而不是梯度裁剪使得损失在大多数情况下更加稳定。请参阅改进的 Wasserstein GAN:PyTorch 示例论文
  4. 帮助判别器训练到最优的另一个技巧是在判别器中使用 BatchNorm。也许你可以尝试这个而不是辍学? 来源
  5. 您是否尝试过更长时间地训练模型?我发现 Wasserstein GAN 有时需要几个步骤才能开始学习。也就是说,一开始,鉴别器的损失达到峰值,就像您的情况一样,但随后它开始按预期运行并产生良好的结果。见下图绿线: Example WGAN loss with initial peak

我希望这些有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.