变分自编码器(二):从贝叶斯观点出发
By 苏剑林 | 2018-03-28 | 506828位读者 |源起 #
前几天写了博文《变分自编码器(一):原来是这么一回事》,从一种比较通俗的观点来理解变分自编码器(VAE),在那篇文章的视角中,VAE跟普通的自编码器差别不大,无非是多加了噪声并对噪声做了约束。然而,当初我想要弄懂VAE的初衷,是想看看究竟贝叶斯学派的概率图模型究竟是如何与深度学习结合来发挥作用的,如果仅仅是得到一个通俗的理解,那显然是不够的。
所以我对VAE继续思考了几天,试图用更一般的、概率化的语言来把VAE说清楚。事实上,这种思考也能回答通俗理解中无法解答的问题,比如重构损失用MSE好还是交叉熵好、重构损失和KL损失应该怎么平衡,等等。
建议在阅读《变分自编码器(一):原来是这么一回事》后对本文进行阅读,本文在内容上尽量不与前文重复。
准备 #
在进入对VAE的描述之前,我觉得有必要把一些概念性的内容讲一下。
数值计算vs采样计算 #
对于不是很熟悉概率统计的读者,容易混淆的两个概念应该是数值计算和采样计算,也有读者在《三味Capsule:矩阵Capsule与EM路由》出现过同样的疑惑。比如已知概率密度函数p(x),那么x的期望也就定义为
E[x]=∫xp(x)dx
如果要对它进行数值计算(数值积分),那么可以选若干个有代表性的点x0<x1<x2<⋯<xn,然后得到
E[x]≈n∑i=1xip(xi)(xi−xi−1)
这里不讨论“有代表性”是什么意思,也不讨论提高数值计算精度的方法。这样写出来,是为了跟采样计算对比。如果从p(x)中采样若干个点x1,x2,…,xn,那么我们有
E[x]≈1nn∑i=1xi,xi∼p(x)
我们可以比较(2)跟(3),它们的主要区别是(2)中包含了概率的计算而(3)中仅有x的计算,这是因为在(3)中xi是从p(x)中依概率采样出来的,概率大的xi出现的次数也多,所以可以说采样的结果已经包含了p(x)在里边,就不用再乘以p(xi)了。
更一般地,我们可以写出
Ex∼p(x)[f(x)]=∫f(x)p(x)dx≈1nn∑i=1f(xi),xi∼p(x)
这就是蒙特卡洛模拟的基础。
KL散度及变分 #
我们通常用KL散度来度量两个概率分布p(x)和q(x)之间的差异,定义为
KL(p(x)‖q(x))=∫p(x)lnp(x)q(x)dx=Ex∼p(x)[lnp(x)q(x)]
KL散度的主要性质是非负性,如果固定p(x),那么KL(p(x)‖q(x))=0⇔p(x)=q(x);如果固定q(x),同样有KL(p(x)‖q(x))=0⇔p(x)=q(x),也就是不管固定哪一个,最小化KL散度的结果都是两者尽可能相等。这一点的严格证明要用到变分法,而事实上VAE中的V(变分)就是因为VAE的推导就是因为用到了KL散度(进而也包含了变分法)。
当然,KL散度有一个比较明显的问题,就是当q(x)在某个区域等于0,而p(x)在该区域不等于0,那么KL散度就出现无穷大。这是KL散度的固有问题,我们只能想办法规避它,比如隐变量的先验分布我们用高斯分布而不是均匀分布,原因便在此,这一点我们在前文《变分自编码器(一):原来是这么一回事》中也提到过了。
顺便说点题外话,度量两个概率分布之间的差异只有KL散度吗?当然不是,我们可以看维基百科的Statistical Distance一节,里边介绍了不少分布距离,比如有一个很漂亮的度量,我们称之为巴氏距离(Bhattacharyya distance),定义为
DB(p(x),q(x))=−ln∫√p(x)q(x)dx
这个距离不仅对称,还没有KL散度的无穷大问题。然而我们还是选用KL散度,因为我们不仅要理论上的漂亮,还要实践上的可行,KL散度可以写成期望的形式,这允许我们对其进行采样计算,相反,巴氏距离就没那么容易了,读者要是想把下面计算过程中的KL散度替换成巴氏距离,就会发现寸步难行了。
本文的符号表 #
讲解VAE免不了出现大量的公式和符号,这里将部分式子的含义提前列举如下:
xk,zk表示随机变量x,z的第k个样本x(k),z(k)表示多元变量x,z的第k个分量Ex∼p(x)[f(x)]表示对f(x)算期望,其中x的分布为p(x)KL(p(x)‖q(x))两个分布的KL散度‖x‖2向量x的l2范数,也就是我们通常说的模长的平方L本文的损失函数的符号D,dD是输入x的维度,d是隐变量z的维度
框架 #
这里通过直接对联合分布进行近似的方式,简明快捷地给出了VAE的理论框架。
直面联合分布 #
出发点依然没变,这里再重述一下。首先我们有一批数据样本{x1,…,xn},其整体用x来描述,我们希望借助隐变量z描述x的分布˜p(x):
q(x)=∫q(x|z)q(z)dz,q(x,z)=q(x|z)q(z)
这里q(z)是先验分布(标准正态分布),目的是希望q(x)能逼近˜p(x)。这样(理论上)我们既描述了˜p(x),又得到了生成模型q(x|z),一举两得。
接下来就是利用KL散度进行近似。但我一直搞不明白的是,为什么从原作《Auto-Encoding Variational Bayes》开始,VAE的教程就聚焦于后验分布p(z|x)的描述?也许是受了EM算法的影响,这个问题上不能应用EM算法,就是因为后验分布p(z|x)难以计算,所以VAE的作者就聚焦于p(z|x)的推导。
但事实上,直接来对p(x,z)进行近似是最为干脆的。具体来说,定义p(x,z)=˜p(x)p(z|x),我们设想用一个联合概率分布q(x,z)来逼近p(x,z),那么我们用KL散度来看它们的距离:
KL(p(x,z)‖q(x,z))=∬
KL散度是我们的终极目标,因为我们希望两个分布越接近越好,所以KL散度越小越好。当然,由于现在p(x,z)也有参数,所以不单单是q(x,z)来逼近p(x,z),p(x,z)也会主动来逼近q(x,z),两者是相互接近。
于是我们有
\begin{aligned}KL\Big(p(x,z)\Big\Vert q(x,z)\Big) =& \int \tilde{p}(x) \left[\int p(z|x)\ln \frac{\tilde{p}(x)p(z|x)}{q(x,z)} dz\right]dx\\
=& \mathbb{E}_{x\sim \tilde{p}(x)} \left[\int p(z|x)\ln \frac{\tilde{p}(x)p(z|x)}{q(x,z)} dz\right]
\end{aligned}\tag{9}
这样一来利用(4)式,把各个x_i代入就可以进行计算了,这个式子还可以进一步简化,因为\ln \frac{\tilde{p}(x)p(z|x)}{q(x,z)}=\ln \tilde{p}(x) + \ln \frac{p(z|x)}{q(x,z)},而
\begin{aligned}\mathbb{E}_{x\sim \tilde{p}(x)} \left[\int p(z|x)\ln \tilde{p}(x)dz\right] =& \mathbb{E}_{x\sim \tilde{p}(x)} \left[\ln \tilde{p}(x)\int p(z|x)dz\right]\\
=&\mathbb{E}_{x\sim \tilde{p}(x)} \big[\ln \tilde{p}(x)\big]
\end{aligned}\tag{10}
注意这里的\tilde{p}(x)是根据样本x_1,x_2,\dots,x_n确定的关于x的先验分布,尽管我们不一定能准确写出它的形式,但它是确定的、存在的,因此这一项只是一个常数,所以可以写出
\mathcal{L}=KL\Big(p(x,z)\Big\Vert q(x,z)\Big) - \text{常数}= \mathbb{E}_{x\sim \tilde{p}(x)} \left[\int p(z|x)\ln \frac{p(z|x)}{q(x,z)} dz\right]\tag{11}
目前最小化KL\Big(p(x,z)\Big\Vert q(x,z)\Big)也就等价于最小化\mathcal{L}。注意减去的常数为\mathbb{E}_{x\sim \tilde{p}(x)} \big[\ln \tilde{p}(x)\big],所以\mathcal{L}拥有下界-\mathbb{E}_{x\sim \tilde{p}(x)} \big[\ln \tilde{p}(x)\big]~注意到\tilde{p}(x)不一定是概率,在连续情形时\tilde{p}(x)是概率密度,它可以大于1也可以小于1,所以-\mathbb{E}_{x\sim \tilde{p}(x)} \big[\ln \tilde{p}(x)\big]不一定是非负,即loss可能是负数。
你的VAE已经送达 #
到这里,我们回顾初衷——为了得到生成模型,所以我们把q(x,z)写成q(x|z)q(z),于是就有
\begin{aligned}\mathcal{L} =& \mathbb{E}_{x\sim \tilde{p}(x)} \left[\int p(z|x)\ln \frac{p(z|x)}{q(x|z)q(z)} dz\right]\\
=&\mathbb{E}_{x\sim \tilde{p}(x)} \left[-\int p(z|x)\ln q(x|z)dz+\int p(z|x)\ln \frac{p(z|x)}{q(z)}dz\right]\end{aligned}\tag{12}
再简明一点,那就是
\begin{aligned}\mathcal{L} = &\mathbb{E}_{x\sim \tilde{p}(x)} \left[\mathbb{E}_{z\sim p(z|x)}\big[-\ln q(x|z)\big]+\mathbb{E}_{z\sim p(z|x)}\Big[\ln \frac{p(z|x)}{q(z)}\Big]\right]\\
= &\mathbb{E}_{x\sim \tilde{p}(x)} \Bigg[\mathbb{E}_{z\sim p(z|x)}\big[-\ln q(x|z)\big]+KL\Big(p(z|x)\Big\Vert q(z)\Big)\Bigg]
\end{aligned}\tag{13}
看,括号内的不就是VAE的损失函数嘛?只不过我们换了个符号而已。我们就是要想办法找到适当的q(x|z)和q(z)使得\mathcal{L}最小化。
再回顾一下整个过程,我们几乎都没做什么“让人难以想到”的形式变换,但VAE就出来了。所以,没有必要去对后验分布进行分析,直面联合分布,我们能更快捷地到达终点。
不能搞分裂~ #
鉴于(13)式的特点,我们也许会将\mathcal{L}分开为两部分看:\mathbb{E}_{z\sim p(z|x)}\big[-\ln q(x|z)\big]的期望和KL\Big(p(z|x)\Big\Vert q(z)\Big)的期望,并且认为问题变成了两个loss的分别最小化。
然而这种看法是不妥的,因为KL\Big(p(z|x)\Big\Vert q(z)\Big)=0意味着z没有任何辨识度,所以-\ln q(x|z)不可能小(预测不准),而如果-\ln q(x|z)小则q(x|z)大,预测准确,这时候p(z|x)不会太随机,即KL\Big(p(z|x)\Big\Vert q(z)\Big)不会小,所以这两部分的loss其实是相互拮抗的。所以,\mathcal{L}不能割裂来看,而是要整体来看,整个的\mathcal{L}越小模型就越接近收敛,而不能只单独观察某一部分的loss。
事实上,这正是GAN模型中梦寐以求的——有一个总指标能够指示生成模型的训练进程,在VAE模型中天然就具备了这种能力了,而GAN中要到WGAN才有这么一个指标~
实验 #
截止上面的内容,其实我们已经完成了VAE整体的理论构建。但为了要将它付诸于实验,还需要做一些工作。事实上原论文《Auto-Encoding Variational Bayes》也在这部分做了比较充分的展开,但遗憾的是,网上很多VAE教程都只是推导到(13)式就没有细说了。
后验分布近似 #
现在q(z),q(x|z),p(z|x)全都是未知的,连形式都还没确定,而为了实验,就得把(13)式的每一项都明确写出来。
首先,为了便于采样,我们假设z\sim N(0,I),即标准的多元正态分布,这就解决了q(z)。那q(x|z),p(z|x)呢?一股脑用神经网络拟合吧。
注:本来如果已知q(x|z)和q(z),那么p(z|x)最合理的估计应该是:
\hat{p}(z|x) = q(z|x) = \frac{q(x|z)q(z)}{q(x)} = \frac{q(x|z)q(z)}{\int q(x|z)q(z)dz}\tag{14}
这其实就是EM算法中的后验概率估计的步骤,具体可以参考《从最大似然到EM算法:一致的理解方式》。但事实上,分母的积分几乎不可能完成,因此这是行不通的。所以干脆用一般的网络去近似它,这样不一定能达到最优,但终究是一个可用的近似。
具体来说,我们假设p(z|x)也是(各分量独立的)正态分布,其均值和方差由x来决定,这个“决定”,就是一个神经网络:
p(z|x)=\frac{1}{\prod\limits_{k=1}^d \sqrt{2\pi \sigma_{(k)}^2(x)}}\exp\left(-\frac{1}{2}\left\Vert\frac{z-\mu(x)}{\sigma(x)}\right\Vert^2\right)\tag{15}
这里的\mu(x),\sigma^2(x)是输入为x、输出分别为均值和方差的神经网络,其中\mu(x)就起到了类似encoder的作用。既然假定了高斯分布,那么(13)式中的KL散度这一项就可以先算出来:
KL\Big(p(z|x)\Big\Vert q(z)\Big)=\frac{1}{2} \sum_{k=1}^d \Big(\mu_{(k)}^2(x) + \sigma_{(k)}^2(x) - \ln \sigma_{(k)}^2(x) - 1\Big)\tag{16}
也就是我们所说的KL loss,这在上一篇文章已经给出。
生成模型近似 #
现在只剩生成模型部分q(x|z)了,该选什么分布呢?论文《Auto-Encoding Variational Bayes》给出了两种候选方案:伯努利分布或正态分布。
什么?又是正态分布?是不是太过简化了?然而并没有办法,因为我们要构造一个分布,而不是任意一个函数,既然是分布就得满足归一化的要求,而要满足归一化,又要容易算,我们还真没多少选择。
伯努利分布模型 #
首先来看伯努利分布,众所周知它其实就是一个二元分布:
p(\xi)=\left\{\begin{aligned}&\rho,\, \xi = 1;\\
&1-\rho,\, \xi = 0\end{aligned}\right.\tag{17}
所以伯努利分布只适用于x是一个多元的二值向量的情况,比如x是二值图像时(mnist可以看成是这种情况)。这种情况下,我们用神经网络\rho(z)来算参数\rho,从而得到
q(x|z)=\prod_{k=1}^D \Big(\rho_{(k)}(z)\Big)^{x_{(k)}} \Big(1 - \rho_{(k)}(z)\Big)^{1 - x_{(k)}}\tag{18}
这时候可以算出
-\ln q(x|z) = \sum_{k=1}^D \Big[- x_{(k)} \ln \rho_{(k)}(z) - (1-x_{(k)}) \ln \Big(1 -\rho_{(k)}(z)\Big)\Big]\tag{19}
这表明\rho(z)要压缩到0~1之间(比如用sigmoid激活),然后用交叉熵作为损失函数,这里\rho(z)就起到了类似decoder的作用。
正态分布模型 #
然后是正态分布,这跟p(z|x)是一样的,只不过x,z交换了位置:
q(x|z)=\frac{1}{\prod\limits_{k=1}^D \sqrt{2\pi \tilde{\sigma}_{(k)}^2(z)}}\exp\left(-\frac{1}{2}\left\Vert\frac{x-\tilde{\mu}(z)}{\tilde{\sigma}(z)}\right\Vert^2\right)\tag{20}
这里的\tilde{\mu}(z),\tilde{\sigma}^2(z)是输入为z、输出分别为均值和方差的神经网络,\tilde{\mu}(z)就起到了decoder的作用。于是
-\ln q(x|z) = \frac{1}{2}\left\Vert\frac{x-\tilde{\mu}(z)}{\tilde{\sigma}(z)}\right\Vert^2 + \frac{D}{2}\ln 2\pi + \frac{1}{2}\sum_{k=1}^D \ln \tilde{\sigma}_{(k)}^2(z)\tag{21}
很多时候我们会固定方差为一个常数\tilde{\sigma}^2,这时候
-\ln q(x|z) \sim \frac{1}{2\tilde{\sigma}^2}\Big\Vert x-\tilde{\mu}(z)\Big\Vert^2\tag{22}
这就出现了MSE损失函数。
所以现在就清楚了,对于二值数据,我们可以对decoder用sigmoid函数激活,然后用交叉熵作为损失函数,这对应于q(x|z)为伯努利分布;而对于一般数据,我们用MSE作为损失函数,这对应于q(x|z)为固定方差的正态分布。
采样计算技巧 #
前一节做了那么多的事情,无非是希望能(13)式明确地写下来。当我们假设p(z|x)和q(z)都是正态分布时,(13)式的KL散度部分就已经算出来了,结果是(16)式;当我们假设q(x|z)是伯努利分布或者高斯分布时,-\ln q(x|z)也能算出来了。现在缺什么呢?
采样!
p(z|x)的作用分两部分,一部分是用来算KL\Big(p(z|x)\Big\Vert q(z)\Big),另一部分是用来算\mathbb{E}_{z\sim p(z|x)}\big[-\ln q(x|z)\big]的,而\mathbb{E}_{z\sim p(z|x)}\big[-\ln q(x|z)\big]就意味着
-\frac{1}{n}\sum_{i=1}^n \ln q(x|z_i),\quad z_i \sim p(z|x)\tag{23}
我们已经假定了p(z|x)是正态分布,均值和方差由模型来算,这样一来,借助“重参数技巧”就可以完成采样。
但是采样多少个才适合呢?VAE非常直接了当:一个!所以这时候(13)式就变得非常简单了:
\mathcal{L} = \mathbb{E}_{x\sim \tilde{p}(x)} \Bigg[-\ln q(x|z) + KL\Big(p(z|x)\Big\Vert q(z)\Big)\Bigg],\quad z\sim p(z|x)\tag{24}
该式中的每一项,可以在把(16),(19),(21),(22)式找到。注意对于一个batch中的每个x,都需要从p(z|x)采样一个“专属”于x的z出来才去算-\ln q(x|z)。而正因为VAE在p(z|x)这里只采样了一个样本,所以它看起来就跟普通的AE差不多了。
那么最后的问题就是采样一个究竟够了吗?事实上我们会运行多个epoch,每次的隐变量都是随机生成的,因此当epoch数足够多时,事实上是可以保证采样的充分性的。我也实验过采样多个的情形,感觉生成的样本并没有明显变化。
致敬 #
这篇文章从贝叶斯理论的角度出发,对VAE的整体流程做了一个梳理。用这种角度考察的时候,我们心里需要紧抓住两个点:“分布”和“采样”——写出分布形式,并且通过采样来简化过程。
简单来说,由于直接描述复杂分布是难以做到的,所以我们通过引入隐变量来将它变成条件分布的叠加。而这时候我们对隐变量的分布和条件分布都可以做适当的简化(比如都假设为正态分布),并且在条件分布的参数可以跟深度学习模型结合起来(用深度学习来算隐变量的参数),至此,“深度概率图模型”就可见一斑了。
让我们一起致敬贝叶斯大神,以及众多研究概率图模型的大牛,他们都是真正的勇者。
转载到请包括本文地址:https://spaces.ac.cn/archives/5343
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Mar. 28, 2018). 《变分自编码器(二):从贝叶斯观点出发 》[Blog post]. Retrieved from https://spaces.ac.cn/archives/5343
@online{kexuefm-5343,
title={变分自编码器(二):从贝叶斯观点出发},
author={苏剑林},
year={2018},
month={Mar},
url={\url{https://spaces.ac.cn/archives/5343}},
}
May 25th, 2024
写得真好,以理服人。
有个疑惑,VAE本身有没有约束x每个分量之间的关系?用图像重构的例子,相邻的像素重构的时候应该有很大的相关性,比如数字的笔画是连续的,比如图上的一个region是眼睛,但是在(18)和(20)式中看起来是相互独立的(如果Z给定)?不知道我的理解有偏差吗。
虽然但是好像也没错,但“以理服人”这个词总感觉哪里不对...
言归正传,VAE的Decoder确实假设了x的每个分量相互独立,但有个前提,是给定z之后每个分量独立,所以这个假设虽然不是很完美,但不至于很糟糕,结果就是能生成大致符合目标的结果,但会比较模糊。
谢谢你的印证,感觉上就是这样,但是我没有足够的数学素养来推导。我总觉得通过Z来的约束不够明确,可能具有多解性,模型很可能就给了个mean,看起来就模糊,这个是根本假设上的问题,VAE不容易解决?所以生成还是扩散模型给力。
July 2nd, 2024
感觉这里面涉及一个关键命题的证明:
当P(X)为任意分布,P(Z)~N(0, I)情况下,能否设计出一个联合分布P(X, Z),满足:P(X|Z)和P(Z|X)都是正态分布?
1.当P(X)和P(Z)都符合正态分布时,上面的命题成立。但目前P(X)并不一定满足这一条件。
2.如果限定Z=f(x) + Y, Y是正态分布,那么可以降低f(x)的值,来让P(Z)逼近正态分布。且P(Z|X)也正态分布,但是仍然无法证明P(X|Z)是正态分布?(这种情况看起来很像扩散模型)
综合来看,上面的命题始终没办法保证,其正确性依赖于P(X)的分布特点(比如是正态分布,则命题自然成立),既然如此,为什么VAE可以直接假定P(Z),P(X|Z), P(Z|X)都是正态分布呢?
你理解的没毛病,但注意关键词是“假定”而不是“一定”,也就是说,我们是通过假设P(X|Z)和P(Z|X)都是正态分布,来得到一个近似结果,并不是说它们一定是正态分布。
举个例子,f(x)是一个三次函数x^3,我们可以假设g(x)=ax^2+bx+c,然后最小化\int_0^1 (f(x)-g(x))^2 dx来获得f(x)在[0,1]的一个近似,但不是说f(x)就是二次函数。至于为什么选择二次函数,则很可能只是因为二次函数比较好算,等等。
OK,能够大概理解你的意思。我本来以为,一定能够保证找到这么一组正态分布P(X|Z)和P(Z|X),只是需要模型去拟合其参数。现在看来是分布本身都不确定,而是假定一个正态分布去拟合这个未知分布(而非未知正态分布)。
但是还是会有疑问:感觉这种假设太强了,将参数直接退化到了2个,感觉涉及到这个任务本身是否可学习了。如果分布差异很大,感觉算法的表现不应该好才对,但显然VAE看起来还挺work。
又去详细的看了原论文,作者直接干了2重假设:1)P(Z|X)近似多元高斯分布; 2)这个多元高斯分布还得是近似对角协方差矩阵。然后实际操作中直接当成协方差矩阵的高斯分布计算。。。
如果是“一定”,那就不会有模糊现象了,就是不一定,所以通常才会模糊。
条件正态分布看上去虽然弱了点,但它参数不止两个,因为它的均值方差都有可能是整个神经网络模型的预测结果,所以参数量是不定的。它为什么效果还过得去,大概是因为它是双重逼近。相当于说a和b相互逼近,a,b都有参数,而不是a向b逼近或者b向a逼近(a,b之一没有参数)
感谢回复,经过沟通了解了更多的细节~~
其实这个假设没有你想的那么强,因为这里只假设了后验分布是高斯分布,比如p(Z|X)是给定X的情况下Z服从高斯分布,这个高斯分布的均值和方差是用神经网络估计的,所以p(Z|X)总体还是个复杂的条件概率分布,复杂性由神经网络决定。
神经网络估计是真,但是这个分布很弱也是真。条件高斯分布,就好比说中心和离心率就由神经网络预测的椭圆,神经网络再复杂,它也只能拟合(单个)椭圆,没法拟合方形,也没法拟合更复杂的图案。
July 3rd, 2024
苏神,有个tf1的相关的代码报错想请教一下
Traceback (most recent call last):
File "/home/a99/桌面/FakingFakeNews_fudan/grover/lm/train.py", line 160, in
tf.compat.v1.app.run()
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/tensorflow_core/python/platform/app.py", line 40, in run
_run(main=main, argv=argv, flags_parser=_parse_flags_tolerate_undef)
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/absl/app.py", line 306, in run
flags_parser,
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/absl/app.py", line 375, in _run_init
flags_parser=flags_parser,
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/absl/app.py", line 220, in _register_and_parse_flags_with_usage
args_to_main = flags_parser(original_argv)
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/tensorflow_core/python/platform/app.py", line 31, in _parse_flags_tolerate_undef
return flags.FLAGS(_sys.argv if argv is None else argv, known_only=True)
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/tensorflow_core/python/platform/flags.py", line 112, in __call__
return self.__dict__['__wrapped'].__call__(*args, **kwargs)
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/absl/flags/_flagvalues.py", line 673, in __call__
self.validate_all_flags()
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/absl/flags/_flagvalues.py", line 533, in validate_all_flags
self._assert_validators(all_validators)
File "/home/a99/anaconda3/envs/grover/lib/python3.6/site-packages/absl/flags/_flagvalues.py", line 568, in _assert_validators
raise _exceptions.IllegalFlagValueError('\n'.join(messages))
absl.flags._exceptions.IllegalFlagValueError: flag --input_file=None: Flag --input_file must have a value other than None.
flag --output_dir=None: Flag --output_dir must have a value other than None.
看上去就不是tf的问题,自行理解报错意思吧...
August 14th, 2024
苏神写得太好了!对公式(2)有个小疑问。
这个公式里x_{i}似乎是二阶的。假如x_0, ... x_n都扩大10倍,E[x]就变为原来的100倍。但实际上假如x变为10倍,E[x]应该也为10倍。
抱歉,之前的公式漏了一项,现在补充上去了。不知道现在还有没有疑问,公式2是数值积分,而不是采样估计。
现在没有疑问了,感谢!
October 28th, 2024
苏神,您好,关于式(18)和式(19),有些gap有些难以理解:
1. 针对二值图像,从极大似然角度出发,式(18)中的D应该是样本总数量,那么,\rho _{k}(z)是伯努利分布的概率取值,并且应该与k无关,该取值一般\rho\in [0,1], 那么,通过该loss,理论上无法生成完美的二值图像。
2. 针对一般图像,使用MSE或者BCE LossE,正如您在【1】中的实现方案。我们考虑BCE的情况,那么,式(19)中的D是像素总数,该式中的x_{(k)}则为位置k处像素点取值(归一化),\rho _{k}(z)为解码器输出的概率值。细想这一点,还存在一个gap, q(x|z)的x的含义是什么?因为x已经是像素点取值了,即x\in[0,1], 那么,q(x|z)就无法理解了。
3. 在第二点基础上,我们进一步分析,p(z|x)为编码器,那么,x为输入图像,x_{(k)}则为位置k处像素点取值,这一点是合理的。但是,q(x|z)应该是解码器的输出图像,那么,解码器和编码器图像一致的情况,则只有在x_{(k)}=q(x_{(k)}|z)成立,这一点有些费解。
以上困惑,本人看过VAE原文以及很多解读文章,都无法得到解惑。不知苏神,您怎么看?
【1】苏剑林,https://github.com/bojone/vae/blob/master/vae_keras.py, 第62行。
本文说的q(x|z),是针对单个样本的,z是encoder的编码结果,x是目标图像,它是一个向量or矩阵,所以D是向量or矩阵的总维度,即单张图像的总像素数,比如cifar-10的图像是32*32*3大小的,那么D=3072。
首先,非常感谢您的回复,但是,我想在尝试“狡辩”一下,我目前理解下来伯努利分布在式(18)中依然有些不太直观。
我们回顾一下,N个样本的伯努利分布似然函数:
lnL(\rho|x_1,x_2,...,x_N)=ln\prod_{i=1}^{N}P(X=x_i|\rho)\\ =ln\prod_{i=1}^{N}\rho^{x_i}(1-\rho)^{1-x_i}\\ =\sum_{i=1}^{N}(x_i ln\rho+(1-x_i)ln(1-\rho))
对比上式与式(18),二者存在一个关键区别:
1. 上式中的伯努利参数\rho与样本无关。
2. VAE中的伯努利参数\rho_{(k)}(z)与样本x相关,因为z与x相关。
换个角度去理解,我们讨论的二值图像x_{(k)}\in\{0,1\},编码器和解码器输出完全一致时,我们可以得出x_{(k)}==\rho_{(k)}(z)\in \{0,1\},而这,只能勉强算是伯努利分布的一个特例了。
综上,本人认为VAE中的伯努利分布,理论上理解起来依然有些不太自然。
最后,一个小小纠正,公式(17)至(18)中的文字描述,MNIST并非二值图像,其取值属于[0,1]。
前面已经说了,VAE的loss定义中不涉及多个样本,它就是单个样本,每个样本有多分量,每个分量独立地服从不同的以z为条件的分布。
关于MNIST的数值,很多时候确实会取一个阈值,将MNIST来二值化,从而使用伯努利分布。
November 4th, 2024
直面联合分布,最后是不是加上一个常数呀,小白想了很久,不敢质疑苏神
加减也没什么区别吧,我这里是减,常数是\mathbb{E}_{x\sim \tilde{p}(x)} \big[\ln \tilde{p}(x)\big]
December 29th, 2024
[...] 本文对COMPLETER: Incomplete Multi-view Clustering via Contrastive Prediction这篇文章进行讲解,由于论文思路及其数学推导相对简单,因此没把精力放在敲公式与论文复述上,大部分内容来自参考文献。这篇文章阅读前提可以看看变分推断与变分自编码器,所提跨视图对偶预测损失计算时可以参考变分自编码器部分,或者参考变分自编码器(二):从贝[...]
January 20th, 2025
减去的常数是不是就是x的负信息熵呀,所以损失函数的下界就是这个信息熵,信息熵不能为负,按道理损失函数应该是非负的?
对于离散分布是成立的,但对于连续型概率密度,它的信心熵-\int p(x)\log p(x)dx不一定是非负的(p(x)没有小于等于1的约束)。
March 10th, 2025
苏神您好,我想请教一下,在VAE中,Decoder是在建模q(x|z),假设是正态分布的情况,最后生成图像的时候,我们从q(z)中采样,然后送入Decoder得到生成的图像,但是为什么网上有很多说法(比如下面),说Decoder其实输出的是q(x|z)这个正态分布的均值,还说假设了方差是固定的,然后需要根据均值和方差去采样得到最后的图像,只不过为了简便直接把均值当作结果了,感觉很难理解,希望能得到指点
参考说法:
(1)Encoder阶段:给定数据点 x_i,将其输入Encoder。Encoder通过神经网络计算得到隐变量z的近似后验分布q_{\phi}(z \mid x_i)的参数。通常假设后验分布是一个各维度独立的高斯分布,因此Encoder输出该高斯分布的均值\mu_i和方差\sigma_i^2。
(2)采样阶段: 利用步骤1中得到的高斯分布参数\mu_i和\sigma_i^2,从该高斯分布中采样得到一个隐变量z_i。这个z_i代表与输入数据点x_i相似的一类样本的特征表示。
(3)Decoder阶段: 将采样得到的z_i输入Decoder。Decoder拟合似然分布p_{\theta}(X \mid z_i),即通过神经网络计算得到给定z_i时数据点X的分布参数。通常假设似然分布也是一个各维度独立的高斯分布,因此Decoder输出该高斯分布的均值\mu_i'和方差\sigma_i'^2。
(4)生成阶段: 得到似然分布的参数后,理论上需要从该分布中采样以生成新的数据点x_i。但在实际应用中,通常直接使用Decoder输出的均值\mu_i'作为给定z_i时生成的数据点x_i,而不再进行采样。
“说Decoder其实输出的是q(x|z)这个正态分布的均值,还说假设了方差是固定的,然后需要根据均值和方差去采样得到最后的图像,只不过为了简便直接把均值当作结果了”
这个说法完全正确啊,非常严谨,也就是本文的公式(20)\sim (22)。我不大清楚你难理解的点是哪?