如何使用变分自编码器VAE生成动漫人物形象(鍙樺垎鑷紪鐮佸櫒VAE)

技术如何使用变分自编码器VAE生成动漫人物形象如何使用变分自编码器VAE生成动漫人物形象,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。变分自

很多新手不太清楚如何使用VAE生成卡通人物。为了帮助大家解决这个问题,下面小编就详细讲解一下。需要的人可以从中学习,希望你能有所收获。

可变自编码器(VAE)和生成对抗网络(GAN)经常相互比较,其中前者在图像生成中的应用范围比后者窄得多。VAE只能在MNIST数据集上生成有意义的输出吗?在本文中,作者尝试使用VAE自动生成卡通人物的头像,并取得了良好的效果。

如何使用变分自编码器VAE生成动漫人物形象

以上是变分自编码器生成的动画图片样本。

在图像生成领域,人们总是喜欢尝试将变分自编码器(VAE)与对抗生成网络(GAN)进行比较。一般认为VAE更容易训练,对显式表示和观测有显式分布假设(高斯分布),而GAN能更好地捕捉观测值的分布,对观测分布没有假设。因此,大家都认为只有GAN才能创造出清晰生动的画面。虽然这可能是真的,因为从理论上来说,GAN捕捉到了像素之间的相关性,但没有多少人尝试过用大于28*28维MNIST数据的图片作为输入来训练VAE来证明这一点。

如何使用变分自编码器VAE生成动漫人物形象

在MNIST数据集上有太多的VAE实现,但是很少有人在其他数据集上做一些不同的事情。这是因为最初的变分自编码器论文只使用了MNIST数据集作为例子吗?

流言终结者!

现在,让我们做一个“流言终结者”的练习,看看VAE图像生成器的效果有多差。例如,以下图像。

如何使用变分自编码器VAE生成动漫人物形象

模糊的VAE样本。

我们先来找一些GAN的比较群。我在谷歌上搜索了“GAN应用”,发现了一个非常有趣的Github代码仓库,里面总结了一些GAN应用:https://github.com/nashory/gans-awesome-applications.

为什么“GAN应用”可以?嗯,很难找到一个不是图像生成的GAN应用,是吗?为了让这个练习更加精彩,这次我们就尝试通过生成模型来输出一些动画图像!

首先,让我们看看GAN模型能多好地完成这个任务。以下两组图片来自两个动画图片生成项目,是很多人选择的,在此基础上进行的工作:

1)https://github.com/jayleicn/animeGAN

2)https://github.com/tdrussell/IllustrationGAN

如何使用变分自编码器VAE生成动漫人物形象

还不错吧?我喜欢它们的颜色。它们与真实图片非常相似。

如何使用变分自编码器VAE生成动漫人物形象

虽然这些图中有一些鬼,但是看起来更好。我猜诀窍是放大图像,只看脸。

结果表明,氮化镓的优异性能令人印象深刻。这让我感到压力。

哦.我们应该继续吗?

从哪里获得数据?

不幸的是,互联网上没有标准的动画图像数据集。但这不能阻止像我这样的人去寻找。在浏览了一些GitHub代码仓库后,我得到了一些提示:

一个叫“Getchu”的日本网站有很多动画图片。

你需要一些工具从网上下载图片,但是你需要自己找到这个工具。我是来给你提供一个可能是非法的。

有很多预先训练好的U-net/RCNN动画人脸检测器,比如lbpcascade_animeface,这样可以把人脸提取成6464的图片。

变分自编码器 VAE

本文假设您已经阅读了大量关于可变自编码器的文章。如果你没有,我想告诉你

推荐下面这几篇文章:

  1. Intuitively Understanding Variational Autoencoders (https://towardsdatascience.com/intuitively-understanding-variational-autoencoders-1bfe67eb5daf)

  2. Tutorial—What is a variational autoencoder? (https://jaan.io/what-is-variational-autoencoder-vae-tutorial/)

  3. Introducing Variational Autoencoders (in Prose and Code) (http://blog.fastforwardlabs.com/2016/08/12/introducing-variational-autoencoders-in-prose-and.html)

  4. 在 TensorFlow 中对比两大生成模型:VAE 与 GAN

所以,在你知道了什么是 VAE 以及如何实现它之后,现在的问题就是「如果知道目标函数和实现方法就足够去训练一个变分自编码器了吗?」我认为答案是肯定的,但是它并不想通常说的那么简单。例如,这个目标函数来自哪里的问题,以及 KL 散度分量在这里有什么作用。在这篇帖子中,我会试着去解释 VAE 背后隐藏的奥秘。

变分推断是一种在概率图模型(PGM)中推断复杂分布的技术。直观地说,如果你不能很容易地捕获复杂分布的最优点,你就可以用一些像高斯分布这样的简单分布来近似估计它的上界或者下界。例如,下图展示了如何使用高斯分布近似估计局部最优解。

如何使用变分自编码器VAE生成动漫人物形象

图片来自:https://people.duke.edu/~ccc14/sta-663/EMAlgorithm.html

请忽略标题中的 EM(最大期望算法)。这是一个在概率图模型中经典的优化方法,它能够更新变分下界,但是现在你在深度学习中会使用随机梯度下降算法(SGD)。

KL 散度是另外一个在概率图模型中会用到的非常重要的技术。它用来测量两个分布之间的差异。它不是一个距离度量,因为 KL[Q||P] 不等于 KL[P||Q]。下面的幻灯片展示了这种差异。

如何使用变分自编码器VAE生成动漫人物形象

图片来自:https://www.slideshare.net/Sabhaology/variational-inference

显然,在 Q>0 时,KL[Q||P] 不允许 P=0. 换句话说,当最小化 KL[Q||P] 时,你想用 Q 分布来捕获 P 分布的一些模式,但是你必然会忽略一些模式的风险。并且,在 P>0 时,KL[P||Q] 不允许 Q=0。换句话说,当最小化 KL[P||Q] 时,你想让 Q 捕获整个分布,而且如果有需要的话,完全忽略掉 P 的模式。

到目前为止,我们直观地明白了两个事实:

  1. 「变分」大致是对上界或者下界的近似。

  2. 「KL」衡量两个分部之间的差异。

现在让我们回过头来看看 VAE 的目标函数是怎么得来的。

如何使用变分自编码器VAE生成动漫人物形象

这是我对 VAE 的推导。尽管它似乎与你可能在论文中看到的看起来不同,但这是我认为最容易理解的推导。

给定一些图像作为训练数据,我们想要拟合一些能够尽可能准确地表示训练数据的参数(theta)。正式一点说,我们想要拟合用于最大化观测值的联合概率的模型。因此,你会得到左边的表达式。

「z」从何而来?

z 是创造观测值(图像)的潜在表示。直观地说,我们假设一些神秘的画家在数据集中创作这些图像(x),我们将它们称作 Z。并且,我们发现 Z 是不确定的,有时 1 号画家创作了图片,有时候是 2 号画家创作了图片。我们仅仅知道所有的艺术家都对他们所画的图片有着特别的偏爱。

大于等于号是怎么来的?

Jensen 不等式如下所示。注意: log 是凹函数,所以在我们的例子中,不等式反过来的。

如何使用变分自编码器VAE生成动漫人物形象

图片来自 Youtube:https://www.youtube.com/watch?v=10xgmpG_uTs

为什么在最后一行取近似?

我们不能对无穷的可能的 z 做几分,所以我们使用数值逼近,这意味着我们从分布中进行抽样来对期望取近似。

什么是 P(x|z) 分布?

在变分自编码器中,我们假设它是高斯函数。这就是为什么在优化 VAE 时,要做均方误差(MSE)。

如何使用变分自编码器VAE生成动漫人物形象

f 函数是解码器!哦!在范数之后应该有平方符号。

  
  
  
  1. @staticmethod

  2. def _gaussian_log_likelihood(targets, mean, std):

  3.    se = 0.5 * tf.reduce_sum(tf.square(targets - mean)) / (2*tf.square(std)) + tf.log(std)

  4.    return se


  5. @staticmethod

  6. def _bernoulli_log_likelihood(targets, outputs, eps=1e-8):


  7.    log_like = -tf.reduce_sum(targets * tf.log(outputs + eps)

  8.                              + (1. - targets) * tf.log((1. - outputs) + eps))

  9.    return log_like

P(x|z) 的假设: 高斯和伯努利分布。代码显示了负的对数似然,因为我们总是希望最小化错误,而不是在深度学习中显式地最大化似然。

你在 Github 中看到如此多的 softmax 函数的原因是,对于像 MNIST 这样的二进制图像,我们假设分布是伯努利分布。

什么是 P(z|x) 分布?

这是高斯分布。这就是为什么你看到 KL 散度的实现是一个近似的解。不明白吗?不要担心,你可以看看这篇里:https://stats.stackexchange.com/questions/318184/kl-loss-with-a-unit-gaussian

  
  
  
  1. @staticmethod

  2. def _kl_diagnormal_stdnormal(mu, log_var):


  3.    var = tf.exp(log_var)

  4.    kl = 0.5 * tf.reduce_sum(tf.square(mu) + var - 1. - log_var)

  5.    return kl

Python 语言编写的 KL 散度近似形式的表达式

这个等式怎么能成为一个自编码器呢?

等式中有两类参数。参数 theta 是用来对分布 P(x|z) 建模的,它将 z 解码为图像 x。变体的 theta 是用来对分布 Q(z|x) 建模的,它将 x 编码成潜在的表示 z。

如何使用变分自编码器VAE生成动漫人物形象

自制的变分自编码器的示意图。绿色和蓝色的部分是可微的,琥珀色的部分代表不可微的白噪声。每个人都用著名的猫的图片,所以这里我使用了狗。我不知道我从哪里得到的这张可爱的狗狗图片。如果你知道,请告诉我,这样我可以正确地引用原始网站。

相应的 TensorFlow 计算图谱:

  
  
  
  1. def _build_graph(self):


  2.    with tf.variable_scope('vae'):

  3.        self.x = tf.placeholder(tf.float32, shape=[None, self._observation_dim])


  4.        with tf.variable_scope('encoder'):

  5.            encoded = self._encode(self.x, self._latent_dim)


  6.        with tf.variable_scope('latent'):

  7.            self.mean = encoded[:, :self._latent_dim]

  8.            logvar = encoded[:, self._latent_dim:]

  9.            stddev = tf.sqrt(tf.exp(logvar))

  10.            epsilon = tf.random_normal([self._batch_size, self._latent_dim])

  11.            # Reparameterization Trick

  12.            self.z = self.mean + stddev * epsilon


  13.        with tf.variable_scope('decoder'):

  14.            decoded = self._decode(self.z, self._observation_dim)

  15.            self.obs_mean = decoded

  16.            if self._observation_distribution == 'Gaussian':

  17.                obs_epsilon = tf.random_normal([self._batch_size,

  18.                                                self._observation_dim])

  19.                self.sample = self.obs_mean + self._observation_std * obs_epsilon

  20.            else:

  21.                self.sample = Bernoulli(probs=self.obs_mean).sample()

VAE 目标函数的两个组成部分的意义

  1. 最小化 KL 项:将 P(z|x) 看作 N(0,1)(标准正态分布)。我们希望通过从标准正态分布中抽样来生成图像。因此,我们最好让潜在的分布尽可能地接近标准正态分布。

  2. 最大限度地减小重构损失:创造尽可能生动/真实的图像。最小化真实的图像和生成的图像之间的误差。

很容易看到,为了使 VAE 很好的工作,平衡这两个部分是十分关键的。

如果我们完全忽略 KL 项,变分自编码器将收敛到标准的自编码器,它将删除目标函数中的随机部分。因此,VAE 不能生成新的图像,只能记住并且展示训练数据(或者创造纯粹的噪声,因为在那个潜在的位置没有编码的图像!)如果你足够幸运的话,理想的结果是实现了核主成分分析!

如果我们完全忽略了重构项,那么潜在的分布会退化成标准的正态分布。所以无论输入是什么,你总是得到类似的输出。

如何使用变分自编码器VAE生成动漫人物形象

一个 GAN 退化的案例。VAE 的情况也相同。图片来自:http://yusuke-ujitoko.hatenablog.com/entry/2017/05/30/011900

现在我们明白了:

  1. 我们希望 VAE 生成合理的图像,但是我们不想让它显示训练数据。

  2. 我们想从标准正态分布中取样,但是我们不想一次又一次地看到同样的图像。我们希望模型能产生差别非常大的图像。

那么,我们如何平衡它们呢?我们将观测值的标准差设置成一个超参数。

  
  
  
  1. with tf.variable_scope('loss'):

  2.    with tf.variable_scope('kl-divergence'):

  3.        kl = self._kl_diagnormal_stdnormal(self.mean, logvar)


  4.    if self._observation_distribution == 'Gaussian':

  5.        with tf.variable_scope('gaussian'):

  6.            # self._observation_std is hyper parameter

  7.            reconst = self._gaussian_log_likelihood(self.x,

  8.                                                    self.obs_mean,

  9.                                                    self._observation_std)

  10.    else:

  11.        with tf.variable_scope('bernoulli'):

  12.            reconst = self._bernoulli_log_likelihood(self.x, self.obs_mean)


  13.    self._loss = (kl + reconst) / self._batch_size

我看到人们经常将 KL 项设定为一个像 0.001×KL + Reconstruction_Loss 这样的值,这是不正确的!顺便问一下,这就是很多人只在 MNIST 数据集上做 VAE 的原因吗?

还有什么值得注意的呢?模型的复杂程度是支撑损失函数的关键因素。如果解码器太复杂,那么即使是较弱的损失也不能阻止它过拟合。结果是,潜在的分布被忽略了。如果解码器太简单了,模型就不能合理地解码潜在的表示,最终只能捕获一些粗略的轮廓,就像我们之前所展示的图像那样。

最后,如果我们上面做的事情都是正确的,是时候看看 VAE 的力量了。

如何使用变分自编码器VAE生成动漫人物形象

成功了!

好吧,我承认,小图片是没有说服力的。

如何使用变分自编码器VAE生成动漫人物形象

稍微放大一点...

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/156003.html

(0)

相关推荐

  • 馒头和米饭哪个含糖量高,蒸米饭与煮米饭哪个升糖快

    技术馒头和米饭哪个含糖量高,蒸米饭与煮米饭哪个升糖快大家好,我是奎哥,很高兴能为你解答馒头和米饭哪个含糖量高:蒸米饭与煮米饭哪个升糖快?根据查询资料,也咨询过相关专业人员,还是觉得煮米饭升糖快,因为米饭煮的话,糖分会很快

    生活 2021年10月31日
  • 去角质产品排行榜10强,能否推荐一下脸部去角质的产品

    技术去角质产品排行榜10强,能否推荐一下脸部去角质的产品我用的是美肤宝精粹角质嗜喱去角质产品排行榜10强。这是一款智能去角质产品!也许有人会问,智能去角质产品,是不是就比普通的去角质产品去除的更多?结果恰恰相反!智能去角

    生活 2021年10月23日
  • mysql如何查询字段值

    技术mysql如何查询字段值这篇文章主要介绍mysql如何查询字段值,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! mysql查询字段值的方法:1、使用“SELECT

    攻略 2021年12月2日
  • sketch主要是做什么的(sketch 主要是做什么)

    技术sketch的优势是什么今天就跟大家聊聊有关sketch的优势是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。现在UI设计师不仅仅需要掌握基础的设计软件P

    攻略 2021年12月24日
  • Lotus系统中CS与BS有什么区别

    技术Lotus系统中CS与BS有什么区别这篇文章主要为大家展示了“Lotus系统中CS与BS有什么区别”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Lotus系统中CS与BS

    攻略 2021年12月3日
  • javascript中怎么实现一个基于DOM的模板引擎

    技术javascript中怎么实现一个基于DOM的模板引擎本篇内容主要讲解“javascript中怎么实现一个基于DOM的模板引擎”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习

    攻略 2021年11月15日