人脸漫画合成

人脸漫画合成

简单记录一下我的毕业设计。

任务

给定一张人脸图像,把它转化成日本动漫的风格。

数据集

人脸数据集:CelebAMask-HQ是一个大型的人脸图像数据集,它有30,000张高分辨率的人脸图像,下载地址:https://github.com/switchablenorms/CelebAMask-HQ

人脸数据集示例图

动漫数据集:Danbooru ,有14,000张裁剪好的动漫头像,下载地址: https://www.kaggle.com/lukexng/animefaces-512x512

漫画数据集示例图

网络结构

主要借鉴了 CycleGAN。网络有两个生成器,两个判别器,在生成器的输入加入了face-parsing,更改了判别器。符号意义如下:

domain A:人脸 domain B:动漫

Generators: G_A: A -> B;实现从人脸到动漫的迁移 G_B: B -> A 实现从动漫到人脸的迁移
Discriminators: D_A: G_A(A) vs. B; 判断是真实动漫还是生成的假动漫 D_B: G_B(B) vs. A判断是真实人脸还是生成的假人脸

A->B方向网络示意图如下:

B->A类似,不再赘述。

生成器

网络结构没有改动:卷积->上采样*2->resnet _block*9->下采样*2->卷积

输入从3通道变为6通道(photo+face-parsing or anime+face-parsing):face-parsing代表了人脸五官的结构,可以指导生成,降低不配对任务的难度

判别器

改进版PatchGAN的D,将30个patch改为35个,考虑到动漫和人脸在五官比例上是不对应的,比如动漫中的大眼睛、小鼻子,所以这个任务要允许一定变形,要求生成的人脸和人脸解析完全对应反而达不到动漫的效果 。因此,判别器的输入还是三通道,只用判断真假,判别器结构示意图如下:

损失函数

对抗损失:让生成的图片接近真实图片的分布

循环一致性损失:保持内容不变

总损失:

实验设置

数据集制作

为了在CycleGAN上运行我们自己的数据集,要实现一个dataset类并修改train.py,具体做法见代码。

选取了12,000张人脸,28,000张动漫,将人脸图片用BiSeNet进行处理,得到相应的face-parsing结果。然后按8:2的比例划分了训练集与测试集。

实验参数

大部分都是CycleGAN论文里的设置。

试验结果

由于设备和时间的限制,只跑了25个epoch,效果还行就没再训练了,多跑几个epoch应该会有更好的效果。

25_epoch

可以看到,由于face-parsing的输入,生成的图片和人脸在五官位置上还是比较对应的,风格也比较接近动漫,但细节部分还不够好,尤其是鼻子和嘴巴,猜想是因为日本动漫对鼻子和嘴巴的勾勒本来就比较钱,再加上训练次数不够,导致了此问题。未来可以考虑加入注意力机制以提升合成图片的质量。

25_epoch

侧脸、戴帽子等遮挡难度还是比较大,还有一些莫名失败的例子。

一些数据集中没有的,如胡子、眼镜、手指,生成的动漫勉强可以接受。

遇到的一些问题

1.多线程问题

最开始在自己的电脑上测试代码,报错:

CUDA out of memory. Tried to allocate 784.00 MiB (GPU 0; 4.00 GiB total capacity; 456.81 MiB already allocated; 2.47 GiB free; 548.00 MiB reserved in total by PyTorch)

可以看到内存是够用的却不分配,后发现是多线程的问题,num_threads=0解决。

2.D的损失突然接近0,生成图片只剩纹理图

之前以为是学习率太大了,调小后跑了几个epoch还是会出现这种情况。根本原因在于D的性能太好了,生成器学不到什么东西,改进D后这种状况消失了。

3.一些失败的尝试

这里的代码或多或少有点问题,不过还是记录一下。

奇怪的微笑.jpg
全员粉色.jpg
纹理.jpg

猜你喜欢

转载自www.cnblogs.com/iclaire/p/13194155.html