美文网首页
Variational Auto-encoder(VAE)变分自

Variational Auto-encoder(VAE)变分自

作者: 612twilight | 来源:发表于2020-03-08 23:48 被阅读0次

    介绍

    ​ Variational Auto-encoder(VAE)变分自编码器,是无监督复杂概率分布学习的最流行的方法之一。

    ​ VAE的最大特点是模仿自动编码机的学习预测机制,在可测函数之间进行编码、解码。同GAN类似,其最重要的idea是基于一个令人惊叹的数学事实:

    对于一个目标概率分布,给定任何一种概率分布,总存在一个可微的可测函数,将其映射到另一种概率分布,使得这种概率分布与目标的概率分布任意的接近。

    ​ 可测函数是测度论中的概念,它是真实世界的随机事件到数学世界的随机事件的映射。

    ​ VAE的一个重要的哲学思想是,我们希望生成的样本是由某些隐含变量所构造出来的。举个例子,比如我们想要生成0-9的手写体,影响生成这些数字的样式可能有很多因素,比如笔画粗细、笔尖的角度、写者的书写习惯、天气好坏(天气会影响写者的心情,进而影响书写方式。根据蝴蝶效应,初始条件的微小变化会影响最终的结果)。这些因素不胜枚举,一些看似不相关的因素,都有可能影响最终的结果。一个直接的方法是显示地构造出这些隐含因素的概率分布,但是这些因素实在是太多了,无穷多个,我们显然不能手工构造。VAE巧妙地避开了这个问题,利用一个联合高斯分布作为隐含可测函数的分布(这个隐含可测函数将上面所说的所有现实世界影响写字样式的隐含因素映射到欧式空间中去了),随即将问题转化为学习一个从隐含可测函数(隐含变量)到一个所希望生成样本的映射。后面我们会看到,这个过程就是解码过程。可以想象,这个映射会极为复杂。我们自然会想到利用深度学习强大的函数拟合能力来学习这个映射。

    模型设计

    目的

    ​ VAE的核心目的是希望构建一个从隐变量Z生成目标数据X的模型。更准确地讲,它们是假设了Z服从某些常见的分布(比如正态分布或均匀分布),然后希望训练一个模型X = g(Z),这个模型能够将原来的概率分布映射到训练集的概率分布,也就是说,它们的目的都是进行分布之间的变换。

    难点

    ​ 那现在假设Z服从某个已知分布,那么我就可以从中采样得到若干个Z_{1},Z_2,…,Z_n,然后对它做变换得到X^1=g(Z_1),X^2=g(Z_2),…,X^n=g(Z_n),但是我们无法判断这个转换得到的分布跟我们目标的数据集分布是不是一样的。一般计算两个不同的分布的差异是通过KL散度,但是这里我们实际上没有两个分布的表达式,我们只有一批从构造的分布采样而来的数据\{{{\hat X}_1},{{\hat X}_2}...{{\hat X}_n}\},还有一批从真实的分布采样而来的数据{X1,X2,…,Xn}(也就是我们希望生成的训练集)。我们只有样本本身,没有分布表达式,当然也就没有方法算KL散度。

    从后验估计入手

    ​ 首先我们有一个数据x,x服从于某未知p_\theta(X)分布,与x对应的有一个隐变量z,服从于某一已知先验分布p(Z),用p_\theta (x|z)表示似然概率,用p_\theta(z|x)表示后验概率。显然这里除了z的先验分布p(Z)是我们指定的,其余的概率分布我们一无所知。

    ​ 假设数据集中的数据都是独立同分布的,那么对于数据集中的数据就有如下的最大似然概率估计
    {{\mathop{\rm logp}\nolimits} _\theta }({x^{(1)}},{x^{(2)}}...,{x^{(N)}}) = \sum\limits_{i = 1}^{i = N} {{{{\mathop{\rm logp}\nolimits} }_\theta }({x^{(i)}})}
    不过我们没有p_\theta (x)的分布表示形式,所以没法直接计算。

    VAE从后验估计入手,利用一个编码器{q_\phi }(z|x^{(i)})去拟合其后验概率p_\theta(z|x^{(i)}),最终目标是让两个分布的KL散度最小化。因此有如下公式
    \begin{array}{l} KL({q_\phi }(z|{x^{(i)}})||{P_\theta }(z|{x^{(i)}})) = {E_{{q_\phi }(z|{x^{(i)}})}}(\log (\frac{{{q_\phi }(z|{x^{(i)}})}}{{{P_\theta }(z|{x^{(i)}})}}))\\ = {E_{{q_\phi }(z|{x^{(i)}})}}(\log (\frac{{{q_\phi }(z|{x^{(i)}})*{p_\theta }({x^{(i)}})}}{{{P_\theta }(z|{x^{(i)}})*{p_\theta }({x^{(i)}})}}))\\ = {E_{{q_\phi }(z|{x^{(i)}})}}(\log (\frac{{{q_\phi }(z|{x^{(i)}})*{p_\theta }({x^{(i)}})}}{{{P_\theta }(z,{x^{(i)}})}}))\\ = {E_{{q_\phi }(z|{x^{(i)}})}}(\log (\frac{{{q_\phi }(z|{x^{(i)}})}}{{{P_\theta }(z,{x^{(i)}})}})) + {E_{{q_\phi }(z|{x^{(i)}})}}(\log ({p_\theta }({x^{(i)}})))\\ = {E_{{q_\phi }(z|{x^{(i)}})}}(\log (\frac{{{q_\phi }(z|{x^{(i)}})}}{{{P_\theta }(z,{x^{(i)}})}})) + \log ({p_\theta }({x^{(i)}})) \end{array}
    于是我们的对数似然概率就可以表示为
    \log ({p_\theta }({x^{(i)}})){\rm{ = }}KL({q_\phi }(z|{x^{(i)}})||{P_\theta }(z|{x^{(i)}})){\rm{ + L(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(i)}})
    其中{\rm{L(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(i)}})就是对数似然函数变分推断的下界,ELBO,全称是Evidence Lower Bound
    \begin{array}{l} L(\theta ,\phi ;{x^{{\rm{(i)}}}}) = - {E_{{q_\phi }(z|{x^{(i)}})}}\log (\frac{{{q_\phi }(z|{x^{(i)}})}}{{{p_\theta }(z,{x^{(i)}})}})\\ = - {E_{{q_\phi }(z|{x^{(i)}})}}\log (\frac{{{q_\phi }(z|{x^{(i)}}){p_\theta }(z)}}{{{p_\theta }(z,{x^{(i)}}){p_\theta }(z)}})\\ = - {E_{{q_\phi }(z|{x^{(i)}})}}\log (\frac{{{q_\phi }(z|{x^{(i)}})}}{{{p_\theta }(z)}}) + {E_{{q_\phi }(z|{x^{(i)}})}}\log (\frac{{{p_\theta }(z,{x^{(i)}})}}{{{p_\theta }(z)}})\\ = - KL({q_\phi }(z|{x^{(i)}})||{p_\theta }(z)) + {E_{{q_\phi }(z|{x^{(i)}})}}\log ({p_\theta }({x^{(i)}}|z)) \end{array}
    因为KL散度的非负性,所以\log ({p_\theta }({x^{(i)}})) > = {\rm{L(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(i)}}),因此我们可以用优化下界{\rm{L(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(i)}})的方式去优化\log ({p_\theta }({x^{(i)}}))

    显然这里的{\rm{L(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(i)}})是包含期望的,因此我们需要使用蒙特卡洛方法去估计期望。假定编码器{{q_\phi }(z|{x^{(i)}})}可以写作可微函数{z} = {g_\phi }(\varepsilon ,{x}),其中\varepsilon是噪声,服从p(\varepsilon).
    {{\rm{L}}^B}{\rm{(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(i)}}) = - KL({q_\phi }(z|{x^{(i)}}){\rm{||}}{P_\theta }(z)){\rm{ + }}\frac{1}{M}\sum\limits_{m = 1}^M {(\log ({P_\theta }({x^{(i)}}{\rm{|}}{z^{(i,m)}})))}
    其中{z^{(i,m)}} = {g_\phi }({\varepsilon ^{(i,m)}},{x^{(i)}})

    实际试验时,如果样本量N很大,我们一般采用minibatch的方法进行学习,对数似然函数的下界可以通过minibatch来估计,假设minibatch为K个,则
    {\rm{L(}}\theta {\rm{,}}\phi {\rm{;x}}) \approx \frac{N}{K}\sum\limits_{k = 1}^K {{{\rm{L}}^B}{\rm{(}}\theta {\rm{,}}\phi {\rm{;}}{{\rm{x}}^{(k)}})}
    可以看到,为了计算{\rm{L(}}\theta {\rm{,}}\phi {\rm{;x}}),我们用了两层估计。当K较大时,内层蒙特卡洛估计可以由外层估计来完成,也就是说,取M=1即可。实际计算中,作者取K=100,M=1。由上述推导得到AEVB算法:

    img

    现在我们需要给定一些具体的分布来启动算法,
    \begin{array}{l}p(\varepsilon ) = N(\varepsilon ;0,I)\\{q_\phi }(z|{x^{(i)}}) = N(z;{\mu ^{(i)}},{\sigma ^{(i)}}^{^2}I)\\{P_\theta }(z) = N(z;0,I)\\{g_\phi }({\varepsilon ^m},{x^{(i)}}{\varepsilon ^m}) = {\mu ^{(i)}} + {\sigma ^{(i)}} \odot {\varepsilon ^m}\end{array}
    {P_\theta }({x^{(i)}}{\rm{|}}z)则依据z是二值或者是实值来制定不同的分布,二值则采用伯努利分布来估计,而实值则使用正太分布{P_\theta }({x^{(i)}}{\rm{|}}z) = N({x^{(i)}};{{\mu '}^{(i)}},{{\sigma '}^{(i)}}^{^2}I)来估计

    作者采用多层感知机来估计上述{q_\phi }(z|{x^{(i)}}){P_\theta }({x^{(i)}}{\rm{|}}z),

    若为二维数据,则
    \begin{array}{l}\log p(x|z) = \sum\limits_{i = 1}^{{D_x}} {{x_i}\log {x_i} + (1 - {x_i})\log (1 - {y_i})} \\y = sigmoid({W_2}\tanh ({W_1}z + {b_1}) + {b_2}))\end{array}
    若为实值数据,则
    \begin{array}{l} \mu = {W_1}h + {b_1}\\ \sigma = {W_2}h + {b_2}\\ h = \tanh ({W_3}z + {b_3})\\ \log p(x|z) \approx \frac{1}{2}\sum\limits_{j = 1}^{{D_z}} {(1 + log({{({\sigma _j}^{(i)})}^{^2}}) - } {({\mu _j}^{(i)})^2} - {({\sigma _j}^{(i)})^{^2}}) + \frac{1}{M}\sum\limits_{m = 1}^M {(\log ({P_\theta }({x^{(i)}}{\rm{|}}{z^{(i,m)}})))} \\ 其中{z^{(i,m)}} = {\mu ^{(i)}} + {\sigma ^{(i)}} \odot {\varepsilon ^m} \end{array}
    对数似然函数的第一项的推导过程:
    \begin{aligned}&KL\Big(N(\mu,\sigma^2)\Big\Vert N(0,1)\Big)\\ =&\int \frac{1}{\sqrt{2\pi\sigma^2}}e^{-(x-\mu)^2/2\sigma^2} \left(\log \frac{e^{-(x-\mu)^2/2\sigma^2}/\sqrt{2\pi\sigma^2}}{e^{-x^2/2}/\sqrt{2\pi}}\right)dx\\ =&\int \frac{1}{\sqrt{2\pi\sigma^2}}e^{-(x-\mu)^2/2\sigma^2} \log \left\{\frac{1}{\sqrt{\sigma^2}}\exp\left\{\frac{1}{2}\big[x^2-(x-\mu)^2/\sigma^2\big]\right\} \right\}dx\\ =&\frac{1}{2}\int \frac{1}{\sqrt{2\pi\sigma^2}}e^{-(x-\mu)^2/2\sigma^2} \Big[-\log \sigma^2+x^2-(x-\mu)^2/\sigma^2 \Big] dx\end{aligned}
    整个结果分为三项积分,第一项实际上就是-\log \sigma^2乘以概率密度的积分(也就是1),所以结果是-\log \sigma^2;第二项实际是正态分布的二阶矩,熟悉正态分布的朋友应该都清楚正态分布的二阶矩为\mu^2 + \sigma^2;而根据定义,第三项实际上就是“-方差除以方差=-1”。所以总结果就是
    KL\Big(N(\mu,\sigma^2)\Big\Vert N(0,1)\Big)=\frac{1}{2}\Big(-\log \sigma^2+\mu^2+\sigma^2-1\Big)
    因此可以启动优化过程了。

    苏剑林的用了另一个思路来描述这个过程以下内容摘录自变分自编码器(一):原来是这么一回事

    解决方案

    ​ 我们最终目标是想要生成属于p(X)的分布的数据,但我们现在只有一批数据样本\{X_1,\dots,X_n\},其整体用X来描述,假如我们能够根据\{X_1,\dots,X_n\}得到X的分布p(X),那我直接根据p(X)来采样,就可以得到所有可能的X了(包括\{X_1,…,X_n\}以外的),这是一个终极理想的生成模型了。当然,这个理想很难实现,于是我们将分布改一改
    p(X)=\sum_Z p(X|Z)p(Z)
    ​ 此时p(X|Z)就描述了一个由Z来生成X的模型,而我们假设Z服从标准正态分布,也就是p(Z)=N(0,I)。如果这个理想能实现,那么我们就可以先从标准正态分布中采样一个Z,然后根据Z来算一个X,也是一个很棒的生成模型。接下来就是结合自编码器来实现重构,保证有效信息没有丢失,再加上一系列的推导,最后把模型实现。

    vae的传统理解

    ​ 如果像这个图的话,我们其实完全不清楚:究竟经过重新采样出来的Z_k,是不是还对应着原来的X_k,所以我们如果直接最小化D({\hat X_k},X_k)^2(这里D代表某种距离函数)是很不科学的

    ​ 其实,在整个VAE模型中,我们并没有去使用p(Z) (隐变量空间的分布)是正态分布的假设,我们用的是假设p(Z|X)(后验分布)是正态分布!!

    ​ 具体来说,给定一个真实样本X_k,我们假设存在一个专属于X_k的分布p(Z|X_k)(学名叫后验分布),并进一步假设这个分布是(独立的、多元的)正态分布。为什么要强调“专属”呢?因为我们后面要训练一个生成器X=g(Z),希望能够把从分布p(Z|X_k)采样出来的一个Z_k还原为X_k。如果假设p(Z)是正态分布,然后从p(Z)中采样一个Z,那么我们怎么知道这个Z对应于哪个真实的X呢?现在p(Z|X_k)专属于X_k,我们有理由说从这个分布采样出来的Z应该要还原到X_k中去。

    ​ 回到本文,这时候每一个X_k都配上了一个专属的正态分布,才方便后面的生成器做还原。但这样有多少个X就有多少个正态分布了。我们知道正态分布有两组参数:均值μ和方差σ^2(多元的话,它们都是向量),那我怎么找出专属于X_k的正态分布p(Z|X_k)的均值和方差呢?好像并没有什么直接的思路。那好吧,那我就用神经网络来拟合出来吧!这就是神经网络时代的哲学:难算的我们都用神经网络来拟合。

    于是我们构建两个神经网络μ_k=f_1(X_k)logσ^2_k=f_2(X_k)来算它们了。我们选择拟合logσ^2_k而不是直接拟合σ^2_k,是因为σ^2_k总是非负的,需要加激活函数处理,而拟合logσ^2_k不需要加激活函数,因为它可正可负。到这里,我能知道专属于X_k的后验分布的均值和方差了,也就知道它的正态分布长什么样了,然后从这个专属分布中采样一个Z_k出来,然后经过一个生成器得到\hat{X}_k=g(Z_k),现在我们可以放心地最小化D(\hat X_k,X_k)^2,因为Z_k是从专属X_k的分布中采样出来的,这个生成器应该要把开始的X_k还原回来。于是可以画出VAE的示意图

    事实上,vae是为每个样本构造专属的正态分布,然后采样来重构

    ​ 考虑一下上述的模型,首先,我们希望重构X,也就是最小化D(\hat X_k,X_k)^2,但是这个重构过程受到噪声的影响,因为Z_k是通过重新采样过的,不是直接由encoder算出来的。显然噪声会增加重构的难度,不过好在这个噪声强度(也就是方差)通过一个神经网络算出来的,所以最终模型为了重构得更好,肯定会想尽办法让方差为0。而方差为0的话,也就没有随机性了,所以不管怎么采样其实都只是得到确定的结果(也就是均值),只拟合一个当然比拟合多个要容易,而均值是通过另外一个神经网络算出来的。

    说白了,模型会慢慢退化成普通的AutoEncoder,噪声不再起作用。

    这样不就白费力气了吗?说好的生成模型呢?

    别急别急,其实VAE还让所有的p(Z|X)都向标准正态分布看齐,这样就防止了噪声为零,同时保证了模型具有生成能力。怎么理解“保证了生成能力”呢?如果所有的p(Z|X)都很接近标准正态分布N(0,I),那么根据定义
    p(Z)=\sum_X p(Z|X)p(X)=\sum_X \mathcal{N}(0,I)p(X)=\mathcal{N}(0,I) \sum_X p(X) = \mathcal{N}(0,I)
    这里的\sum_X p(X)可以是积分或者求和,总之概率和为一,这样我们就能达到我们的先验假设:p(Z)是标准正态分布。然后我们就可以放心地从N(0,I)中采样来生成图像了。

    为了使模型具有生成能力,vae要求每个p(Z_X)都向正态分布看齐

    为了使模型具有生成能力,vae要求每个p(Z_X)都向正态分布看齐

    那怎么让所有的p(Z|X)都向N(0,I)看齐呢?如果没有外部知识的话,其实最直接的方法应该是在重构误差的基础上中加入额外的loss:
    \mathcal{L}_{\mu}=\Vert f_1(X_k)\Vert^2\quad \text{和}\quad \mathcal{L}_{\sigma^2}=\Vert f_2(X_k)\Vert^2
    因为它们分别代表了均值\mu_k和方差的对数\log σ^2_k,达到\mathcal N(0,I)就是希望二者尽量接近于0了。不过,这又会面临着这两个损失的比例要怎么选取的问题,选取得不好,生成的图像会比较模糊。所以,原论文直接算了一般(各分量独立的)正态分布与标准正态分布的KL散度KL\Big(N(\mu,\sigma^2)\Big\Vert N(0,I)\Big)作为这个额外的loss,计算结果为
    \mathcal{L}_{\mu,\sigma^2}=\frac{1}{2} \sum_{i=1}^d \Big(\mu_{(i)}^2 + \sigma_{(i)}^2 - \log \sigma_{(i)}^2 - 1\Big)
    这里的d是隐变量Z的维度,因为假设各分变量独立所以每个变量独立计算KL散度,然后再求和。其中μ(i)和σ2(i)分别代表一般正态分布的均值向量和方差向量的第i个分量。直接用这个式子做补充loss,就不用考虑均值损失和方差损失的相对比例问题了。

    重参数技巧

    由于这里我们需要从正态分布\mathcal p(Z|X_k)中采样出来一个Z_k,但是分布的均值和方差都是神经网络算出来的,现在我们要利用采样出来的结果去在损失函数中计算loss,然后反过来优化这个分布的均值和方差。可是采样的这个操作是不可导的,所以要利用一个重参数的技巧,英文名是reparameterization trick。我们利用如下公式
    \begin{aligned}&\frac{1}{\sqrt{2\pi\sigma^2}}\exp\left(-\frac{(z-\mu)^2}{2\sigma^2}\right)dz \\ =& \frac{1}{\sqrt{2\pi}}\exp\left[-\frac{1}{2}\left(\frac{z-\mu}{\sigma}\right)^2\right]d\left(\frac{z-\mu}{\sigma}\right)\end{aligned}
    这说明(z-\mu)/\sigma=\varepsilon是服从均值为0、方差为1的标准正态分布的,要同时把dz考虑进去,是因为乘上dz才算是概率,去掉dz是概率密度而不是概率。这时候我们得到:

    \mathcal{N}(\mu,\sigma^2)中采样一个Z,相当于从\mathcal N(0,I)中采样一个ε,然后让Z=\mu + \varepsilon \times \sigma

    于是,我们将从\mathcal{N}(\mu,\sigma^2)采样变成了从\mathcal N(0,I)中采样,然后通过参数变换得到从\mathcal{N}(\mu,\sigma^2)中采样的结果。这样一来,“采样”这个操作就不用参与梯度下降了,改为采样的结果参与,使得整个模型可训练了。

    相关文章

      网友评论

          本文标题:Variational Auto-encoder(VAE)变分自

          本文链接:https://www.haomeiwen.com/subject/mxdhlhtx.html