超详细VAE学习笔记【万字长文】

写在前面

本文是一个大二学生的在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^)=xx^2=xgϕ(fθ(x))2

通过最小化重构误差,训练过程调整编码器和解码器的参数 θ \theta θ ϕ \phi ϕ,使得编码器提取的特征具有良好的表示能力,解码器能够准确地重构输入数据。

其实哈,我们感觉,凭借万能的神经网络,我们已经达到一个编码解码的过程了,何必在引入一个我一个大二学生根本看不懂的变分过程(V,Variational),一开始翻译软件还给我翻译的变异自动编码器,给我整得一愣一愣的,这玩意哪里变异了???
其实,那必然是AE不够好,有缺陷嘛。

自动编码器的局限性

尽管自动编码器在降维和特征提取方面表现出色,但它们存在一些局限性:

  1. 生成能力有限

    • 传统自动编码器的编码器和解码器是确定性的映射,缺乏生成新数据的能力。
    • 在测试阶段,无法从潜在空间中采样新的潜在变量 z z z来生成新数据。
  2. 潜在空间结构不明确

    • 编码器将数据映射到潜在空间,但这个空间的结构往往是复杂且不明确的。
    • 潜在空间中的点不一定对应于有效的数据样本,这限制了其在生成任务中的应用。

引入变分自编码器(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。生成过程包括两个步骤:

  1. 从某个先验分布 p θ ∗ ( z ) p_{\theta^*}(z) pθ(z)中生成一个值 z ( i ) z^{(i)} z(i)
  2. 从某个条件分布 p θ ∗ ( x ∣ z ) p_{\theta^*}(x|z) pθ(xz)中生成一个值 x ( i ) x^{(i)} x(i)

我们假设先验 p θ ∗ ( z ) p_{\theta^*}(z) pθ(z)和似然 p θ ∗ ( x ∣ z ) p_{\theta^*}(x|z) pθ(xz)来自于参数化的分布族 p θ ( z ) p_{\theta}(z) pθ(z) p θ ( x ∣ z ) p_{\theta}(x|z) pθ(xz),并且它们的概率密度函数在 θ \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θ(xz)pθ(z)dz(1)

这里, z z z 是潜在变量, p θ ( x ∣ z ) p_\theta(x \mid z) pθ(xz) 是观测数据 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θ(xz)pθ(z)dz,据资料说有很多很多原因,我挑了两条我能看懂的:

  • 高维积分:隐变量 z z z 常常是高维向量,积分的维度会大幅增加,复杂度很高,且随着维度的增加,计算复杂度呈指数级增长,简单来说,算不动!
  • 非线性和复杂的函数形式:生成模型 p θ ( x ∣ z ) p_{\theta}(x|z) pθ(xz) 和先验分布 p θ ( z ) p_{\theta}(z) pθ(z)可能是非常复杂和非线性的函数。例如,如果 p θ ( x ∣ z ) p_{\theta}(x|z) pθ(xz) 是通过深度神经网络定义的,那么积分中的每一项都需要计算一个复杂的神经网络输出,这使得积分计算非常困难。简单来讲,积不动!

不会算,怎么办?
那好,惹不起我还躲不起吗? p θ ( x ∣ z ) p_{\theta}(x|z) pθ(xz) 我不会算,那就别算好了,我自己造一个 q ϕ ( x ∣ z ) q_{\phi}(x|z) qϕ(xz) ,我通过一波骚操作逼近 p θ ( x ∣ z ) p_{\theta}(x|z) pθ(xz) ,然后趁机篡位取而代之!这个其实就是V,VAE中最核心的变分推断操作。原谅我又要多说废话了,这里我再补充一下什么是变分,什么是变分推断,知道的同学自觉跳过~


什么是变分?

变分(Variational)是一个数学概念,指的是在优化过程中,通过在函数空间中寻找一个最优的函数,来逼近或优化目标函数。在变分法中,我们不直接在原始的优化问题上求解,而是将问题转换为一个等价或近似的优化问题,通过在更容易处理的函数空间中找到最佳解来达到目的。

什么是变分推断?

变分推断(Variational Inference,VI)是一种用于近似复杂概率分布的技术,特别是当直接计算后验分布非常困难时。其核心思想是将复杂的概率推断问题转换为一个优化问题。

具体来说,在贝叶斯推断中,我们希望估计后验分布 p ( z ∣ x ) p(z \mid x) p(zx),但由于计算复杂或不可解,直接计算通常是不可行的。变分推断通过引入一个简单的分布族 q ( z ) q(z) q(z) 来近似真实的后验分布 p ( z ∣ x ) p(z \mid x) p(zx)。然后,我们通过优化来最小化两者之间的差异,使得 q ( z ) q(z) q(z) 尽可能接近 p ( z ∣ x ) p(z \mid x) p(zx)。(注意这个 q ( z ) q(z) q(z)就是我们所用的 q ϕ ( x ∣ z ) q_{\phi}(x|z) qϕ(xz))


来吧,不会算的我们也搞了变分,现在看看能不能算下去:
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ϕ(xz)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)=xP(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)=xP(x)logQ(x)
这里, P ( x ) P(x) <

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值