FUNIT: Few-Shot Unsupervised Image-to-Image Translation
project:https://nvlabs.github.io/FUNIT/
作者:陈扬

在人工智能“造假”领域有着三大“邪术”: “AI 换脸术”Deepfake 、“无中生有术”StyleGAN,和“造假神术”CycleGAN 与 StarGAN 。其中,“造假神术”大小通吃:大,可以让你把风景照随意变成大师的油画;小,可以让你按心情给自拍换个造型,染个头发,改个表情。这便是“图像风格迁移”。

但是,如绝大多数机器学习领域一样,人工智能“造假”的成本可不低。一个成熟的模型是由大量训练数据“喂”出来的。训练样本不够,模型吐出来的只能被称为“半成品”。

近日,英伟达的研究科学家刘洺堉等人,发明了一个称为 FUNIT (Few-shot Unsupervised Image-to-image Translation)的小样本非监督图像转换模型,只需少量样本(几张照片),就能将一张新图片中的一些姿势、五官分布等特征转换到这些样本图上。 赋予AI 可以媲美人类的“脑补”能力:“看几眼”新物种,便能“推测”出新物种某些(与新图片一致的)动作姿势,就像有人第一眼看到独角兽,便能想象它怎样奔跑。

图为输入吐舌歪头杀的金毛以及两张模型训练集中未出现过的新动物图像,输出吐舌歪头杀的新动物(来源:Ming-Yu Liu, et al./ nvidia)

对比其他非监督图图转换,FUNIT 一枝独秀,不仅秀在所需目标样本极少,而且秀在适用广,输入两张图像,从二狗子到猫主子,从小野豹到虎大爷,无不乖巧听话被转换。

FUNIT 模型框架

与其他各种“造假”模型一样,FUNIT 的本质也是生成对抗网络(GAN),但它改进了传统 GAN 的结构,并推出了一个独特的网络框架。模型由两部分组成:条件图像生成网络(Conditional image generator)和多任务对抗判别网络(Multi-task Adversarial Discriminator criminator)。

首先是条件图像生成网络,它的功能类似传统 GAN 中的 G,既生成网络。它的输入为一张“内容图”和一组“类别图”,输出则会在结构上与内容图类似,但在类别上与类别图一样,实现图像风格转移。

举个例子:如果内容图为一只张嘴吐舌的狗,而类别图是小狐狸的正脸与侧脸,输出的便是张嘴吐舌的小狐狸。

训练时,条件图像生成网络在内容图和类别图上进行如此的转换,而测试时,类别图是训练集中从未出现的图像(即未见过的动物),期望输出未见过动物的新动作。

在具体结构上面,条件图像生成网络是由内容编码器(Content encoder)、类别编码器(Class encoder)、解码器(Decoder)三部分组成。

内容编码器含有 4 个二维卷积层和 2 层残差网络,将内容图像映射成内容编码。

类别编码器含有 5 个二维卷积层和 1 个均值池化,分别将每个类别图像进行向量化,再取均值作为类别编码。

解码器含有多个自适应实例标准化残差网络(AdaIN Residual Blocks),即残差网络模型利用 AdaIN(Adaptive Instance Normalization)做归一化层。AdaIN 是风格迁移模型中的一个手段,本质是对 Instance Normalization(实例标准化)的改进,可以进行任意风格的图像迁移。除此之外,解码器还存有多个卷积层,将内容编码做仿射变换(即风格迁移,仿射变换的参数由类别编码经过全连接层变换得到),得到具有内容图像特征的类别图像类似图。通俗来讲,编码解码后实现了将豹哥(抽取类别图像猎豹面部特征)转换成大眼卖萌的猎豹(内容图像是大眼卖萌狗子)。

图为小样本图像转换网络模型的三个子模型结构(来源:Ming-Yu Liu, et al./ nvidia)

多任务对抗判别网络的功能与传统GAN 中的 D,既判别网络类似。它需要判断图像是真实图像还是条件图像生成网络产生的转换图像。无论是哪种图像,判断失败都会加大惩罚,即加大损失函数,通过最小损失来逼生成网络的转换图像越来越逼真。而与传统的判别网络不同,FUNIT 的判别模型为 Patch GAN discriminator,有 1 个卷积层和 10 个残差网络 ,和直接输出真伪的传统判别网络相比,Patch GAN 判别网络的输出是一个 NN 矩阵,每个矩阵元素代表对输入的某一图块的真伪判断。

训练与测试结果

FUNIT 模型在训练时会抽取内容图像的特征,生成具有该特征的他类动物。比如在训练过程中,将侧脸的狗子抽取,生成了长毛狗的侧脸。在模型足够泛化后进行测试时,仅用几张训练集中不存在的新图像作为类别图像(如猎豹),使用大眼卖萌汪的内容图像特征,便收获了猎豹的卖萌凝视。AI 此时便获得了“实用的想象力”,它凭借已看过的狗狗卖萌,在看几眼新动物——猎豹时,就知道猎豹的卖萌模样。

图为FUNIT 模型训练过程和测试过程(来源:Ming-Yu Liu, et al./ nvidia)

在试验中,FUNIT 每次都可以使用极少的样本成功抽取特征,展现出可媲美人类的想象能力。

看见新狗子能知道它怎么伸脖子,看见新猫咪能知道它怎么伸舌头,看见新鸟知道它怎么叉腿儿,即使训练集中从未出现,测试集出现类别图像 y1、y2 两张图,就能根据内容图 X,成功输出类似的图,可以说很强了。

图为FUNIT 对小样本输入图像的成功动作转换,将输入的两张图像 y1、y2 赋予 x 的动作。(来源:Ming-Yu Liu, et al./ nvidia)

此外,FUNIT 还优于现有最佳的非监督图图转换模型StarGAN。

测试结果最右侧的 FUNIT 结果说明,即使训练集中没有目标图像(即以前没见过汪 y1,y2),当测试集中出现 y1,y2 时(即看见新汪),可以成功模拟出新汪内容图像(Input x)做的动作,而 StarGAN 在训练集中无新汪,即因为 FUNIT 也没见过新汪的 Fair(公平)结果时,输出图根本不是新汪在做动作。而 StarGAN 在训练集有新汪,即 Unfair(不公平)结果时,勉强输出了信息,但仍有点怪怪的,显然被 FUNIT 甩 n 条街。

图为FUNIT 和训练集加入目标图像的 StarGAN、训练集未加入目标图像的 StarGAN 对比(来源:Ming-Yu Liu, et al./ nvidia)

介于 FUNIT 模型无需大量目标图像数据即可实现对内容图像的模拟,且泛化很强,它的使用前景极其广泛。想象一下,如果有一个拍你几张照片后,就能轻松把你的特征根据一张新照片进行替换的手机 APP,可以轻松模拟各种造型的美妆、服装、发型,哪些整容爱好者岂不是会爽翻天。

参考网址:

https://nvlabs.github.io/FUNIT/
https://cloud.tencent.com/developer/article/1428621
https://www.toutiao.com/a6694117157430624779/
————————————————
版权声明:本文为CSDN博主「zaf赵」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zaf0516/article/details/103298511

简介

无监督的图像到图像转换方法学习利用图像的非结构化(UNlabel)数据集将给定类中的图像映射到不同类中的类似图像。在ICCV2019上,NVIDIA-Lab发表了Image-to-image最新的研究成果,基于少量类别学习的FUNIT.笔者在CVPR2020的投稿中正好也大量涉及到了image2image的实验,其中样本不均衡是对unpair-image2image任务来说同样是一个很大的问题,而few-shot Learning则是其中一种极端情况.于此同时,paper中令我影响深刻的是作者做了大量的Ablation Study ,充分的实验证明了算法的有效性以及鲁棒性.


前言

在我们展开深入理解FUNIT之前,我们来看一下他的前身UNIT,由NVIDIA-Lab在2017年提出,该文章首次提Image-Image Translation这个概念,将计算机视觉和计算机图形学的许多任务总结进去,分为一对多和多对一的两类转换任务,包括CV里的边缘检测,图像分割,语义标签以及CG里的mapping labels or sparse user inputs to realistic images.

该文章定义了  和  作为两个图像域.传统的supervised Image-to-image 通过对图像域进行采样,求其联合概率分布  ,通过Encoder-Decoder的思想,作者定义了两个E和G,希望使得z=E(X)在latent space上近可能的分布一致.意味着当我们同时对  时,我们希望得出:

这样,我们得到了两个Domain下image的一致表示,再通过令  ,从latent space中重构  ,

因此,我们两个采样下的  经过  ,再把:

通过Adv_loss对抗学习跨域生成图片的效果.

可能细心的你以及发现了这是不是很类似VAE-GAN吗?是的.

作者通过联合训练4个网络  的三个  来训练整个网络:

VAE的目标是minimize source domain to latent space's KL diversity and latent space to destination domain's KL diversity(我觉得中文太拗口了,这句话实在是说不来)来最小化变分上界,VAE的定义如下:

对抗:GAN_LOSS被用于确保翻译图像类似图像在目标域.定义如下:

循环一致性:由于shared latent-space假设暗含了循环一致性约束,因此我们在提出的框架中实施循环一致性约束,以进一步规范不适定的无监督图像间转换问题。产生的信息处理流称为循环重建流,定义如下:

训练好的网络,我们可以通过对latent sapce的latent variable重编码,进而把输入图像迁移到各个域中:


few-shot

虽然UNIT以及其变种(cycleGAN等等)已经表现得非常成功,现有的无监督图像到图像转换模型在两个方面受到限制。首先,如果在训练时只给出很少的图像,它们的样本效率低,产生差的转换输出。

其次,学习的模型仅限于在两个类之间转换图像。尽管新任务与原始任务之间存在相似性,但是用于一个转换任务的训练模型不能直接重用于新任务。

例如,即使猫与老虎有很大的相似性,也不能将哈士奇与猫的转换模型重新用于哈士奇 与老虎的转换。

同样,作者通过few-shot学习得到的图像同样可以应用于少样本分类,在Ablation Study中作者做了非常详细的比较,进而验证其有效性.


算法描述

前提假设:为了训练 FUNIT,我们使用来自一组对象类(例如各种动物物种的图像)的图像,称为源类。我们不假设任何两个类别之间配对图像的存在.

使用源类图像来训练多级无监督图像到图像的转换模型。

在测试过程中,我们为模型提供了 一些来自新对象类的图像,称为目标类。该模型必须利用少 数目标图像将任何源类图像转换为目标类的同类图像。

框架由条件图像生成器 G 和多任务对抗判别器 D 组成。它采用一个图像作为输入,我们的生成 器 G 同时采用内容图像  和一组类别图像K:{  }作为输入,并通过生成器G产生输出图像:

我们将 G 称为少样本图像转换器。G 将输入内容图像  映射到输出图像  ,使得 x 看起来像属于对象类  的图像,并且  和  具有纹理结构上的相似性。设  和  分别表示源类集和目标类集。训练时,  在测试时,G 从未看到的目标类  获取一些图像作为类图像,并将从任何源类采样的 图像映射到目标类  的类似图像。

多任务对抗判别器

判别器 D 通过同时解决多个对抗分类任务来训练。 每个任务是二分类任务,确定输入图像是源类的实际图像还来自 G 生成的转换输出.这个对抗训练实际上是类似前面提到过的,不在赘述.


框架设计

少样本图像转换器由三个子网络组成:内容编码器  (Content Encoder),  类编码器(Class Encoder)和  解码器(Decoder).

内容编码器由几个 2D 卷积层组成,后跟几个ResBlock。它将输入内容图像 x 映射到内容潜码  ,其代表空间特征映射。

class ContentEncoder(nn.Module):def __init__(self, downs, n_res, input_dim, dim, norm, activ, pad_type):super(ContentEncoder, self).__init__()self.model = []self.model += [Conv2dBlock(input_dim, dim, 7, 1, 3,norm=norm,activation=activ,pad_type=pad_type)]for i in range(downs):self.model += [Conv2dBlock(dim, 2 * dim, 4, 2, 1,norm=norm,activation=activ,pad_type=pad_type)]dim *= 2self.model += [ResBlocks(n_res, dim,norm=norm,activation=activ,pad_type=pad_type)]self.model = nn.Sequential(*self.model)self.output_dim = dimdef forward(self, x):return self.model(x)

类编码器由几个 2D 卷积层组成,后面是样本轴平滑操作。具体地说,它首先映射 K个类别图像  映射到中间潜在向量,然后计算中间潜在向量的平均值,以获得最终的潜码  。

class ClassModelEncoder(nn.Module):def __init__(self, downs, ind_im, dim, latent_dim, norm, activ, pad_type):super(ClassModelEncoder, self).__init__()self.model = []self.model += [Conv2dBlock(ind_im, dim, 7, 1, 3,norm=norm,activation=activ,pad_type=pad_type)]for i in range(2):self.model += [Conv2dBlock(dim, 2 * dim, 4, 2, 1,norm=norm,activation=activ,pad_type=pad_type)]dim *= 2for i in range(downs - 2):self.model += [Conv2dBlock(dim, dim, 4, 2, 1,norm=norm,activation=activ,pad_type=pad_type)]self.model += [nn.AdaptiveAvgPool2d(1)]self.model += [nn.Conv2d(dim, latent_dim, 1, 1, 0)]self.model = nn.Sequential(*self.model)self.output_dim = dimdef forward(self, x):return self.model(x)

解码器由几个自适应实例正规化(AdaIN)和残差块Resblock组成,后面跟着一些上 采样卷 积层。 AdaIN 残余 块是使用 AdaIN [18]作为正则化层的残余块。对于每个样本,AdaIN 首先将每个通道中样本的激活函数标准化为零均值和单位方差。然后它会缩放激活使用一组标量和偏置组成的学习仿射变换(通过两层全连接网络FC,使用自适应地计算仿射变换参数)。

class Decoder(nn.Module):def __init__(self, ups, n_res, dim, out_dim, res_norm, activ, pad_type):super(Decoder, self).__init__()self.model = []self.model += [ResBlocks(n_res, dim, res_norm,activ, pad_type=pad_type)]for i in range(ups):self.model += [nn.Upsample(scale_factor=2),Conv2dBlock(dim, dim // 2, 5, 1, 2,norm='in',activation=activ,pad_type=pad_type)]dim //= 2self.model += [Conv2dBlock(dim, out_dim, 7, 1, 3,norm='none',activation='tanh',pad_type=pad_type)]self.model = nn.Sequential(*self.model)def forward(self, x):return self.model(x)class MLP(nn.Module):def __init__(self, in_dim, out_dim, dim, n_blk, norm, activ):super(MLP, self).__init__()self.model = []self.model += [LinearBlock(in_dim, dim, norm=norm, activation=activ)]for i in range(n_blk - 2):self.model += [LinearBlock(dim, dim, norm=norm, activation=activ)]self.model += [LinearBlock(dim, out_dim,norm='none', activation='none')]self.model = nn.Sequential(*self.model)def forward(self, x):return self.model(x.view(x.size(0), -1))

生成器整体代码:

class FewShotGen(nn.Module):def __init__(self, hp):super(FewShotGen, self).__init__()nf = hp['nf']nf_mlp = hp['nf_mlp']down_class = hp['n_downs_class']down_content = hp['n_downs_content']n_mlp_blks = hp['n_mlp_blks']n_res_blks = hp['n_res_blks']latent_dim = hp['latent_dim']self.enc_class_model = ClassModelEncoder(down_class,3,nf,latent_dim,norm='none',activ='relu',pad_type='reflect')self.enc_content = ContentEncoder(down_content,n_res_blks,3,nf,'in',activ='relu',pad_type='reflect')self.dec = Decoder(down_content,n_res_blks,self.enc_content.output_dim,3,res_norm='adain',activ='relu',pad_type='reflect')self.mlp = MLP(latent_dim,get_num_adain_params(self.dec),nf_mlp,n_mlp_blks,norm='none',activ='relu')def forward(self, one_image, model_set):# reconstruct an imagecontent, model_codes = self.encode(one_image, model_set)model_code = torch.mean(model_codes, dim=0).unsqueeze(0)images_trans = self.decode(content, model_code)return images_transdef encode(self, one_image, model_set):# extract content code from the input imagecontent = self.enc_content(one_image)# extract model code from the images in the model setclass_codes = self.enc_class_model(model_set)class_code = torch.mean(class_codes, dim=0).unsqueeze(0)return content, class_codedef decode(self, content, model_code):# decode content and style codes to an imageadain_params = self.mlp(model_code)assign_adain_params(adain_params, self.dec)images = self.dec(content)return images

通过使用这种转换器设计,我们的目标是使用内容编码 器提取具有类不变的潜在表示(例如,对象姿势)并使用类编码器提取类特定的潜在表示(例如,对象外观)。通过经由 AdaIN 层将类别潜码馈送到解码器,我们让类图像控制 全局外观(例如,对象外观),而内容图像确定局部结构(例如,眼睛的位置)。


损失函数的设计

我们通过解决由下式给出的极小极大优化问题来训练所提 出的 FUNIT 框架:

其中  ,  和  分别是 GAN 损失,内容图像重建损失和特征匹配损失。

对抗损失仅使用类的相应二分类预测分数来计算损失。

内容重建损失有助于 G 学习转换模型。 具体地,当对输入内容图像和输入类图像使用相同图像时(在这种情况下 K = 1),损失促使 G 生成与输入相同的输出图像(重构一致性,在cycleGAN在叫identity Loss).

特征匹配损失使训练正常化。 我们首先通过从 D 重新移 动最后一个(预测)层来构造一个特征提取器,称为  。 然后我们使用  从转换输出  和 类图像
 中提取特征并最小化 :


实验部分

我非常想重点讲一下实验部分,我看完这篇文章的实验部分做的太好了,给了我在今后的科研中一个非常好的榜样.

重点说一下评价指标啊,在image-to-image这个领域据我所知,肉眼观察法是最好的评价指标,但是他也会带来一些个人的主观性,我们看看作者是如何通过实验说服我的:

先放一张漂亮的大图:

性能指标。作者使用几个标准进行评估。首先,作者测量转换是否类似于目标类的图像。其次,作者检查在转换期间是否保留了类不变内容。第三,作者量化输出图像的写实照片。最后,作者测量该模型是否可用于生成目标类的图像分布。

量化对比:User performance score(肉眼观察法):

少样本分类准确度:

Inception Score(我很困惑这个指标真的有用吗?)和FID(这个确实还有点用):

Ablation Study

(都能坚持看到这里了都,我觉得英文说得更明白了 ):

we analyze the impact of the content image reconstruction loss weight on the Animal Faces dataset. The table shows that λR = 0.1 provides a good trade-off, and we used it as the default value throughout the paper. Interestingly, a very small weight value λR = 0.01 results in degrading performance on both content preservation and translation accuracy.

Latent Space Interpolation

we use t-SNE to visualize the class code in a two dimensional space. It can be seen that images from similar classes are grouped together in the class embedding space.

we find that by interpolating between two source classes (Siamese cat and Tiger) we can sometimes generate a target class (Tabby cat) that the model has never observed. This suggests that the class encoder learns a general class-specific representation, thus enabling generalization to novel classes.

总结

这篇文章很好的结合了few-shot解决UNpair image-to-image的样本不均衡的问题,更重要的是其及其接近实际的生产应用环境,是一篇无论是从理论上还是实际应用角度出发来看,都具有重大指导意义的文章,笔者同样很喜欢这个工作.

如果您是一位C9高校的老师,看到了这篇文章,可以在知乎上联系我,笔者目前正就读于中国海洋大学计算机科学与技术专业,发表CCF_C类一作一篇, SCI_1区3作,一篇文章在投,希望有大佬把我领走了(-╹▽╹-).

深入理解风格迁移三部曲(三)--FUNIT相关推荐

  1. StyleTransferTrilogy 风格迁移三部曲

    目录 固定风格固定内容的普通风格迁移 VGG16 内容 风格 Gram 矩阵 风格损失 训练 效果 固定风格任意内容的快速风格迁移 模型 ConvLayer ResidualBlock Transfo ...

  2. TensorFlow练手项目三:使用VGG19迁移学习实现图像风格迁移

    使用VGG19迁移学习实现图像风格迁移 2020.3.15 更新: 使用Python 3.7 + TensorFlow 2.0的实现: 有趣的深度学习--使用TensorFlow 2.0实现图片神经风 ...

  3. 风格迁移-风格损失函数(Gram矩阵)理解

    吴恩达教授卷积神经网络的课程中,有一部分是关于风格迁移的内容.组合内容图片,风格图片生成新的图片 主体思路是: 随机生成一张图片(可以基于原内容图片生成,从而加速训练) 计算其与内容图片之间的内容损失 ...

  4. 深度学习实战(一)快速理解实现风格迁移

    前言 Gatys大神之前发表了一篇利用风格迁移进行作画的文章,让普通的照片具有名人的画风,效果如下: 让一篇普通的图片有了梵高的风格,厉害了. 文章链接:A Neural Algorithm of A ...

  5. 三个前端浏览器图片制作-风格迁移,图片压缩,照片动漫化

    原文链接:https://dsx2016.com/?p=1821 公众号:大师兄2016 风格迁移 https://github.com/reiinakano/arbitrary-image-styl ...

  6. AnimeGANv2 实现动漫风格迁移,简单操作

    作者 | Yunlord 出品 | CSDN博客 前言 之前一直在研究如何将图像动漫化,尝试了阿里云api和百度api,效果都不尽如人意.结果发现了一个宝藏github项目--AnimeGANv2,能 ...

  7. python神经结构二层_《python深度学习》笔记---8.3、神经风格迁移

    <python深度学习>笔记---8.3.神经风格迁移 一.总结 一句话总结: 神经风格迁移是指将参考图像的风格应用于目标图像,同时保留目标图像的内容. 1."神经风格迁移是指将 ...

  8. 一文详解计算机视觉的广泛应用:网络压缩、视觉问答、可视化、风格迁移等

    作者 | 张皓(南京大学) 来源:人工智能头条丨公众号 引言 深度学习目前已成为发展最快.最令人兴奋的机器学习领域之一,许多卓有建树的论文已经发表,而且已有很多高质量的开源深度学习框架可供使用.然而, ...

  9. 【NLP】NLP文本风格迁移,秒变金庸风

    NewBeeNLP公众号原创出品 公众号专栏作者@山竹小果 风格迁移是自然语言生成领域一个非常火的主题,对于文本风格迁移,先举个例子: Input:谢谢 Output(金庸):多谢之至 Input:再 ...

最新文章

  1. 【高并发】又一个朋友面试栽在了Thread类的stop()方法和interrupt()方法上!
  2. SAMBA的一些特殊设置
  3. 75 Zabbix中文乱码问题
  4. 利用IE8开发人员工具调试JavaScript脚本
  5. 《苏醒之路》制作人王鲲:独立游戏如何成功出海?
  6. 转载:售前十年,你在第几年
  7. Codeforces Round #655 (Div. 2) E. Omkar and Last Floor 区间dp + 巧妙的状态设计
  8. 每日一题:leetcode341.扁平化嵌套列表迭代器
  9. C++学习之路:适合C++新手的练手项目,高薪之路必备项目!
  10. css固定姓名显示长度,排列更整齐
  11. mysql怎么递归查询下级_mysql递归查询上下级
  12. 百度地图API的IP定位城市和浏览器定位
  13. NodeJS开发简易图书管理系统
  14. iis6.0 index.php,IIS6.0下Wordpress 去掉 index.php 和 category 的方法小结
  15. Android Studio 安装AVD (处理器为AMD)图文详解
  16. 谈小米内忧外患的困境
  17. uniapp中唤醒支付宝,微信进行支付并返回app
  18. 禅道的安装使用和升级
  19. 【02月25日】【精彩电影合集】【15部】【亲测】【Lsyq5647发布】
  20. 判断两个时间区间是否存在交集-Java实现

热门文章

  1. everything每次打开都会扫描_每次启动车,转方向盘都会咔一下,咋回事?
  2. fnv64 mysql,centos7安装搭建rabbitmq
  3. java什么时会出现gc_面试题:java GC发生在会么时候,对什么东西,做了什么事情...
  4. 【c语言】蓝桥杯算法提高 简单加法
  5. sentinel限流_微服务架构进阶:Sentinel实现服务限流、熔断与降级
  6. excel 按数据拆分 xlam_利用EXCEL提升效率之五分钟缩短至五秒批量合并EXCEL批量转换PDF批量上传报关单随附单据___EXCELVBA...
  7. Algorithm——最长公共前缀
  8. vue+mint-ui地址三级or四级联动
  9. Python学习小结---粗略列表解析
  10. mybatis学习笔记(13)-延迟加载