保存了近期训练的一些GAN模型,其中:
-
CGAN文件夹是之前训练的一个Conditional GAN模型,不过训练失败了(D失衡)。其实如果使用DCGAN后期的Discriminator的话理论上应该可以train出来,不过目前没有足够的计算资源和时间。
-
DCGAN是用来生成二次元人脸的DCGAN模型。目前正在训练中,在1000轮左右时开始显现脸的轮廓
-
pack中保存训练用的数据
- selected中包括64*64的1.8w张带标签的二次元人脸
- tags.txt中每行为一个类别的标签,包括发色、瞳孔颜色和发长
- filtered.txt中每行对应selected中一张人脸,从0开始计数
训练的时候发现一些技巧:
- 每一轮迭代时,当D或是G的输出正确率达到$p_0$就停止训练了,因为理论上$Acc_D[fake]+Acc_G=1$,如果一直训练下去可能会使得梯度变得很小,D和G就会失去平衡。我取的是$p_0=Acc_D[fake]=0.999$。
- 之前训练CGAN时失败应该就是因为$p_0$取值过小,如果D或是G无法达到接近100%的正确率,实际上是比较失败的,D和G只会在高维空间中比较平滑的区域随机抖动。
- DCGAN中D的生成网络初始映射的channel一定要多,不要吝惜内存,不然很容易D就偏向只对realdata或是fakedata的输入判断,另一个正确率为0。大概是因为要保持realdata和fakedata的输入准确率都很高,所以尽量避免卷积时的信息损失吧。
- G比D难训练得多,我在训练时发现,G的参数要比D多几倍才能和D达到平衡,并且很容易准确率就变为0。
- 为了防止出现D强G弱的现象,在计算D的损失函数时,不直接使用${0,1}$标签,而是加入随机噪声。
- 大部分模型学习速率0.0002最佳。
- G的输出可以用tanh规范化到$[-1,1]$。
- D的网络中加入批规范化(BatchNormalize)效果非常好。
- 在D中使用LeakyReLU。
- 定时保存模型和log真的很重要。可以在必要时回退并调整训练参数
实际上训练尚未结束,记一下当前的进度吧,目前一共跑了大概两个多小时,不得不说卷积层真的非常省内存。
- 刚开始的500轮比较稳定,不需要人为干预,D和G就可以维持平衡
- 853轮时G失效,从853-980epoch准确率都是0,回退到840轮增加DLoss的随机性,重新开始训练。
- 960-996epoch时D的准确率都是0,但是到了997突然变为1.0000,这次的对抗epoch较多,实际上回退具有一定风险。
- 1220epoch时G输出为一张纯蓝色的图,回退到1160
- 1360-1430epoch时D都无法分辨出G的输出,回退到1140,修改batchsize为96
下面的动图是从[80,180,260,280,320,420,500,640,700,760,800,840,900,960,1020,1100]epoch的记录,G使用了同一个随机向量。
80-640中在我看来人脸的辨识度是逐渐提高的,640epoch以后不知道什么原因,G更改了优化的方向,图片直接从两只眼睛变成了一只眼睛,1020epoch时人脸有了三只眼睛,1100后又回到了两只眼睛。
如果G和D没有提前结束,每一轮epoch大概要5s左右,不过通常G或是D都会提前结束。