前段时间看到了百度飞浆美颜祛法令纹的比赛,刚好想试试看GAN,看了眼经验分享很多人用PaddleGAN这个库,感觉很好上手就试了一下。
安装PaddleGAN
!git clone https://gitee.com/PaddlePaddle/PaddleGAN
!pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
比赛介绍
美颜祛法令纹。提供了6000张人脸图片,是在用StyleGAN2生成的人脸图片(target)上生成了法令纹图片(input),评价指标是PSNR和MSSSIM,模型最好小于5MB且单张图片耗时<30ms。
思路
我先看了一些类似比赛的思路都是UNet做的,PaddleGAN里自带的NANFNet的效果我随便跑跑就挺好的了(但是好像似乎没啥人用GAN,虽然我后面发现GAN确实效果不好…
Anyway,这个比赛对模型大小和耗时的要求比较高。最终我的思路就是先扩充数据集训个大的,之后用蒸馏来压缩。
(另外,踩了坑,本来试图抠出脸的部分来做的,结果发现其实背景也是不太一样的,遂放弃。)
数据集扩充
本来我是打算利用现有数据先训个CycleGAN得到两个模型,模型A输入纯人脸生成有法令纹的人脸,模型B相反。之后拿模型A生成更多的带法令纹的图片。但是我的计算资源不够放弃。(这里PaddleGAN本身可以基于StyleGAN2生成人脸,还有一个很好的开源项目放在这里记录一下。)
之后我就想到现有人脸融合,一开始直觉是直接叠图,看到这篇展示的效果放弃,还得老实用算法:ModelScope图像人脸融合。
最终生成了10000张融合后的人脸,效果如下所示:
纯人脸融合
![](https://i-blog.csdnimg.cn/blog_migrate/cb369ea90664cb71dcb64b0618031b35.png)
![](https://i-blog.csdnimg.cn/blog_migrate/613d8f90d785ef7910439a0cfc3cd0d8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f4b34e284a883741d32b2be19a4515f5.png)
法令纹人脸
![](https://i-blog.csdnimg.cn/blog_migrate/be3d69fd4cc186dd3173f51686924529.png)
![](https://i-blog.csdnimg.cn/blog_migrate/61ade6fb131b63d6b90b8c606115ccdf.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d9edfa4d210825983835c97e797f5fba.png)
数据增强
普通的resize和水平翻转。
在输入尺寸这里我其实犹豫了一下,GAN一般都是(256,256),早期可视化的时候非常糊,后来发现是训的轮数还不够。
训练过程
模型选择了pix2pix,感觉是比较合适的一一对应关系。但最终整体的效果其实不是很好,主要baseline的效果不是很好,psnr大概在36左右,扩充数据集后涨到40左右(可能扩充的数据集多样性也有限),而简单UNet的效果在没有扩充数据集时已经可以达到49左右了。
loss选择
一开始是GAN Loss + L1 Loss,听说会有奇效,但最终效果看起来不是很好,因为时间比较紧没有感觉等不到后面再微调了,于是直接换成GAN Loss + PSNR Loss。
这里我觉得比较关键的是loss的平衡,权重设得不好GAN容易崩,可视化的时候很早就出现噪声。
Optimizer和Lr schedule
其他时候我直接无脑AdamW + Cycle/Cosine lr,但这里发现似乎效果不是很好。循环学习率我一直觉得会学得很慢,在训练后期其实应该缩小循环范围。这里的话体现得更明显,一旦重新循环感觉就是重新学了…PaddleGAN里默认的是线性变化的lr。
一些尝试
试过最后一层激活函数换成tanh,感觉作用不大。
尽量避免了ReLu和pooling等可能产生稀疏梯度的层,所以整个训练过程还算是比较稳定的。
总结
最后由于时间关系,蒸馏的部分还没有实现,一些看到的GAN的trick也没有尝试,比如wassertein GAN的损失函数、反转标签、加高斯噪声等。但我觉得GAN在比赛方面似乎优势不是很大,很难平衡G/D学习和生成图像(方向?)的追求。从肉眼看我觉得法令纹去除效果还是很成功的(左到右是realA、realB、fakeB),只是可能其他部分的一对一关系没有学好,像那种单任务网络反而更加明了。
![](https://i-blog.csdnimg.cn/blog_migrate/1c1d595e20b280dbf232bcfa75dc79ee.png)
![](https://i-blog.csdnimg.cn/blog_migrate/572bf1129d2725390e56d6bd7bc26492.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4b3a601945a56c8262239348bfa479bb.png)
最后PaddleGAN作为入门用的工具包还挺好用的,推理的时候也相当方便,模型存储调用基本也写好了,基本只要改动具体config和model就可以。