调教神经网络来生成老婆(划掉)动漫头像的一些尝试(一)

GAN在生成逼真的人脸等图像已经有了很多报道了。但传统的GAN有个严重的问题,就是输出的分辨率太低。最近的ProGAN和StyleGAN引入了从低分辨率开始,逐渐提升分辨率的训练方法,终于可以生成512×512,甚至1024×1024的逼真图像。从而引发了一系列报道,以及一系列的xx doesn’t exist的网站 [person] [cat] [airbnb] [waifu]。对肥宅而言(划掉),其中尤其引人瞩目的是Gwern Branwen生成动漫头像方面的实验数据集。这个数据集包含了330万张的动漫图像,每个图像有人打的tag,投票数,缩略图和原图,感觉是个不太难(相对低维)但又有现实意义的数据集,很适合用来点StyleGAN这个技能点。所以在这方面做了一些实验。

StyleGAN生成的动漫头像

首先我试图复现Gwern在生成动漫头像方面的一些结果,比如只生成炮姐(动漫某科学的超电磁炮)的头像。为了实现这一点,最简单的思路就是,只把炮姐的头像扔给GAN去学就好了。这里面有两个困难,第一,下下来的数据集是全身的图,应该怎么办?直接扔进去还是先做人脸识别再扔;第二,怎么从330万张图找到炮姐的图呢?

做一些简单的调研就可以发现,Gwern其实已经尝试了把全身图扔给GAN训练了。不晓得是参数没调好还是全身图太复杂了学不出来,出来的结果非常鬼畜(见下),双头人,六腿人什么的(如果接受了这个设定的话,想想看好像还挺带感?)。我们如果只用炮姐训练的话,图像更少更不可能学出来了。所以没得选,只能做人脸检测。

鬼畜的全身训练结果

但如果用开源的DNN跑一把的话会发现,在真人身上训练的人脸检测模型在动漫上面完全没反应,毛都检测不出来。好在有好心人已经在动漫上训练好了传统的Viola人脸检测器。直接拿来跑就好。在缩略图上recall不是很高,大概只有50%。

人脸检测后的训练数据

至于怎么拿到超电磁炮的图,直接根据tag搜就好。cat metadata/* | grep railgun一行搞定(话说从电磁炮的原理来说,炮姐应该叫coilgun而不是railgun。。(逃。然后检测人脸,缩放至统一大小,用StyleGAN自带的工具转成TensorFlow record格式就可以开训啦。

训练过程的可视化。图片较大。

训练的过程大概如上图所示。可以看到分辨率的确是逐步升高的,相对来说也比较靠谱。但当分辨率一高以后,生成的图像有大量的ringring artefact(振铃?)。loss很难再降下去。这可能说明我们的数据量还是过小(只有约5000张人脸),无法支撑高分辨率的模型。那怎么办呢?

一个直观的思路就是现在大规模数据上pretrain,然后过来finetune了。这么实践以后效果好了很多。一个GAN生成的例子如下图所示。

GAN生成的图片

可以看到图像的质量和分辨率都比从零开始训练高了很多。但还是有些地方比较奇怪。。比如左上那个红脸炮姐是什么鬼!左下那个没眼睛的又是怎么回事!要理解这个的原因,需要把训练的过程给可视化出来。如下图,最左边是刚开始finetune时候的图像,逐渐往右是同样的latent vector经过训练过程中的网络生成的图像:

finetune过程的可视化

第一行最开始是一个和炮姐比较类似的角色,脸型,发色,瞳色都差的不远。所以比较顺畅地在几个epoch之后就学到了炮姐的特征,后面连细节比如头顶的发饰都学出来了,这是个正例。第二行是个比较有意思的例子。刚开始的画风是低龄向,说明在latent space里面这一块区域的语义可能是低龄(换言之如果往这个方向走可以把正常向的图年龄降低)。然后随着学习的进行,在10个epoch以后从这块采样出来的图像虽然具有了炮姐的面部特征,但还是幼儿版炮姐。从训练数据的角度来说,这种图片是非常非常少的,一方面动画中幼年版炮姐几乎没什么镜头(最后之作魔禁中才出场),一方面手工检查训练数据也可以确认没有什么萝莉版炮姐的奇怪数据。所以这是GAN通过结合其他大量的预训练的数据,自己推导出了非常自然的炮姐幼年时的长相/画风。这和我们在普通人脸里面看到的观察是一致的——我们可以通过GAN来生成一个人年老或者年轻时候的样子。而这个finetune的过程启发我们,为了让这种模拟更逼真,我们可以用这个人的很多图片(哪怕都是一个年龄段的也可以)来finetune一个在大规模数据集上预训练好的模型,然后就采样原来特征的latent space,比如年轻/年老/卷发/谢顶,生成的图片很可能就是这个人在这种给定特征下的模拟图。(不finetune直接采样行不行呢?效果会更差。我们下篇文章详细叙述。)

下面三行主要是想看在画风极度不同的情况下finetune会有什么反应。比如第三行可能是恐怖/黑化向。可以看到优化算法再把网络不停地往炮姐的方向赶,所以网络困惑了相当一段时间,生成了一些非常沙雕的图,然后终于幡然醒悟开始往炮姐的方向靠。但因为童年的黑暗记忆实在是太深刻了,还是给这个似乎是炮姐和黑子混合物的东西带上了一抹赤红的肤色。。可能这块latent space就是红吧。。第四第五行的表现都是比较类似的。第四行也崩了一段时间,然后终于反应过来自己的归宿其实是食蜂。可以看到网络先是把发型发色弄对了,然后把嘴的形状整明白了,最后开始调整细节比如食蜂特色的星星眼。第五行是大眼萝莉,值得注意的是网络在训练过程中出现了摇摆,先是往炮姐的方向走,然后又变成食蜂。类似的情况也出现在第六行,先是往初春的方向优化,然后突然头发变长变成了佐天的样子。这说明整个SGD的过程中不同区域之间还是会相互影响,latent space的语义是会互相干扰转变的。因为高分辨率StyleGAN的训练需要很长时间(比如FFHQ单卡V100需要一个月),所以我也没有训完。相信如果再有一周时间训练会有更加逼真自然的结果。

那么在这篇文章中,我们简单介绍了如何用动漫数据集来调教神经网络来生成逼真的动漫头像。对finetune过程的可视化可以带来一些很有意思的结论。在下一篇文章中,我们会继续介绍如果有一张图像,如何在GAN中找到它对应的latent variable,以及进一步寻找相关的latent direction来生成不同年龄/性别/肤色等要素的人脸。

更新:第二部分戳这里

来源:知乎 www.zhihu.com

作者:grapeot

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。
点击下载