GAN 的问题主要有两点:Loss 等于0的梯度消失问题和梯度不稳定以及多样性受损。 前者是因为选择的分布函数使用JS 距离,这个距离不能衡量两个不相交的分布的距离;后者是因为Loss 函数要求KL 距离最小,JS 距离最大,所以梯度不稳定,而且 Loss 函数对正确率要求太大,多样性要求小,所以会造成模型选择大量生成“安全”的“数字1”来降低Loss函数。
WGAN 使用了EM 距离,保证了多样 性,并且解决了梯度消失的问题,从实验结果来看,多样性是有保证的,但是生成图片的效果 并不好,较难收敛。
WGAN-GP 的效果好,在第100代的时候,就可以生成多样化、图片清晰的手写数字。 该实验证明了以下两点:
(1)WGAN解决了多样性问题,这也说明,之前原理部分分析的多样性受损确实是由Loss 函数造成的;
(2)WGAN-GP 比 WGAN 效果好,梯度惩罚的效果比 Weight Clipping强,收敛速度快。
WGAN(2017)关于WGAN 的 Loss 函数的图
class discriminator(nn.Module):
def __init __(self):
super(discriminator,self).init__()
self.dis=nn.Sequential(
nn.Linear(784,256),
nn.LeakyReLU(0.2),
nn.Linear(256,256),
nn.LeakyReLU(0.2),
nn.Linear(256,1))
def forward(self,x):
x=self.dis(x)
return x
对于判别器 D 来说,若要使V(G,D) 最大,那么它的Loss 函数就要使-V(G,D) 最小
注释掉GAN判别器D的loss函数,在合适位置写下Loss的新函数
d_loss=torch.mean(fake_out)-torch.mean(real_out)
同理在合适的位置下写下G的新的Loss函数
g_loss=torch.mean(-output)
最后,增加上Weight Clipping (权重剪裁).Weight Clipping将所有的参数都变到[一c,c] 内,这里 截断值c=0.05。 截断值c 要根据具体任务具体设置,如果c 过小,会造成梯度消失;如果 c 过大,会造成梯度爆炸。
梯度消失(Vanishing Gradients)是深度学习中常见的一个问题,特别是在训练深层神经网络时。当网络层数较多时,反向传播过程中梯度会通过多层权重进行连乘,这可能导致梯度变得非常小,以至于网络中的权重更新非常缓慢,从而使得训练过程非常缓慢甚至停滞.
梯度爆炸则是指在训练过程中,梯度随着层数的增加而指数级增长,导致权重更新过大,从而使模型训练变得不稳定。这通常与权重的初始化值过大、学习率过高或网络结构设计不合理有关。
for layer in D.dis:
if(layer. __class __.__name__=='Linear'):
layer.weight.requires_grad=False#关闭梯度
layer.weight.clamp_(-c,c)
layer.weight.requires_grad=True#打开梯度
</