最近在跟着教程用PyTorch搭一个简单的DCGAN,想在自拍数据集上生成点真人脸的假图。结果每次训练到差不多200个epoch左右,判别器loss就突然飙到20多,生成器loss直接掉到0附近,然后整个模型就废掉了,出来的全是噪点。我确认过数据归一化是[-1,1],学习率设的是0.0002,用的是Adam优化器。有人说是梯度爆炸或者模式崩塌,但我不知道怎么判断具体是哪种,也不知道该调什么参数。有没有大佬给个排查思路?或者有什么靠谱的GAN训练trick可以分享?先谢过。
用PyTorch写GAN训练到一半loss爆了,有人遇到过类似情况吗?
全部回复
共 163 条大概率是判别器太强把生成器压死了,试试调低判别器学习率或者加label smoothing。
我个人觉得你这个情况更偏向模式崩塌,梯度爆炸一般会在训练早期就出现,不会等到200个epoch才突然爆发。判别器loss飙到20多,生成器掉到0,典型特征是判别器太强直接把生成器按死了,导致梯度信号消失。可以试试把判别器的学习率调低一点,比如降到0.0001,或者把生成器和判别器的学习率设置成不一样,让生成器稍微跑快一点。另外加一些标签平滑也很有用,把真实标签从1改成0.9,虚假标签从0改成0.1,这样能防止判别器过于自信。还有个小trick是每更新一次判别器就更新两次生成器,保持两者的对抗节奏。你用的自拍数据集如果样本不够多样或者背景太单一,也容易诱发崩塌,可以考虑加一点随机裁剪或者旋转来增广。对了,检查下判别器里是不是用了BatchNorm,有些教程在判别器里不加BN反而更稳定,你可以试一下。
试试把判别器的学习率降到生成器的十分之一,或者加个标签平滑,我这么调过之后稳了很多。
这大概率是判别器太强导致生成器梯度消失,试试给判别器加个梯度惩罚或调低学习率。
试试把判别器的学习率降到生成器的一半,比如1e-4,同时加一点标签平滑。
看到你这个情况我太熟了,之前我做人脸生成的时候也卡在差不多200epoch这个坎上。你判别器loss飙到20多基本就是梯度爆炸了,可以试试给判别器加个梯度裁剪,或者把学习率降到1e-4甚至5e-5,Adam的betas参数也可以从默认的(0.9, 0.999)调成(0.5, 0.999)来缓解训练震荡。另外模式崩塌的话生成器loss降到0附近但出来的全是噪点,其实两个问题经常会同时出现,我建议你先在判别器里加个标签平滑,把真实标签从1换成0.9,虚假标签从0换成0.1,这能防止判别器过于自信导致梯度炸裂。还有个小trick是每训练一次判别器就训练两次生成器,或者反过来,保持两者的平衡,我之前用这个办法撑过了400epoch才出好效果。你用的自拍数据集如果人脸角度变化太大,也可能导致模型早期学崩,可以先挑些正面照试试看。
200轮才崩的话,感觉更像是模式崩塌而不是单纯的梯度爆炸,你可以试试给判别器加一点标签平滑,或者把生成器的学习率调低到0.0001甚至更低,有时候Adam的betas参数调成(0.5, 0.999)也能稳住训练。另外检查一下判别器里有没有用BatchNorm,DCGAN里生成器用BN没问题,但判别器加了反而容易让loss乱跳。
这情况太典型了,八成是生成器把判别器给“骗崩”了,导致梯度爆炸。你试试把判别器的学习率降到生成器的一半,比如1e-4,或者给判别器加个梯度惩罚,用WGAN-GP的loss替换原始BCE loss。另外检查下生成器输出层有没有用Tanh,以及判别器里别用BatchNorm,容易引入batch间的统计波动。
这情况太典型了,我刚开始练GAN也遇到过。模式崩塌和梯度爆炸其实可以看判别器loss的变化区分:如果loss持续冲高,大概率是梯度爆炸,试试梯度裁剪或调低学习率;如果loss在0和20之间来回跳,生成器loss又特别低,那基本就是模式崩塌,建议加小批量判别或者标签平滑。另外自拍数据集如果背景太单一,也容易崩,可以试试把图像尺寸调小或者先用随机噪声过拟合几轮看看模型能不能稳定。
这种情况我也踩过坑,200 epoch左右崩大概率是判别器太强了,生成器跟不上导致模式崩塌。可以试试给判别器加个标签平滑,或者把它的学习率调低一点,比如0.00005,同时给生成器加一点噪声输入。另外检查一下是不是梯度消失,把判别器的梯度打印出来看看,如果前几层接近0就是梯度问题。
大概率是判别器太强导致生成器梯度消失了,200轮这个点正好是两者能力失衡的临界点。你可以试试给判别器加Dropout或者Label Smoothing,再不然就把判别器的学习率调低到生成器的一半。我之前也踩过这个坑,后来把生成器的学习率提到0.0003,判别器降到0.0001,同时给判别器加了个谱归一化,训练就稳多了。你检查过判别器最后几层的梯度吗?那个突然飙升的loss通常对应梯度爆炸。
你这情况八成是判别器学太快了,把生成器按在地上摩擦,导致梯度消失。可以试试把判别器的学习率调低到生成器的十分之一,或者给判别器加一点标签平滑,别让它太自信。另外检查下是不是每次更新判别器次数太多,建议判别器每更新一次、生成器更新两次,平衡一下对抗强度。我自己之前也是200epoch崩,调了这些之后稳定多了。
这种情况我也遇到过,大概率是判别器学得太快把生成器压死了,也就是你说的模式崩塌。建议试试把判别器的学习率调低一点,比如0.00005,或者给生成器加一点标签平滑。另外检查一下判别器里有没有用BatchNorm,DCGAN里判别器通常不用这个,换成InstanceNorm或者直接去掉可能会稳一些。
200轮崩盘大概率是模式崩塌,试试给判别器加个标签平滑或者把学习率降到1e-4。
试试把判别器加个梯度惩罚,或者学习率降到万分之一,我之前这么调稳住了。
我遇到过一模一样的情况,DCGAN训练到后面判別器loss突然起飞基本就是典型的模式崩塌。你可以先试试把判别器的学习率调低一点,比如降到0.0001或者0.00005,有时候两边学习率不平衡就会这样。另外检查一下生成器最后一层是不是用的Tanh,输出范围得跟数据归一化[-1,1]对上。我自己的经验是给判別器加一点标签平滑,就是把真实标签从1换成0.9,假的从0换成0.1,能有效防止它过于自信导致梯度爆炸。还有个小trick是每训练几次判別器才训练一次生成器,比如5:1的比例,让判別器先稳住。你用的自拍数据集如果图片分辨率不高或者背景太杂,也容易让模型学崩,可以考虑先做一下人脸对齐或者裁剪。反正别灰心,GAN调参本来就是个玄学,多试几次找到平衡点就好了。
这情况太经典了,八成是判别器学得太快导致生成器梯度消失。建议试试给判别器加个标签平滑,把真实标签从1换成0.9,或者每训练一次判别器就训练两次生成器,平衡一下对抗强度。另外也可以调低判别器的学习率,比如降到0.00005,或者干脆给判别器加个dropout层防止过拟合。我之前跑CelebA也遇到过这种暴毙,把batch size从64提到128反而稳定了,你可以也试试。
试试给判别器加label smoothing,或者把生成器的学习率调低到0.0001,我这么改完稳定多了。
这情况太经典了,八成是判别器学得太快直接把生成器压死了,模式崩塌的典型症状。你可以试试把判别器的学习率调低一点,比如改成0.0001,或者给判别器加个梯度惩罚,别让它更新太猛。另外看看是不是batch size太小了,如果显存允许的话提到64或128,也能稳定不少。
这情况太经典了,我刚开始跑DCGAN也遇到过,大概率是判别器学得太快把生成器压死了。可以试试给判别器加个标签平滑,把真实标签从1换成0.9,或者调低判别器的学习率,比如降到0.00005,同时把生成器学习率稍微提一点。另外检查下是不是梯度裁剪没加,我习惯给判别器设个梯度范数上限1.0,能有效防止loss突然飞升。