本文为粉丝咆哮的阿杰投稿,介绍了其开发的Morph-UGATIT图像翻译库,欢迎大家使用这个有趣的开源工程。

链接:https://zhuanlan.zhihu.com/p/348124048

前言

大家好,笔者将在本文介绍一种基于UGATIT的图像翻译网络,并且DIY,加入两项额外的trick,使UATIT能支持渐进式的域迁移,即能实现A域的图像样本是如何逐渐向B域迁移的。我们叫该DIY模型为Morph-UGATIT。笔者在该项目的主要工作有:

  • 首先基于UGATIT官方tensorflow源代码,用PyTorch 1:1完美还原,包括网络模型,训练代码,超参数。

  • 在生成器(G)的loss中引入额外的一项:identity preserving loss。

  • 在生成器(G)中,增加MLP,沿用StyleGAN利用w+空间的方式,代替UGATIT生成beta和gamma的方式。

  • 将UGATIT的两个生成器,整合为一个生成器。判别器依然使用两个,分别判别A域和B域的真假。

Note:写在前面,笔者的改进思路,并非完全原创,其借鉴了Eccv2020的一篇论文。文中也会提及。全部代码已经开源,地址在:

https://github.com/shoutOutYangJie/Morph-UGATIT

预备知识

我们先简单回顾一下UGATIT,作为一个Cycle-base图像翻译方法,它和cycleGAN的主要区别在于:

  • 提出CAM loss,CAM loss在G和D中起到的作用也不一样。

  • 提出AdaLIN,自适应改变LN和IN的比例。

https://github.com/taki0112/UGATIT

由于以上两个区别不会导致和CycleGAN framework的巨大差异,为了方便我以下的描述,笔者直接沿用cycleGAN的framework进行描述。CycleGAN的framework大致如下,仅画了从A域向B域迁移的过程,黄色虚线是计算loss,省略了identity loss:

cycle-base GAN (方向:AtoB)

A域的真实样本经过G_A得到假的B域样本fakeB,fakeB经过G_B又从B域向A域迁移,为了是建立cycle consistency loss。优化cycle consistency loss,使得A和B域之间的各个属性mapping能一一对齐,这样就解决了unpair的图像翻译。

同时,A域的样本经过B,直接得到了B域的样本,各位炼丹师们是无法得知,样本是如何从A域变换到B域的。

接下来简单介绍笔者借鉴的另一篇论文。

https://github.com/royorel/Lifespan_Age_Transformation_Synthesis

lifespan age synthesis

该论文是一个unpair multi-domain transfer的图像翻译方法。作者将年龄分成6个段,作为单独的6个域,能实现一个样本在这6个域的连续渐变迁移。巧妙的地方在于,不同于其他face aging(人脸年龄编辑)的cgan方式,作者使用了一个mlp编码年龄向量z,进入到一个隐空间。

不同年龄段的latent code进行插值,用插值之后的latent code生成图像,则图像的效果就介于两个域之间。比如说,该论文选择face aging这个方向实验。数据集中各个年龄被化分为几个段:{0:6},{16:30},...。如果我们想得到{7:15}岁的人脸,则将{0:6}和{16:30}这两个区间对应的latent code进行按比例插值即可。

大家要注意,如果没有这个mlp,现存的方式的做法是,z将会被视作condition,直接送入G中。但是,如果直接在z空间插值,得到z',z'是无法直接起到作用的。因为在训练阶段,G就没有见过z'这种数据分布。在隐空间插值,绕过了这个问题。

这样的话,笔者已经介绍完毕所需要的预备知识。

方法

Morph-UGATIT

overview:Morph-UGATIT直接使用一个生成器完成2个域的迁移。X是生成器的输入,接收来自两个域的样本。Z空间也是两个域分别对应一个随机z向量。如果Z空间输入的是z1,则代表,生成器要生成B域图像;

反之亦然。有两个判别器,分别对生成的A域真or假样本以及B域真or假样本进行判别。同时生成的样本X`,也会在经过一个E,和原始输入X对应的E(X),计算L1 loss,作为identity presevering loss,即希望生成的样本和原始样本的细节接近一致。

Z空间的初始化是依赖于生成器想生成哪个域的样本,如果想生成B域样本,则输入z1;反之亦然。z1和z2的初始化方式也不一样。Z向量是一个64维向量,其初始化方式为:

z1和z2的初始化方式,仅仅在于加1的位置不同,z1在前zdim个位置都加上1,z2则在后zdim个位置上加1。z_dim的值是Z长度的一半,即32(在笔者的实验中)。

看到这里大家也许就明白为何不能在Z空间插值了。因为插值出来的新z‘,不属于两种分布之一,G没有在训练中接收到这种分布,自然没法在测试阶段起到作用。

将两个域用一个生成器实现,以及MLP的应用,都是遵从论文“Lifespan Age Transformation Synthesis”的做法。

笔者认为,原作者首先将Z单独使用,由Z决定生成器要往哪个域上迁移,有助于Encoder(E)学习到A域和B域共同属性的特征,再加上identity preserving loss的作用,进一步约束两个域的相似。

下面以从A域向B域迁移为例子:

  • 初始化一个向量z1,用属于方向"AtoB"的方式新建一个z1。(两个方向,初始化z的方式不一样),送入生成器中。

  • x经过Generator,得到E(x), x', cam_abcam_ab是为了计算cam loss,属于ugatiti论文的做法,不再多说明

  • 重新初始化一个向量z2,把x'和z2都送进生成器,得到x''。

  • 计算对抗loss,恒等映射loss(identity loss),cam loss,cycle consistency loss,以及identity preserving loss。G和D交替优化。

更相似的过程可以参考笔者开源的代码:

https://github.com/shoutOutYangJie/Morph-UGATIT

实验

笔者设置了3组模型。分别在{成人脸,娃娃脸}和{真实人脸,动漫人脸}两种数据集探究Morph-UGATIT的能力。

  • config-A: 使用笔者自己用pytorch复现的UGATIT训练

  • config-B:在config-A的基础上,增加identity preserving loss

  • config-C: 在config-B的基础上,增加MLP学习隐空间

数据集来源:

  • {成人脸,娃娃脸}:来自G-lab开放下载的,由StyleGAN2生成的萌娃数据集,以及StyleGAN生成的成人数据集。(没错,用的生成的假数据训练的。实在没有好的数据来源。)所幸这批数据大部分样本还是很逼真,有些样本的背景包括发尾,颈部以下会失真。

http://www.seeprettyface.com/mydataset.html#adult
  • {真实人脸, 动漫人脸}:来自UGATIT开源的代码中提供的数据集,大家可以自行寻找。目前这个实验正在做,还没有做完。

首先看一下在成人脸向娃娃脸(AtoB)转化,在训练集上的表现。

以下图像按照原图(第一列),config-A(第二列,UGATIT),config-C(第三列,Morph-UGATIT)。因为config-B的视觉效果和config-A差不多,故此省略。

第3列的样本,morph-ugatit生成的脸更像输入人脸

config-A和config-C总体上差不多,也说明UGATIT自身的强大。

受样本分布影响,黑人基本上都转成了白人娃娃

总体来看,在训练集上,config-{A,B,C}差不多,且都存在bad case。config-C在细节的保留上略微好了一丢丢。这里面有两个点需要探讨:

  • 如果不在训练集上测试,config-{A,B,C}的差距会不会拉大。毕竟训练集是做了针对性优化的

  • config-C的CAM如果去除,会不会提升其视觉效果,进一步拉开与config-{A,B}的差距。(笔者木有时间做了)

笔者在网络上搜集了一些名人明星的照片,作为测试集。因为时间及精力有限,仅搜集了几张。这些照片均使用FFHQ规则进行align。

四列按照 原图,config-A, config-B,config-C的排列。

接下来看看在{真实人脸,动漫人脸}数据集上的效果。笔者在UGATIT论文提供的数据集“selfie2anime”上的训练集训练,在测试集测试。由于时间关系,笔者仅仅做了config-A的实验(即笔者自己用pytorch实现的UGATIT)。

消融讨论(ablation discussion)

1.Morph-UGATIT的Encoder是否可以学习到公共的属性,能如笔者所想?

在笔者的实验过程中,意外的发现,cam loss的曲线异常,这算是一个实验的惊喜。笔者搭建的morph-ugatit,是在笔者自己复现的ugatit的基础上完成的,自然保留了CAM这个模块以及对应的loss。

起初笔者并没有思考,在自己DIY的基础上,还需不需要CAM,而是选择直接保留。于是就看到了这样的CAM loss 曲线。

config-C(第一行)和config-B(第二行)的CAM loss曲线。

这里简单回顾一下生成器的CAM loss:

在UGATIT原文中,G中的CAM负责找出最不像目标域的区域,并使用cam的方式强调该区域。CAM loss则优化从源域到目标域得到的置信概率,以及目标域到目标域(恒等映射)得到的置信概率的距离。

CAM loss可以简单理解为:让两个不同域的样本进入相同的Encoder,特征分布要有所区分。我们从上面的曲线图可以看出,config-B的CAM loss都优化都到了接近0的位置。而config-C的CAM loss优化到1300多,就已经要收敛了!!!

这提供了一个事实依据:Morph-UGATIT能够解耦出AB域共同的特征属性。因为config-C的cam loss很早就陷入了拉锯战:一个相同的分布,如何让它被分到两个类别上去?自然无法做到,因此cam loss一直很高,无法下降。

2. 在AB域插值,查看其渐变迁移效果如何。

很遗憾,在{成人脸,娃娃脸}数据集上,AB域的转换非常不平滑。没有论文“lift age transformation synthesis”中的那么好。这里面存在的可能原因将在Extension.3中提及。

A域向B域渐进迁移(从右向左)

在A域逐渐向B域迁移的过程中,可以看出,迁移效果并不稳定。一些中间结果出现了artifacts。迁移的变化,主要体现在面部脸盘变大,发型开始变化,面部细节的变换很生硬,基本是直接跳过去的。

笔者认为,如果A域B域的关键因素(比如年龄)的间隔如果小一些,可能迁移会更加平滑,正如论文“lift age transformation synthesis”展示的效果那样。

另外如果在训练过程中,设置一个新的判别器,用来判别用mix W空间隐向量生成的样本的真伪,在辅助identity preserving loss,以及content loss,push生成结果更加真实,也许能在该数据集上,做到比较真实且平滑的大人脸到娃娃脸之间的迁移。

Extension

1. 在希望编码公共属性的同时,也许我们留出某些通道,去挖掘AB域的不同点,剩下的通道学习AB域的公共属性,让CAM loss只去优化挖掘不同点对应的权重,也许会有更好的视觉效果。

2. 笔者虽然引入了Z空间,但Z空间的作用只为了满足两个域的转换所需要的分布。这导致z的不同并不能生成基于原始A域样本人物的多样性B域样本。如何能让z的变化,带来domain transfer上的变化,也是一个不错的探索方向。

3. AB域的渐进变化,并不平滑。这里可能是因为{成人脸,娃娃脸}年龄相差太大导致。也可能是因为decoder没有完全采用论文“Lifespan_Age_Transformation_Synthesis”中的style-based decoder。

4. 由于用的是L1 loss进行恒定映射,所以导致A域到A域的映射会输出一张模糊的照片,这是L1,L2loss自身的局限性。但因为cycle-base训练方式需要恒定映射,而L1 loss也是最简单的做法。

如果想生成更真的恒定映射结果,或许可以用content loss(vgg loss)以及将恒等映射的结果也送到判别器,参与训练,说不定可以解决该问题。同理,cycle loss需要的recA,recB也是可以用同样的做法。

5. 在训练过程中,设置一个新的判别器,用来判别用mix W空间隐向量生成的样本的真伪,在辅以identity preserving loss,以及content loss,以此来push生成结果更加真实,也许能在{大人脸,娃娃脸}上,做到比较真实且平滑的大人脸到娃娃脸之间的迁移。

总结

  • cycle-based的domain transfer,还是尽量对齐数据集的分布,就拿人脸数据集来说,男性女性分开,前景背景分离,以及侧脸正脸区分,都是有助于模型的收敛。我在实验的时候发现,对于侧脸的情况以及带眼睛(墨镜)的情况,生成器倾向于生成正脸,但脸部的边缘又有侧脸情况的重影(导致视觉效果假),墨镜则被完全移除。

  • identity preserving loss的一个副作用,就是让生成器过度关注人脸面部,而忽略的其他细节的合理性:比如假样本娃娃域的耳朵实在是太大了(哈哈)

  • identity preserving loss并不是让Encoder学习公共属性的关键,而是引入MLP,将域的转换依赖于Z空间分布,并且让Encoder接收来自不同域的样本,迫使encoder学习公共属性。因为config-B也使用了identity preserving loss,但是CAM loss 一样优化到了很低.

  • Morph-UGATIT中,生成器的CAM loss虽然经过实验得知,没有必要保留,但笔者开源的代码中还是留存了;笔者也不会再去花费时间验证去除G中CAM loss的效果。但如果去除掉CAM,会不会有视觉效果的提升呢?

  • 男性转化的难度比女性大。

limitation

bad case基本出现在两种情况:极大侧脸以及带了面部装饰。

END

备注:GAN

GAN

生成对抗网络、GAN等技术,

若已为CV君其他账号好友请直接私信。

我爱计算机视觉

微信号:aicvml

QQ群:805388940

微博知乎:@我爱计算机视觉

投稿:amos@52cv.net

网站:www.52cv.net

在看,让更多人看到  

Morph-UGATIT:一种支持渐进式域迁移的图像翻译方法相关推荐

  1. CVPR 2019 论文解读 | 基于多级神经纹理迁移的图像超分辨方法 (Adobe Research)

    基于多级神经纹理迁移的图像超分辨方法 超分辨(Super-Resolution)图像恢复旨在从低分辨模糊图像中恢复出高分辨的清晰图像,是计算机视觉中的一个重要任务,在工业界有非常强的应用前景.CVPR ...

  2. matlab 图片倒影_一种精确快速处理液滴铺展图像的方法与流程

    本发明涉及液滴动力学领域,具体是一种精确快速处理液滴铺展图像的方法. 背景技术: 液滴撞击壁面现象出现在很多行业中,例如航空航天,农业,工业中的喷淋和印刷等.研究液滴撞击壁面的铺展过程对研究液滴与壁面 ...

  3. 2020年,多源域适应(域迁移) MDA最新方法总结综述

    推荐小王爱迁移知乎系列 https://zhuanlan.zhihu.com/p/66130006 2020年,多源域适应MDA最新方法总结综述 Multi-source Domain Adaptat ...

  4. 同源策略_如何支持跨域

    欢迎大家阅读<朝夕Net社区技术专刊> 我们致力于.NetCore的推广和落地,为更好的帮助大家学习,方便分享干货,特创此刊!很高兴你能成为忠实读者,文末福利不要错过哦! 01 PART ...

  5. CVPR2020/UDA/图像翻译-Cross-domain Correspondence Learning for Exemplar-based Image Translation基于范例的跨域对应

    Cross-domain Correspondence Learning for Exemplar-based Image Translation基于范例的跨域对应学习的图像翻译 0.摘要 1.概述 ...

  6. 数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案...

    为什么80%的码农都做不了架构师?>>>    版权声明:本文由本人撰写并发表于2012年9月份的<程序员>杂志,原文题目<一种支持自由规划的Sharding扩容方 ...

  7. 两种可以支持跨域的方式 - 讲解篇

    针对项目:vue.js + Express 本例的vue.js项目使用Express框架作为后台数据服务端 什么叫做跨域? 通常情况下是指两个不在同一域名下的页面无法进行正常通行,或者无法获取其他域名 ...

  8. 直播 | ICML 2021论文解读:满足隐私保护要求的去中心化无监督域迁移范式

    「AI Drive」是由 PaperWeekly 和 biendata 共同发起的学术直播间,旨在帮助更多的青年学者宣传其最新科研成果.我们一直认为,单向地输出知识并不是一个最好的方式,而有效地反馈和 ...

  9. CSS完美实现iframe高度自适应(支持跨域)

    https://blog.csdn.net/qq_32915337/article/details/79900222 Iframe的强大功能偶就不多说了,它不但被开发人员经常运用,而且黑客们也常常使用 ...

最新文章

  1. android native堆内存泄露,Android Native内存泄露检测
  2. 围观各大企业如何活用人工智能,并运用实践?
  3. VLAN+DHCP(1)(附抓包)
  4. 地球椭球体(Ellipsoid)、大地基准面(Datum)及地图投影(Projection)三者的基本概念
  5. IDC机房运行安全评测怎么做,自建IDC机房评测材料准备要点
  6. go linux环境搭建,Linux 下 Go 环境搭建以及 Gin 安装
  7. border,padding,margin盒模型理解
  8. 推荐一个wpfsliverlight的图表控件
  9. 【音效处理】Delay/Echo 简介
  10. goland 2019.1.1破解
  11. [改善Java代码]强制声明泛型的实际类型
  12. 【erlang ~ 4 days】 Day # 1.1 History
  13. iOS资源大全中文版
  14. c语言程序代码分享,一些简单的C语言程序代码(最新整理)
  15. 哈希库--uthash的详细讲解(附uthash相关头文件下载)
  16. 用python的tkinter做游戏(九)—— 坦克大战 正式篇
  17. zebradesigner2教程_ZebraDesigner快速使用说明
  18. HDMI是什么设备与计算机连接的接口类型,Type-C、HDMI及DP视频接口有什么区别?电脑显示器连接线如何选?...
  19. 企业邮箱的优势有哪些
  20. 花开的地方在希尔的故乡,听着远古的战歌仿佛生在花开的地方

热门文章

  1. Eigen--Matrix
  2. CSDN-Markdown--基本语法功能效果
  3. 匹配指定内容的div_HTML背景色教程–如何更改Div背景色,并通过代码示例进行了说明...
  4. c++循环执行一个函数_javascript的五种循环,作为程序员,要根据场景和性能作出选择
  5. 移动端点击拉起输入_耐用的筛分式移动破碎站
  6. java final 初始化_[转]java static final 初始化
  7. esxi 安装网卡驱动
  8. cad一键标注闭合区域lisp_CAD快捷键大全,你值得学会!
  9. php数据库连接程序,常用的数据库连接程序
  10. ajax json 封装,Ajax--json(Ajax调用返回json封装代码、格式及注意事项)