写在前面
本文是一个大二学生的在VAE中挣扎了一周后的学习笔记整理。看了一遍又一遍论文,看了一篇又一篇教程与中外的视频,还是觉得无济于事——直到无意中看到苏剑林老师的VAE五讲,才逐渐走出阴霾,理解了一点点。也受到苏神这种科学分享精神的鼓舞,决定动笔也写下一篇从大二学生视角的VAE学习过程,希望对和我同样处境的朋友一点点帮助。
我大体的思路是按照论文的行文理下来的,当然也加了很多补充与废话。其中肯定有很多理解不到位或者错误,还请大家多多包涵,多多指教!其中主要参考来自苏神的博文与ChatGPT。
看我的废话太多或者错误太多,就赶快跳转苏神的科学空间,不要为难自己哈哈哈。苏神的文章看着很舒服。
论文地址:
(点击红字跳转)https://arxiv.org/abs/1312.6114
苏神博客:
(点击红字跳转)https://kexue.fm/archives/5253
1. 为什么要有VAE?VAE有什么好处?
其实一开始,我看到VAE的时候就是一头雾水?我想着,不是,哥们?你把这数据先编码然后又解码,整这么大一出,是何苦啊?对吧,我有张图片我直接用得了,我干嘛折腾半天,得到一张还不如原来的图片……
但其实那肯定是我的愚昧了。毕竟那么多科学家也不是吃素的,他们肯定比我忙。
变分自编码器(Variational Auto-encoder,VAE)是一种生成模型,其设计目的是学习数据的潜在表示(latent representation),并能够从这种表示生成新的数据样本。
还是看不懂,试着说人话,目的有二:
- 生成与训练数据分布相似的新数据。注意哈,是生成相似的新数据!是要新,且像。例如,在处理图像时,VAE能够生成看起来与训练集中的图像相似的全新图像,从一个人脸真实图生成一堆以假乱真的人脸图。
- VAE通过编码过程将高维数据(如图像)压缩到低维的潜在空间,这种表示通常能够捕捉到数据的主要特征和结构。这种低维表示可以用于各种任务,如数据可视化、数据压缩和特征提取。其实这个降维和压缩数据的功能很不错,你可以实现把一堆大数据压到一个较小的维度存储出来,然后在用的时候通过解码“解压”出来。虽然说哈可能会与原来数据有一丢丢的不同,但总比你存不下了强!
那你可能要问了,你用了什么法术,能凭空把我这么多数据降维了,然后再变出来?其实就是利用数据本身之间的相关性(当然单凭人或者一般的算法是找不出来的),但你别忘了,我们有强大神经网络哈哈!(遇事不决,神经网络)举个栗子,我们有人脸的图片数据集需要压缩,其实每个像素点之间不是没有关联的,就像各个五官的相对位置,各处的颜色、轮廓……等等强大的约束信息,你无法用数学的方法总结约束,但神经网络就能通过训练,把握他们之间的关系,从而存储最为“正交”的信息!这样就实现了降维,当然输出也一样,解铃还须系铃人,我们再用神经网络把它变回来就好了哈哈。
2. 先聊聊AE(Auto-Encoders)
就是所谓的自动编码器,VAE的祖师爷。先做一个简单介绍,其实是对之后理解VAE有很大帮助,初学者直接上来就看VAE容易蒙圈。
自动编码器是一种无监督学习模型,通常用于降维和特征提取。它由两个主要部分组成:编码器(Encoder)和解码器(Decoder)。
编码器(Encoder):
- 输入数据 x x x 被映射到一个潜在空间表示 z z z。
- 这个映射通常通过一个神经网络实现,该网络逐层缩小数据的维度。
- 编码器的目标是提取输入数据的主要特征,丢弃冗余信息。
- 数学表示: z = f θ ( x ) z = f_\theta(x) z=fθ(x),其中 f θ f_\theta fθ是编码器网络, θ \theta θ是网络参数。
解码器(Decoder):
- 潜在表示 z z z 被映射回原始数据空间,生成一个与输入数据相似的重构数据 x ^ \hat{x} x^。
- 解码器同样是一个神经网络,通过逐层扩展数据的维度来恢复原始数据。
- 数学表示: x ^ = g ϕ ( z ) \hat{x} = g_\phi(z) x^=gϕ(z),其中 g ϕ g_\phi gϕ 是解码器网络, ϕ \phi ϕ是网络参数。
自动编码器的训练目标:
自动编码器的训练目标是使重构数据 x ^ \hat{x} x^尽可能接近输入数据 x x x。为此,通常使用重构误差(Reconstruction Error)作为损失函数,如均方误差(MSE,其实就类似于最小二乘法)或交叉熵(Cross-Entropy)。
L ( x , x ^ ) = ∥ x − x ^ ∥ 2 = ∥ x − g ϕ ( f θ ( x ) ) ∥ 2 L(x, \hat{x}) = \|x - \hat{x}\|^2 = \|x - g_\phi(f_\theta(x))\|^2 L(x,x^)=∥x−x^∥2=∥x−gϕ(fθ(x))∥2
通过最小化重构误差,训练过程调整编码器和解码器的参数 θ \theta θ 和 ϕ \phi ϕ,使得编码器提取的特征具有良好的表示能力,解码器能够准确地重构输入数据。
其实哈,我们感觉,凭借万能的神经网络,我们已经达到一个编码解码的过程了,何必在引入一个我一个大二学生根本看不懂的变分过程(V,Variational),一开始翻译软件还给我翻译的变异自动编码器,给我整得一愣一愣的,这玩意哪里变异了???
其实,那必然是AE不够好,有缺陷嘛。
自动编码器的局限性
尽管自动编码器在降维和特征提取方面表现出色,但它们存在一些局限性:
-
生成能力有限:
- 传统自动编码器的编码器和解码器是确定性的映射,缺乏生成新数据的能力。
- 在测试阶段,无法从潜在空间中采样新的潜在变量 z z z来生成新数据。
-
潜在空间结构不明确:
- 编码器将数据映射到潜在空间,但这个空间的结构往往是复杂且不明确的。
- 潜在空间中的点不一定对应于有效的数据样本,这限制了其在生成任务中的应用。
引入变分自编码器(VAE)
为了克服传统自动编码器的局限性,变分自编码器(VAE)被引入。VAE在编码器的基础上引入了概率建模,使得编码器输出潜在变量的分布参数(均值和方差),而不是确定性的潜在表示。(就相当于我不是直接给你丢一个z完事,我神经网络给你丢的是一个均值和方差,然后我还假设了是高斯分布,之后再通过抽样操作抽出z,这不就不是一个准确的死值了嘛而是一个分布了,我觉得这样可以提高泛化性能)通过这种方式,VAE可以在潜在空间中进行采样,从而生成新的数据样本,并且潜在空间具有更明确的结构。
3. VAE千呼万唤始出来
我说了这么多废话(大家实在原谅),因为我兜兜转转看下来,还是感觉小白先看了上面的东西对之后的理解是有帮助的。
问题场景
考虑一个数据集 X = { x ( i ) } i = 1 N X = \{x^{(i)}\}_{i=1}^N X={x(i)}i=1N,它包含了 N N N个独立同分布的样本 x x x,这些样本可以是连续的或离散的变量。我们假设这些数据是由一个随机过程生成的,这个过程涉及一个未观察到的连续随机变量 z z z。生成过程包括两个步骤:
- 从某个先验分布 p θ ∗ ( z ) p_{\theta^*}(z) pθ∗(z)中生成一个值 z ( i ) z^{(i)} z(i)。
- 从某个条件分布 p θ ∗ ( x ∣ z ) p_{\theta^*}(x|z) pθ∗(x∣z)中生成一个值 x ( i ) x^{(i)} x(i)。
我们假设先验 p θ ∗ ( z ) p_{\theta^*}(z) pθ∗(z)和似然 p θ ∗ ( x ∣ z ) p_{\theta^*}(x|z) pθ∗(x∣z)来自于参数化的分布族 p θ ( z ) p_{\theta}(z) pθ(z)和 p θ ( x ∣ z ) p_{\theta}(x|z) pθ(x∣z),并且它们的概率密度函数在 θ \theta θ和 z z z上几乎处处可微。然而,这个过程的大部分对我们来说是隐藏的:真实的参数 θ ∗ \theta^* θ∗以及隐变量 z ( i ) z^{(i)} z(i)的值都是未知的。
核心目标
说点人话,我们现在先编码,再解码,最终想完成的目标是啥?其实是最大化边界似然
p
θ
(
x
)
p_\theta(x)
pθ(x),这时候你可能又要问了,边界似然是个啥?我为啥要使得它最大化?下面我就再仔细解释一下这个:(已了解直接跳到下一部分)
边界似然的定义:
对于给定的观测数据
x
x
x,边际似然
p
θ
(
x
)
p_\theta(x)
pθ(x) 定义为:
p θ ( x ) = ∫ p θ ( x , z ) d z = ∫ p θ ( x ∣ z ) p θ ( z ) d z (1) p_\theta(x) = \int p_\theta(x, z) \, dz = \int p_\theta(x \mid z) p_\theta(z) \, dz\tag{1} pθ(x)=∫pθ(x,z)dz=∫pθ(x∣z)pθ(z)dz(1)
这里, z z z 是潜在变量, p θ ( x ∣ z ) p_\theta(x \mid z) pθ(x∣z) 是观测数据 x x x给定潜在变量 z z z的条件概率分布, p θ ( z ) p_\theta(z) pθ(z) 是潜在变量的先验分布。边际似然是对潜在变量 z z z积分的结果,表示了观测数据 x x x的总体概率。
这个最大化边界似然的操作其实就是我们概率统计中学的极大似然估计,我们想找到能使得 p θ ( x ) p_\theta(x) pθ(x)最大化的参数 θ \theta θ。
我们为啥要最大化边界似然???
一开始其实是朴素的理解,概率当然越大越好。至于为啥,只可意会不可言传哈哈。
其实,对于给定的观测数据
x
x
x,边际似然
p
θ
(
x
)
p_\theta(x)
pθ(x)表示模型生成这个观测数据
x
x
x的概率。换句话说,它表示模型认为这个数据
x
x
x 是“真实的”数据的可能性有多大,那我当然希望他生成概率越大越好啦。如果
p
θ
(
x
)
p_\theta(x)
pθ(x)大,说明模型认为这个数据
x
x
x 很有可能是由模型生成的,或者说模型很“擅长”生成这个数据。对于所有的观测数据
x
x
x,我们希望模型能够很好地生成它们,这意味着我们希望所有
x
x
x 的边际似然
p
θ
(
x
)
p_\theta(x)
pθ(x) 都尽可能大。
那现在搞清楚目标了,我们准备大干一场!不就是把式子(1)最大化嘛?小菜一碟!
理想很丰满,现实很骨感——
上来就给我们泼了一盆凉水,我们不会算!!!
p
θ
(
x
)
=
∫
p
θ
(
x
,
z
)
d
z
=
∫
p
θ
(
x
∣
z
)
p
θ
(
z
)
d
z
p_\theta(x) = \int p_\theta(x, z) \, dz = \int p_\theta(x \mid z) p_\theta(z) \, dz
pθ(x)=∫pθ(x,z)dz=∫pθ(x∣z)pθ(z)dz,据资料说有很多很多原因,我挑了两条我能看懂的:
- 高维积分:隐变量 z z z 常常是高维向量,积分的维度会大幅增加,复杂度很高,且随着维度的增加,计算复杂度呈指数级增长,简单来说,算不动!
- 非线性和复杂的函数形式:生成模型 p θ ( x ∣ z ) p_{\theta}(x|z) pθ(x∣z) 和先验分布 p θ ( z ) p_{\theta}(z) pθ(z)可能是非常复杂和非线性的函数。例如,如果 p θ ( x ∣ z ) p_{\theta}(x|z) pθ(x∣z) 是通过深度神经网络定义的,那么积分中的每一项都需要计算一个复杂的神经网络输出,这使得积分计算非常困难。简单来讲,积不动!
不会算,怎么办?
那好,惹不起我还躲不起吗?
p
θ
(
x
∣
z
)
p_{\theta}(x|z)
pθ(x∣z) 我不会算,那就别算好了,我自己造一个
q
ϕ
(
x
∣
z
)
q_{\phi}(x|z)
qϕ(x∣z) ,我通过一波骚操作逼近
p
θ
(
x
∣
z
)
p_{\theta}(x|z)
pθ(x∣z) ,然后趁机篡位取而代之!这个其实就是V,VAE中最核心的变分推断操作。原谅我又要多说废话了,这里我再补充一下什么是变分,什么是变分推断,知道的同学自觉跳过~
什么是变分?
变分(Variational)是一个数学概念,指的是在优化过程中,通过在函数空间中寻找一个最优的函数,来逼近或优化目标函数。在变分法中,我们不直接在原始的优化问题上求解,而是将问题转换为一个等价或近似的优化问题,通过在更容易处理的函数空间中找到最佳解来达到目的。
什么是变分推断?
变分推断(Variational Inference,VI)是一种用于近似复杂概率分布的技术,特别是当直接计算后验分布非常困难时。其核心思想是将复杂的概率推断问题转换为一个优化问题。
具体来说,在贝叶斯推断中,我们希望估计后验分布 p ( z ∣ x ) p(z \mid x) p(z∣x),但由于计算复杂或不可解,直接计算通常是不可行的。变分推断通过引入一个简单的分布族 q ( z ) q(z) q(z) 来近似真实的后验分布 p ( z ∣ x ) p(z \mid x) p(z∣x)。然后,我们通过优化来最小化两者之间的差异,使得 q ( z ) q(z) q(z) 尽可能接近 p ( z ∣ x ) p(z \mid x) p(z∣x)。(注意这个 q ( z ) q(z) q(z)就是我们所用的 q ϕ ( x ∣ z ) q_{\phi}(x|z) qϕ(x∣z))
来吧,不会算的我们也搞了变分,现在看看能不能算下去:
p
θ
(
x
)
=
∫
p
θ
(
x
,
z
)
d
z
=
∫
q
ϕ
(
x
∣
z
)
p
θ
(
z
)
d
z
p_\theta(x) = \int p_\theta(x, z) \, dz = \int q_{\phi}(x|z)p_\theta(z) \, dz
pθ(x)=∫pθ(x,z)dz=∫qϕ(x∣z)pθ(z)dz
这里呢,我还需要再补充一个知识点——KL散度
什么是KL 散度?
KL散度(Kullback-Leibler Divergence),是信息理论中的一个重要概念,用于衡量两个概率分布之间的差异。它最初由Solomon Kullback和Richard Leibler在1951年提出。
KL散度还需要从信息熵的概念讲起,
熵(Entropy)
熵 H ( P ) H(P) H(P)定义为:
H ( P ) = − ∑ x P ( x ) log P ( x ) H(P) = - \sum_{x} P(x) \log P(x) H(P)=−x∑P(x)logP(x)
熵度量的是使用自身分布 P P P 编码时所需的平均比特数,即分布 P P P的固有不确定性。
交叉熵(Cross-Entropy)
交叉熵 H ( P , Q ) H(P, Q) H(P,Q) 定义为:
H
(
P
,
Q
)
=
−
∑
x
P
(
x
)
log
Q
(
x
)
H(P, Q) = - \sum_{x} P(x) \log Q(x)
H(P,Q)=−x∑P(x)logQ(x)
这里,
P
(
x
)
P(x)
P(x) 是实际分布(或目标分布),
Q
(
x
)
Q(x)
Q(x) 是预测分布(或模型分布)。
交叉熵度量的是使用分布 Q Q Q编码实际分布 P P P 所需的平均比特数。它包含了两个部分:用 Q Q Q编码 P P P的代价,以及因 Q Q Q 与 P P P 不一致所带来的额外代价。
KL散度定义
KL散度 D K L ( P ∥ Q ) D_{KL}(P \parallel Q) DKL(P∥Q)是交叉熵与熵之间的差值。
D
K
L
(
P
∥
Q
)
=
H
(
P
,
Q
)
−
H
(
P
)
D_{KL}(P \parallel Q) = H(P, Q) - H(P)
DKL(P∥Q)=H(P,Q)−H(P)
其实就是交叉熵减去P的熵,表示从预测分布
Q
Q
Q 到实际分布
P
P
P 所需的额外信息量,即用预测分布
Q
Q
Q 对实际分布
P
P
P 进行编码所需的平均比特数减去分布
P
P
P 的固有不确定性。
由此可以推断出,KL散度≥0,当且仅当
Q
Q
Q 与
P
P
P 完全相同时,KL=0,当然这也是我们最期待的状态。
来吧,现在就正式开始了。一般意义上来看,我们进行优化迭代,必须有一个目标函数。在这里,我们需要最大化
p
θ
(
x
)
p_\theta(x)
pθ(x),也就是最大化
l
o
g
p
θ
(
x
(
i
)
)
log p_{\theta}(x^{(i)})
logpθ(x(i)) ,当然,还不能忘了另一个东西,即最小化
p
θ
(
x
∣
z
)
p_{\theta}(x|z)
pθ(x∣z) 与
q
ϕ
(
x
∣
z
)
q_{\phi}(x|z)
qϕ(x∣z) 之间的误差,我们用KL散度表示,即
D
K
L
(
q
ϕ
(
z
∣
x
(
i
)
)
∥
p
θ
(
z
∣
x
(
i
)
)
)
D_{KL}(q_{\phi}(z|x^{(i)}) \parallel p_{\theta}(z|x^{(i)}))
DKL(qϕ(z∣x(i))∥pθ(z∣x(i))),那我索性把
l
o
g
p
θ
(
x
(
i
)
)
log p_{\theta}(x^{(i)})
logpθ(x(i)) 写成:
log
p
θ
(
x
(
i
)
)
=
D
K
L
(
q
ϕ
(
z
∣
x
(
i
)
)
∥
p
θ
(
z
∣
x
(
i
)
)
)
+
L
(
θ
,
ϕ
;
x
(
i
)
)
\log p_{\theta}(x^{(i)}) = D_{KL}(q_{\phi}(z|x^{(i)}) \parallel p_{\theta}(z|x^{(i)})) + \mathcal{L}(\theta, \phi; x^{(i)})
logpθ(x(i))=DKL(qϕ(z∣x(i))∥pθ(z∣x(i)))+L(θ,ϕ;x(i))
移项,得:
log
p
θ
(
x
(
i
)
)
−
D
K
L
(
q
ϕ
(
z
∣
x
(
i
)
)
∥
p
θ
(
z
∣
x
(
i
)
)
)
=
L
(
θ
,
ϕ
;
x
(
i
)
)
\log p_{\theta}(x^{(i)}) -D_{KL}(q_{\phi}(z|x^{(i)}) \parallel p_{\theta}(z|x^{(i)})) = \mathcal{L}(\theta, \phi; x^{(i)})
logpθ(x(i))−DKL(qϕ(z∣x(i))∥pθ(z∣x(i)))=L(θ,ϕ;x(i))
现在只需要最大化
L
(
θ
,
ϕ
;
x
(
i
)
)
\mathcal{L}(\theta, \phi; x^{(i)})
L(θ,ϕ;x(i)) ,即是优化目标,计算得
L
(
θ
,
ϕ
;
x
(
i
)
)
=
−
D
K
L
(
q
ϕ
(
z
∣
x
(
i
)
)
∥
p
θ
(
z
)
)
+
E
q
ϕ
(
z
∣
x
(
i
)
)
[
log
p
θ
(
x
(
i
)
∣
z
)
]
\mathcal{L}(\theta, \phi; x^{(i)}) = -D_{KL}(q_{\phi}(z|x^{(i)}) \parallel p_{\theta}(z)) + \mathbb{E}_{q_{\phi}(z|x^{(i)})} \left[ \log p_{\theta}(x^{(i)}|z) \right]
L(θ,ϕ;x(i))=−DKL(qϕ(z∣x(i))∥pθ(z))+Eqϕ(z∣x(i))[logpθ(x(i)∣z)]
我们需要对这个式子进行更进一步的变换,使其成为能求导优化的式子,先看第一项(当然不想看可以直接跳到推导结果):
第一项计算
−
D
K
L
(
q
ϕ
(
z
∣
x
(
i
)
)
∥
p
θ
(
z
)
)
-D_{KL}(q_{\phi}(z|x^{(i)}) \parallel p_{\theta}(z))
−DKL(qϕ(z∣x(i))∥pθ(z))
刚开始就一直搞不懂这个Loss函数中的第一项
−
D
K
L
(
q
ϕ
(
z
∣
x
)
∣
∣
p
θ
(
z
)
)
-D_{KL}(q_\phi(z|x)||p_\theta(z))
−DKL(qϕ(z∣x)∣∣pθ(z))是怎么得到的,因为其实开始的时候咱们
q
ϕ
(
z
∣
x
)
q_\phi(z|x)
qϕ(z∣x)和
p
θ
(
z
)
p_\theta(z)
pθ(z)都不知道确切的分布是啥,甚至
z
z
z都不知道是啥哈哈。但确实能通过一些数学的计算将其转化成可知参数的形式,就不需要取样之类的复杂操作了。
这里来详细解释一下
−
D
K
L
(
q
ϕ
(
z
∣
x
)
∣
∣
p
θ
(
z
)
)
-D_{KL}(q_\phi(z|x)||p_\theta(z))
−DKL(qϕ(z∣x)∣∣pθ(z))的计算方法,也就是论文中的附录B中的内容解析。
前提条件
我们假设:(这里很重要!!!)
- 先验分布 p θ ( z ) = N ( 0 , I ) p_\theta(z) = N(0, I) pθ(z)=N(0,I)是标准正态分布。
- 后验近似 q ϕ ( z ∣ x ) = N ( z ; μ , σ 2 ) q_\phi(z|x) = N(z; \mu, \sigma^2) qϕ(z∣x)=N(z;μ,σ2)是高斯分布,其中 μ \mu μ 和 σ \sigma σ 是从输入 x x x 通过神经网络得到的均值和标准差。
- 其实这个假设初看也很烧脑,怎么就能这么巧合?在苏剑林老师关于VAE的神作blog中的评论区中,我看到苏老师给了这样一种解释,与其说是假设,不如说是强迫其满足这两个条件,姑且先这么理解~
我们需要计算两部分:
- ∫ q ϕ ( z ∣ x ) log p θ ( z ) d z \int q_\phi(z|x) \log p_\theta(z) dz ∫qϕ(z∣x)logpθ(z)dz
- ∫ q ϕ ( z ∣ x ) log q ϕ ( z ∣ x ) d z \int q_\phi(z|x) \log q_\phi(z|x) dz ∫qϕ(z∣x)logqϕ(z∣x)dz
1. 计算 ∫ q ϕ ( z ) log p θ ( z ) d z \int q_\phi(z) \log p_\theta(z) dz ∫qϕ(z)logpθ(z)dz
由于
p
θ
(
z
)
p_\theta(z)
pθ(z) 是标准正态分布
N
(
0
,
I
)
N(0, I)
N(0,I),其概率密度函数为:
p
θ
(
z
)
=
1
(
2
π
)
J
/
2
exp
(
−
1
2
z
T
z
)
p_\theta(z) = \frac{1}{(2\pi)^{J/2}} \exp\left(-\frac{1}{2}z^Tz\right)
pθ(z)=(2π)J/21exp(−21zTz)
则
log
p
θ
(
z
)
\log p_\theta(z)
logpθ(z) 为:
log
p
θ
(
z
)
=
−
J
2
log
(
2
π
)
−
1
2
z
T
z
\log p_\theta(z) = -\frac{J}{2} \log(2\pi) - \frac{1}{2} z^Tz
logpθ(z)=−2Jlog(2π)−21zTz
现在,计算 ∫ q ϕ ( z ∣ x ) log p θ ( z ) d z \int q_\phi(z|x) \log p_\theta(z) dz ∫qϕ(z∣x)logpθ(z)dz:
∫ q ϕ ( z ∣ x ) log p θ ( z ) d z = ∫ N ( z ; μ , σ 2 ) ( − J 2 log ( 2 π ) − 1 2 z T z ) d z \int q_\phi(z|x) \log p_\theta(z) dz = \int N(z; \mu, \sigma^2) \left( -\frac{J}{2} \log(2\pi) - \frac{1}{2} z^Tz \right) dz ∫qϕ(z∣x)logpθ(z)dz=∫N(z;μ,σ2)(−2Jlog(2π)−21zTz)dz
其中
−
J
2
log
(
2
π
)
-\frac{J}{2} \log(2\pi)
−2Jlog(2π) 是常数,可以提到积分号外面:
=
−
J
2
log
(
2
π
)
−
1
2
∫
N
(
z
;
μ
,
σ
2
)
z
T
z
d
z
= -\frac{J}{2} \log(2\pi) - \frac{1}{2} \int N(z; \mu, \sigma^2) z^Tz dz
=−2Jlog(2π)−21∫N(z;μ,σ2)zTzdz
我们知道,对于高斯分布
N
(
z
;
μ
,
σ
2
)
N(z; \mu, \sigma^2)
N(z;μ,σ2) 来说,
E
[
z
T
z
]
=
∑
j
=
1
J
(
μ
j
2
+
σ
j
2
)
\mathbb{E}[z^Tz] = \sum_{j=1}^J (\mu_j^2 + \sigma_j^2)
E[zTz]=j=1∑J(μj2+σj2)
所以:
∫
N
(
z
;
μ
,
σ
2
)
z
T
z
d
z
=
∑
j
=
1
J
(
μ
j
2
+
σ
j
2
)
\int N(z; \mu, \sigma^2) z^Tz dz = \sum_{j=1}^J (\mu_j^2 + \sigma_j^2)
∫N(z;μ,σ2)zTzdz=j=1∑J(μj2+σj2)
因此:
∫
q
ϕ
(
z
)
log
p
θ
(
z
)
d
z
=
−
J
2
log
(
2
π
)
−
1
2
∑
j
=
1
J
(
μ
j
2
+
σ
j
2
)
\int q_\phi(z) \log p_\theta(z) dz = -\frac{J}{2} \log(2\pi) - \frac{1}{2} \sum_{j=1}^J (\mu_j^2 + \sigma_j^2)
∫qϕ(z)logpθ(z)dz=−2Jlog(2π)−21j=1∑J(μj2+σj2)
2. 计算 ∫ q ϕ ( z ∣ x ) log q ϕ ( z ∣ x ) d z \int q_\phi(z|x) \log q_\phi(z|x) dz ∫qϕ(z∣x)logqϕ(z∣x)dz
由于
q
ϕ
(
z
∣
x
)
q_\phi(z|x)
qϕ(z∣x) 是高斯分布
N
(
z
;
μ
,
σ
2
)
N(z; \mu, \sigma^2)
N(z;μ,σ2),其概率密度函数为:
q
ϕ
(
z
∣
x
)
=
1
(
2
π
σ
2
)
J
/
2
exp
(
−
1
2
σ
2
(
z
−
μ
)
T
(
z
−
μ
)
)
q_\phi(z|x) = \frac{1}{(2\pi\sigma^2)^{J/2}} \exp\left(-\frac{1}{2\sigma^2} (z - \mu)^T (z - \mu)\right)
qϕ(z∣x)=(2πσ2)J/21exp(−2σ21(z−μ)T(z−μ))
则
log
q
ϕ
(
z
∣
x
)
\log q_\phi(z|x)
logqϕ(z∣x) 为:
log
q
ϕ
(
z
∣
x
)
=
−
J
2
log
(
2
π
σ
2
)
−
1
2
σ
2
(
z
−
μ
)
T
(
z
−
μ
)
\log q_\phi(z|x) = -\frac{J}{2} \log(2\pi\sigma^2) - \frac{1}{2\sigma^2} (z - \mu)^T (z - \mu)
logqϕ(z∣x)=−2Jlog(2πσ2)−2σ21(z−μ)T(z−μ)
现在,计算 ∫ q ϕ ( z ∣ x ) log q ϕ ( z ∣ x ) d z \int q_\phi(z|x) \log q_\phi(z|x) dz ∫qϕ(z∣x)logqϕ(z∣x)dz:
∫ q ϕ ( z ∣ x ) log q ϕ ( z ) d z = ∫ N ( z ; μ , σ 2 ) ( − J 2 log ( 2 π σ 2 ) − 1 2 σ 2 ( z − μ ) T ( z − μ ) ) d z \int q_\phi(z|x) \log q_\phi(z) dz = \int N(z; \mu, \sigma^2) \left( -\frac{J}{2} \log(2\pi\sigma^2) - \frac{1}{2\sigma^2} (z - \mu)^T (z - \mu) \right) dz ∫qϕ(z∣x)logqϕ(z)dz=∫N(z;μ,σ2)(−2Jlog(2πσ2)−2σ21(z−μ)T(z−μ))dz
其中
−
J
2
log
(
2
π
σ
2
)
-\frac{J}{2} \log(2\pi\sigma^2)
−2Jlog(2πσ2) 是常数,可以提到积分号外面:
=
−
J
2
log
(
2
π
σ
2
)
−
1
2
σ
2
∫
N
(
z
;
μ
,
σ
2
)
(
z
−
μ
)
T
(
z
−
μ
)
d
z
= -\frac{J}{2} \log(2\pi\sigma^2) - \frac{1}{2\sigma^2} \int N(z; \mu, \sigma^2) (z - \mu)^T (z - \mu) dz
=−2Jlog(2πσ2)−2σ21∫N(z;μ,σ2)(z−μ)T(z−μ)dz
我们知道,对于高斯分布
N
(
z
;
μ
,
σ
2
)
N(z; \mu, \sigma^2)
N(z;μ,σ2) 来说,
(
z
−
μ
)
T
(
z
−
μ
)
(z - \mu)^T (z - \mu)
(z−μ)T(z−μ) 的期望为:
E
[
(
z
−
μ
)
T
(
z
−
μ
)
]
=
∑
j
=
1
J
σ
j
2
\mathbb{E}[(z - \mu)^T (z - \mu)] = \sum_{j=1}^J \sigma_j^2
E[(z−μ)T(z−μ)]=j=1∑Jσj2
所以:
∫
N
(
z
;
μ
,
σ
2
)
(
z
−
μ
)
T
(
z
−
μ
)
d
z
=
∑
j
=
1
J
σ
j
2
\int N(z; \mu, \sigma^2) (z - \mu)^T (z - \mu) dz = \sum_{j=1}^J \sigma_j^2
∫N(z;μ,σ2)(z−μ)T(z−μ)dz=j=1∑Jσj2
因此:
∫
q
ϕ
(
z
∣
x
)
log
q
ϕ
(
z
∣
x
)
d
z
=
−
J
2
log
(
2
π
σ
2
)
−
1
2
∑
j
=
1
J
(
1
+
log
σ
j
2
)
\int q_\phi(z|x) \log q_\phi(z|x) dz = -\frac{J}{2} \log(2\pi\sigma^2) - \frac{1}{2} \sum_{j=1}^J (1 + \log \sigma_j^2)
∫qϕ(z∣x)logqϕ(z∣x)dz=−2Jlog(2πσ2)−21j=1∑J(1+logσj2)
最终KL散度解析结果
将以上两部分结合起来,得到最终的KL散度解析结果:
−
D
K
L
(
q
ϕ
(
z
∣
x
)
∣
∣
p
θ
(
z
)
)
=
1
2
∑
j
=
1
J
(
1
+
log
(
σ
j
2
)
−
μ
j
2
−
σ
j
2
)
-D_{KL}(q_\phi(z|x)||p_\theta(z)) = \frac{1}{2} \sum_{j=1}^J \left( 1 + \log(\sigma_j^2) - \mu_j^2 - \sigma_j^2 \right)
−DKL(qϕ(z∣x)∣∣pθ(z))=21j=1∑J(1+log(σj2)−μj2−σj2)
其中, J J J 是潜在变量 z z z 的维数, μ j \mu_j μj 和 σ j \sigma_j σj 分别是第 j j j 个维度上的均值和标准差。
可以看到,最终KL散度的构成都是由 σ \sigma σ、 μ \mu μ组成,这些都是在神经网络的训练中可以得到的值。
第二项计算
E
q
ϕ
(
z
∣
x
(
i
)
)
[
log
p
θ
(
x
(
i
)
∣
z
)
]
\mathbb{E}_{q_{\phi}(z|x^{(i)})} \left[ \log p_{\theta}(x^{(i)}|z) \right]
Eqϕ(z∣x(i))[logpθ(x(i)∣z)]
一般这种类型的问题,我们可以使用常规的蒙特卡罗梯度估计器(Monte Carlo gradient estimator),其实底层逻辑就是大数定律:
∇
ϕ
E
q
ϕ
(
z
)
[
f
(
z
)
]
=
E
q
ϕ
(
z
)
[
f
(
z
)
∇
q
ϕ
(
z
)
log
q
ϕ
(
z
)
]
≈
1
L
∑
l
=
1
L
f
(
z
)
∇
q
ϕ
(
z
(
l
)
)
log
q
ϕ
(
z
(
l
)
)
\nabla_{\phi} \mathbb{E}_{q_{\phi}(z)} [f(z)] = \mathbb{E}_{q_{\phi}(z)} \left[ f(z) \nabla_{q_{\phi}(z)} \log q_{\phi}(z) \right] \approx \frac{1}{L} \sum_{l=1}^{L} f(z) \nabla_{q_{\phi}(z^{(l)})} \log q_{\phi}(z^{(l)})
∇ϕEqϕ(z)[f(z)]=Eqϕ(z)[f(z)∇qϕ(z)logqϕ(z)]≈L1l=1∑Lf(z)∇qϕ(z(l))logqϕ(z(l))
其中
z
(
l
)
∼
q
ϕ
(
z
∣
x
(
i
)
)
z^{(l)} \sim q_{\phi}(z|x^{(i)})
z(l)∼qϕ(z∣x(i)) 。我们发现,这个梯度估计器表现出很高的方差,对于我们的目的来说是不切实际的,
当然,还有另一个致命的问题,就是“采样”的过程是不可导的!(先别急,往下看)所以必须另辟蹊径!!!
重参数化技巧(The Reparameterization Trick)
在解决上述问题时,我们引入了一种替代方法来从 q ϕ ( z ∣ x ) q_{\phi}(z|x) qϕ(z∣x) 生成样本。这种重新参数化技巧(Reparameterization Trick)非常简单。设 z z z 是一个连续随机变量,且 z ∼ q ϕ ( z ∣ x ) z \sim q_{\phi}(z|x) z∼qϕ(z∣x) 是某个条件分布。通常可以将随机变量 z z z 表示为一个确定性的变量 z = g ϕ ( ϵ , x ) z = g_{\phi}(\epsilon, x) z=gϕ(ϵ,x),其中 ϵ \epsilon ϵ 是具有独立边际分布 p ( ϵ ) p(\epsilon) p(ϵ) 的辅助变量, g ϕ ( . ) g_{\phi}(.) gϕ(.) 是由参数 ϕ \phi ϕ 参数化的某个向量值函数。
这种重新参数化在我们的情况下非常有用,因为它可以用来重写关于 q ϕ ( z ∣ x ) q_{\phi}(z|x) qϕ(z∣x) 的期望,使得期望的蒙特卡罗估计量相对于 ϕ \phi ϕ 可微。证明如下。假设确定性映射 z = g ϕ ( ϵ , x ) z = g_{\phi}(\epsilon, x) z=gϕ(ϵ,x),我们知道 q ϕ ( z ∣ x ) ∏ i d z i = p ( ϵ ) ∏ i d ϵ i q_{\phi}(z|x) \prod_i dz_i = p(\epsilon) \prod_i d\epsilon_i qϕ(z∣x)∏idzi=p(ϵ)∏idϵi。因此,
∫ q ϕ ( z ∣ x ) f ( z ) d z = ∫ p ( ϵ ) f ( z ) d ϵ = ∫ p ( ϵ ) f ( g ϕ ( ϵ , x ) ) d ϵ \int q_{\phi}(z|x)f(z) dz = \int p(\epsilon)f(z) d\epsilon = \int p(\epsilon)f(g_{\phi}(\epsilon, x)) d\epsilon ∫qϕ(z∣x)f(z)dz=∫p(ϵ)f(z)dϵ=∫p(ϵ)f(gϕ(ϵ,x))dϵ
由此可构建一个可微估计器:
∫ q ϕ ( z ∣ x ) f ( z ) d z ≈ 1 L ∑ l = 1 L f ( g ϕ ( x , ϵ ( l ) ) ) \int q_{\phi}(z|x)f(z) dz \approx \frac{1}{L} \sum_{l=1}^{L} f(g_{\phi}(x, \epsilon^{(l)})) ∫qϕ(z∣x)f(z)dz≈L1l=1∑Lf(gϕ(x,ϵ(l)))
其中 ϵ ( l ) ∼ p ( ϵ ) \epsilon^{(l)} \sim p(\epsilon) ϵ(l)∼p(ϵ)。
我第一次看完上面这段专业术语的描述,可以说是一脸懵逼,完全不知道在干什么,为了啥。下面就来说人话解释:
就是我们要从
q
ϕ
(
z
∣
x
)
q_{\phi}(z|x)
qϕ(z∣x) 中采样一个
z
z
z 出来,尽管我们知道了
q
ϕ
(
z
∣
x
)
q_{\phi}(z|x)
qϕ(z∣x) 是正态分布,但是均值方差都是靠模型算出来的,我们要靠这个过程反过来优化均值方差的模型,但是“采样”这个操作是不可导的,而采样的结果是可导的。我们知道,神经网络的反馈迭代更新,就是通过各项的微分计算而成的。而
q
ϕ
(
z
∣
x
)
=
N
(
z
;
μ
,
σ
2
)
q_\phi(z|x) = N(z; \mu, \sigma^2)
qϕ(z∣x)=N(z;μ,σ2) ,所以我们要优化的参数
ϕ
\phi
ϕ 是
μ
\mu
μ 和
σ
\sigma
σ ,也就是要对其求导,但你想想,如果我冷不丁抽了一个
z
z
z 出来,你怎么求导???你求不了!
所以,科学家们就灵光一现,想出了现在这个好办法,但其实这个思想我们高中就经常用,把任何高斯分布转换成标准正态分布:
ϵ
=
(
z
−
μ
)
/
σ
\epsilon=(z-\mu)/\sigma
ϵ=(z−μ)/σ
此时,
ϵ
∼
N
(
0
,
I
)
\epsilon\sim N(0,I)
ϵ∼N(0,I),服从标准正态分布,而且有
z
=
ϵ
∗
σ
+
μ
z=\epsilon*\sigma+\mu
z=ϵ∗σ+μ
这下是不是就可以对
μ
\mu
μ 和
σ
\sigma
σ求导了?而且只需要从确定的
N
(
0
,
I
)
N(0,I)
N(0,I) 分布中抽取
ϵ
\epsilon
ϵ 即可计算得到
z
z
z ,这样一来,“采样”这个操作就不用参与梯度下降了,改为采样的结果参与,使得整个模型可训练了,一举两得,神来之笔!
(上图同样来源于苏老师博客,是对VAE结构的形象表现)
通过上面的推导,可以写出:
L ~ B ( θ , ϕ ; x ( i ) ) = − D K L ( q ϕ ( z ∣ x ( i ) ) ∥ p θ ( z ) ) + 1 L ∑ l = 1 L ( log p θ ( x ( i ) ∣ z ( i , l ) ) ) = 1 2 ∑ j = 1 J ( 1 + log ( ( σ j ( i ) ) 2 ) − ( μ j ( i ) ) 2 − ( σ j ( i ) ) 2 ) + 1 L ∑ l = 1 L ( log p θ ( x ( i ) ∣ g ϕ ( ε ( i , l ) , x ( i ) ) ) ) \tilde{L}_B(\theta, \phi; x^{(i)}) = -D_{KL}(q_\phi(z|x^{(i)}) \| p_\theta(z)) + \frac{1}{L} \sum_{l=1}^L \left( \log p_\theta(x^{(i)}|z^{(i,l)}) \right) = \frac{1}{2} \sum_{j=1}^J \left( 1 + \log((\sigma_j^{(i)})^2) - (\mu_j^{(i)})^2 - (\sigma_j^{(i)})^2 \right) + \frac{1}{L} \sum_{l=1}^L \left( \log p_\theta(x^{(i)}|g_\phi(\varepsilon^{(i,l)}, x^{(i)})) \right) L~B(θ,ϕ;x(i))=−DKL(qϕ(z∣x(i))∥pθ(z))+L1l=1∑L(logpθ(x(i)∣z(i,l)))=21j=1∑J(1+log((σj(i))2)−(μj(i))2−(σj(i))2)+L1l=1∑L(logpθ(x(i)∣gϕ(ε(i,l),x(i))))
其中 z ( i , l ) = g ϕ ( ε ( i , l ) , x ( i ) ) z^{(i,l)} = g_\phi(\varepsilon^{(i,l)}, x^{(i)}) z(i,l)=gϕ(ε(i,l),x(i)) 且 ε ( l ) ∼ N ( 0 , I ) \varepsilon^{(l)} \sim N(0,I) ε(l)∼N(0,I)。
之后,计算
L
~
(
θ
,
ϕ
;
x
)
\tilde{L}(\theta, \phi; x^{})
L~(θ,ϕ;x),我们当然不想把
1
∼
N
1\sim N
1∼N 所有的
L
~
B
(
θ
,
ϕ
;
x
(
i
)
)
\tilde{L}_B(\theta, \phi; x^{(i)})
L~B(θ,ϕ;x(i)) 都拿来加起来,那样计算量太大了,所以我们往往采用 Minibatch 算法,就是从一个很大的全集中抽取一小部分(其实也不小,但相对来说是小的)来代替总体,这样可以减少计算量。
L
~
(
θ
,
ϕ
;
X
)
=
L
~
B
(
θ
,
ϕ
;
X
M
)
=
N
M
∑
i
=
1
M
(
L
~
B
(
θ
,
ϕ
;
x
(
i
)
)
\tilde{L}(\theta, \phi; X^{})=\tilde{L}_B(\theta, \phi; X^{M}) = \frac{N}{M} \sum_{i=1}^M \left( \tilde{L}_B(\theta, \phi; x^{(i)}\right)
L~(θ,ϕ;X)=L~B(θ,ϕ;XM)=MNi=1∑M(L~B(θ,ϕ;x(i))
其中,小批量
X
M
=
x
(
i
)
,
i
=
1
∼
M
X^{M} = {x^{(i)}},i=1\sim M
XM=x(i),i=1∼M 是从包含
N
N
N 个数据点的完整数据集
X
X
X 中随机抽取的
M
M
M 个数据点样本。在实验中,我们发现只要小批量
M
M
M 足够大(例如
M
=
100
M = 100
M=100),每个数据点的样本数
L
L
L 可以设置为 1,所以得到
L
~
(
θ
,
ϕ
;
X
)
=
N
M
∑
i
=
1
M
(
1
2
∑
j
=
1
J
(
1
+
log
(
(
σ
j
(
i
)
)
2
)
−
(
μ
j
(
i
)
)
2
−
(
σ
j
(
i
)
)
2
)
+
log
p
θ
(
x
(
i
)
∣
g
ϕ
(
ε
(
i
,
l
)
,
x
(
i
)
)
)
)
\tilde{L}(\theta, \phi; X^{})= \frac{N}{M} \sum_{i=1}^M \left(\frac{1}{2} \sum_{j=1}^J \left( 1 + \log((\sigma_j^{(i)})^2) - (\mu_j^{(i)})^2 - (\sigma_j^{(i)})^2 \right) + \log p_\theta(x^{(i)}|g_\phi(\varepsilon^{(i,l)}, x^{(i)}))\right)
L~(θ,ϕ;X)=MNi=1∑M(21j=1∑J(1+log((σj(i))2)−(μj(i))2−(σj(i))2)+logpθ(x(i)∣gϕ(ε(i,l),x(i))))
其实后面还有一些内容,关于 ∑ l = 1 L ( log p θ ( x ( i ) ∣ z ( i , l ) ) ) \sum_{l=1}^L \left( \log p_\theta(x^{(i)}|z^{(i,l)}) \right) ∑l=1L(logpθ(x(i)∣z(i,l))) 的分类讨论处理,这里我觉得大家还是直接去看苏神的文章《变分自编码器(二):从贝叶斯观点出发》里的解释,非常清晰!我直接超过来也不太好哈哈哈(其实是懒了)
AEVB算法的Minibatch版本
文章接着描述了AEVB算法的minibatch版本,其中可以使用第2.3节中的任一SGVB估计器。在实验中,我们使用了 ( M = 100 ) 和 ( L = 1 ) 的设置。
-
参数初始化:初始化参数 θ \theta θ 和 ϕ \phi ϕ
-
重复以下步骤直到参数收敛:
- 从完整数据集中随机抽取一个包含 M M M 个数据点的Minibatch X M X_M XM
- 从噪声分布 p ( ε ) p(\varepsilon) p(ε) 中随机抽取样本 ε \varepsilon ε
- 计算Minibatch估计器的梯度 g = ∇ θ , ϕ L ~ M ( θ , ϕ ; X M , ε ) g = \nabla_{\theta, \phi} \tilde{L}_M(\theta, \phi; X_M, \varepsilon) g=∇θ,ϕL~M(θ,ϕ;XM,ε)
- 使用梯度 g g g更新参数 θ \theta θ 和 ϕ \phi ϕ(例如,使用SGD 或 Adagrad算法)
-
返回参数 θ \theta θ 和 ϕ \phi ϕ。
结语
基本的关于VAE的理论部分就到这里啦,希望上面罗里吧嗦的话能对大家有一点点帮助,当然也再次感谢苏剑林老师的文章!
之后有空我会补上完整的实现代码与细节理论补充~