详解变分自编码器——VAE

详解变分自编码器——VAE本文主要对变分自编码器 VAE 做了介绍以及详细推导

本文将介绍另一生成模型——变分自编码器VAE。

详解变分自编码器——VAE

VAE全称(Variational Auto-Encoder)即变分自编码器。是一个生成模型。

了解VAE之间,我们先简单了解一下自编码器,也就是常说的Auto-Encoder

Auto-Encoder包括一个编码器(Encoder)和一个解码器(Decoder)。其结构如下:

Auto-Encoder

中间的这层code也称embedding。

VAE的目标

先假设一个隐变量Z的分布,构建一个从Z到目标数据X的模型,即构建 X = g ( Z ) X=g(Z) X=g(Z),使得学出来的目标数据与真实数据的概率分布相近。与GAN基本一致,GAN学的也是概率分布。

模型结构

VAE的结构图(图源自苏老师的博客,侵删)如下:

VAE结构

VAE对每一个样本 X k X_k Xk匹配一个高斯分布,隐变量Z就是从高斯分布中采样得到的。对K个样本来说,每个样本的高斯分布假设为 N ( μ k , σ k 2 ) \mathcal N(\mu_k,\sigma_k^2) N(μk,σk2),问题就在于如何拟合这些分布。

VAE构建两个神经网络来进行拟合均值与方差。即 μ k = f 1 ( X k ) , l o g σ k 2 = f 2 ( X k ) \mu_k=f_1(X_k),log\sigma_k^2=f_2(X_k) μk=f1(Xk),logσk2=f2(Xk),拟合 l o g σ k 2 log\sigma_k^2 logσk2的原因是这样无需加激活函数。

此外,VAE让每个高斯分布尽可能地趋于标准高斯分布 N ( 0 , 1 ) \mathcal N(0,1) N(0,1)。这拟合过程中的误差损失则是采用KL散度作为计算。

下面做详细推导。

原理推导

其实,VAE与同为生成模型的GMM(高斯混合模型)也有很相似,实际上VAE可看成是GMM的一个distributed representation的版本。我们知道,GMM是有限个高斯分布的隐变量 z z z 的混合,而VAE可看成是无穷个隐变量 z z z 的混合,注意,VAE中的 z z z 可以是高斯也可以是非高斯的。只不过一般用的比较多的是高斯的。

原始样本数据 x x x 的概率分布:
P ( x ) = ∫ Z P ( x ) P ( x ∣ z ) d z P(x)=\int_Z P(x)P(x|z)dz P(x)=ZP(x)P(xz)dz
我们假设 z z z 服从标准高斯分布,先验分布 P ( x ∣ z ) P(x|z) P(xz) 是高斯的,即 x ∣ z ∼ N ( μ ( z ) , σ ( z ) ) x|z \sim N(\mu(z),\sigma(z)) xzN(μ(z),σ(z)) μ ( z ) 、 σ ( z ) \mu(z)、\sigma(z) μ(z)σ(z)是两个函数, 分别是 z z z对应的高斯分布的均值和方差(如下图),则 P ( x ) P(x) P(x) 就是在积分域上所有高斯分布的累加。

在这里插入图片描述

由于 P ( z ) P(z) P(z) 是已知的, P ( x ∣ z ) P(x|z) P(xz) 未知,所以求解问题实际上就是求 μ , σ \mu,\sigma μ,σ这两个函数。我们最开始的目标是求解 P ( x ) P(x) P(x),且我们希望 P ( x ) P(x) P(x)越大越好,这等价于求解关于 x x x 最大对数似然:
L = ∑ x l o g P ( x ) L=\sum_x logP(x) L=xlogP(x)

l o g P ( x ) logP(x) logP(x) 可变换为:
l o g P ( x ) = ∫ z q ( z ∣ x ) l o g P ( x ) d z = ∫ z q ( z ∣ x ) l o g ( P ( z , x ) P ( z ∣ x ) ) d z = ∫ z q ( z ∣ x ) l o g ( P ( z , x ) q ( z ∣ x ) q ( z ∣ x ) P ( z ∣ x ) ) d z = ∫ z q ( z ∣ x ) l o g ( P ( z , x ) q ( z ∣ x ) ) d z + ∫ z q ( z ∣ x ) l o g ( q ( z ∣ x ) P ( z ∣ x ) ) d z = ∫ z q ( z ∣ x ) l o g ( P ( x ∣ z ) P ( z ) q ( z ∣ x ) ) d z + ∫ z q ( z ∣ x ) l o g ( q ( z ∣ x ) P ( z ∣ x ) ) d z \begin{aligned} logP(x)&=\int_z q(z|x)logP(x)dz \\ &=\int_z q(z|x)log(\dfrac{P(z,x)}{P(z|x)})dz \\ &=\int_z q(z|x)log(\dfrac{P(z,x)}{q(z|x)}\dfrac{q(z|x)}{P(z|x)})dz\\ &=\int_z q(z|x)log(\dfrac{P(z,x)}{q(z|x)})dz+ \int_z q(z|x)log(\dfrac{q(z|x)}{P(z|x)})dz\\ &=\int_z q(z|x)log(\dfrac{P(x|z)P(z)}{q(z|x)})dz + \int_z q(z|x)log(\dfrac{q(z|x)}{P(z|x)})dz \end{aligned} logP(x)=zq(zx)logP(x)dz=zq(zx)log(P(zx)P(z,x))dz=zq(zx)log(q(zx)P(z,x)P(zx)q(zx))dz=zq(zx)log(q(zx)P(z,x))dz+zq(zx)log(P(zx)q(zx))dz=zq(zx)log(q(zx)P(xz)P(z))dz+zq(zx)log(P(zx)q(zx))dz

到这里我们发现,第二项 ∫ z q ( z ∣ x ) l o g ( q ( z ∣ x ) P ( z ∣ x ) ) d z \int_z q(z|x)log(\dfrac{q(z|x)}{P(z|x)})dz zq(zx)log(P(zx)q(zx))dz 其实就是 q q q P P P 的KL散度,即 K L ( q ( z ∣ x )    ∣ ∣    P ( z ∣ x ) ) KL(q(z|x)\;||\;P(z|x)) KL(q(zx)P(zx)),因为KL散度是大于等于0的,

为了让 l o g P ( x ) logP(x) logP(x) 越大,我们目的就是要最大化它的这个下界。

推到这里,可能会有个疑问:为什么要引入 q ( z ∣ x ) q(z|x) q(zx)(这里的 q ( z ∣ x ) q(z|x) q(zx)可以是任何分布)?

实际上,因为后验分布 P ( z ∣ x ) P(z|x) P(zx) 很难求(intractable),所以才用 q ( z ∣ x ) q(z|x) q(zx) 来逼近这个后验分布。在优化的过程中我们发现,首先 q ( z ∣ x ) q(z|x) q(zx) l o g P ( x ) logP(x) logP(x) 是完全没有关系的, l o g P ( x ) logP(x) logP(x) 只跟 P ( z ∣ x ) P(z|x) P(zx) 有关,调节 q ( z ∣ x ) q(z|x) q(zx) 是不会影响似然也就是 l o g P ( x ) logP(x) logP(x) 的。所以,当我们固定住 P ( x ∣ z ) P(x|z) P(xz) 时,调节 q ( z ∣ x ) q(z|x) q(zx) 最大化下界 L b L_b Lb,KL则越小。当 q ( z ∣ x ) q(z|x) q(zx)与不断逼近后验分布 P ( z ∣ x ) P(z|x) P(zx)时,KL散度趋于为0, l o g P ( x ) logP(x) logP(x)就和 L b L_b Lb 等价。所以最大化 l o g P ( x ) logP(x) logP(x) 就等价于最大化 L b L_b Lb

在这里插入图片描述

回顾 L b L_b Lb,
L b = ∫ z q ( z ∣ x ) l o g ( P ( x ∣ z ) P ( z ) q ( z ∣ x ) ) d z = ∫ z q ( z ∣ x ) l o g ( P ( z ) q ( z ∣ x ) ) d z + ∫ z q ( z ∣ x ) l o g P ( x ∣ z ) d z = − K L ( q ( z ∣ x )    ∣ ∣    P ( z ) ) + ∫ z q ( z ∣ x ) l o g P ( x ∣ z ) d z = − K L ( q ( z ∣ x )    ∣ ∣    P ( z ) ) + E q ( z ∣ x ) [ l o g ( P ( x ∣ z ) ) ] \begin{aligned} L_b&=\int_z q(z|x)log(\dfrac{P(x|z)P(z)}{q(z|x)})dz \\ &=\int_z q(z|x)log(\dfrac{P(z)}{q(z|x)})dz+\int_z q(z|x)logP(x|z)dz \\ &=-KL(q(z|x)\;||\;P(z)) + \int_z q(z|x)logP(x|z)dz \\ &=-KL(q(z|x)\;||\;P(z)) + E_{q(z|x)}[log(P(x|z))] \end{aligned} Lb=zq(zx)log(q(zx)P(xz)P(z))dz=zq(zx)log(q(zx)P(z))dz+zq(zx)logP(xz)dz=KL(q(zx)P(z))+zq(zx)logP(xz)dz=KL(q(zx)P(z))+Eq(zx)[log(P(xz))]

显然,最大化 L b L_b Lb 就是等价于最小化 K L ( q ( z ∣ x )    ∣ ∣    P ( z ) ) KL(q(z|x)\;||\;P(z)) KL(q(zx)P(z)) 和最大化 E q ( z ∣ x ) [ l o g ( P ( x ∣ z ) ) ] E_{q(z|x)}[log(P(x|z))] Eq(zx)[log(P(xz))]

第一项,最小化KL散度。我们前面已假设了 P ( z ) P(z) P(z) 是服从标准高斯分布的,且 q ( z ∣ x ) q(z|x) q(zx) 是服从高斯分布 N ( μ , σ 2 ) \mathcal N(\mu,\sigma^2) N(μ,σ2) ,于是代入计算可得:
K L ( q ( z ∣ x )    ∣ ∣    P ( z ) ) = K L ( N ( μ , σ 2 )    ∣ ∣    N ( 0 , 1 ) ) = ∫ 1 2 π σ 2 e − ( x − μ ) 2 2 σ 2 ( l o g e − ( x − μ ) 2 2 σ 2 / 2 π σ 2 e − x 2 2 / 2 π ) d x . . . 化简得到 = 1 2 1 2 π σ 2 ∫ e − ( x − μ ) 2 2 σ 2 ( − l o g σ 2 + x 2 − ( x − μ ) 2 σ 2 ) d x = 1 2 ∫ 1 2 π σ 2 e − ( x − μ ) 2 2 σ 2 ( − l o g σ 2 + x 2 − ( x − μ ) 2 σ 2 ) d x \begin{aligned} KL(q(z|x)\;||\;P(z))=KL(\mathcal N(\mu,\sigma^2)\;||\;\mathcal N(0,1))=&\int\dfrac{1}{\sqrt{2\pi\sigma^2}}e^{\frac{-(x-\mu)^2}{2\sigma^2}} \left( log\dfrac{e^{\frac{-(x-\mu)^2}{2\sigma^2}}/\sqrt{2\pi\sigma^2}}{ e^{\frac{-x^2}{2}}/\sqrt{2\pi} } \right)dx \\&…\text{化简得到} \\=&\dfrac{1}{2}\dfrac{1}{\sqrt{2\pi\sigma^2}}\int e^{\frac{-(x-\mu)^2}{2\sigma^2}} \left(-log\sigma^2 +x^2-\dfrac{(x-\mu)^2}{\sigma^2} \right)dx \\=&\dfrac{1}{2}\int \dfrac{1}{\sqrt{2\pi\sigma^2}} e^{\frac{-(x-\mu)^2}{2\sigma^2}} \left(-log\sigma^2 +x^2-\dfrac{(x-\mu)^2}{\sigma^2} \right)dx \end{aligned} KL(q(zx)P(z))=KL(N(μ,σ2)N(0,1))===2πσ2
1
e2σ2(xμ)2loge2x2/2π
e2σ2(xμ)2/2πσ2
dx
...化简得到212πσ2
1
e2σ2(xμ)2(logσ2+x2σ2(xμ)2)dx
212πσ2
1
e2σ2(xμ)2(logσ2+x2σ2(xμ)2)dx

对上式中的积分进一步求解, 1 2 π σ 2 e − ( x − μ ) 2 2 σ 2 \dfrac{1}{\sqrt{2\pi\sigma^2}}e^{\frac{-(x-\mu)^2}{2\sigma^2}} 2πσ2
1
e2σ2(xμ)2
实际就是概率密度 f ( x ) f(x) f(x),而概率密度函数的积分就是1,所以积分第一项等于 − l o g σ 2 -log\sigma^2 logσ2;而又因为高斯分布的二阶矩就是 E ( X 2 ) = ∫ x 2 f ( x ) d x = μ 2 + σ 2 E(X^2)=\int x^2f(x)dx=\mu^2+\sigma^2 E(X2)=x2f(x)dx=μ2+σ2,正好对应积分第二项。又根据方差的定义可知 σ = ∫ ( x − μ ) d x \sigma=\int (x-\mu)dx σ=(xμ)dx,所以积分第三项为 − 1 -1 1

第二项,最大化期望。也就是表明在给定 q ( z ∣ x ) q(z|x) q(zx)(编码器输出)的情况下 P ( x ∣ z ) P(x|z) P(xz)(解码器输出)的值尽可能高。具体来讲,第一步,利用encoder的神经网络计算出均值与方差,从中采样得到 z z z,这一过程就对应式子中的 q ( z ∣ x ) q(z|x) q(zx);第二步,利用decoder的NN计算 z z z 的均值方差,让均值(或也考虑方差)越接近 x x x ,则产生 x x x 的几率 l o g P ( x ∣ z ) logP(x|z) logP(xz) 越大,对应于式子中的最大化 l o g P ( x ∣ z ) logP(x|z) logP(xz) 这一部分。

在这里插入图片描述

推导至此完毕。

重参数技巧

最后模型在实现的时候,有一个重参数技巧,就是我们想从高斯分布 N ( μ , σ 2 ) \mathcal N(\mu,\sigma^2) N(μ,σ2) 中采样Z时,其实是相当于从 N ( 0 , 1 ) \mathcal N(0,1) N(0,1) 中采样一个 ϵ \epsilon ϵ,然后再来计算 Z = μ + ϵ × σ Z=\mu+\epsilon\times\sigma Z=μ+ϵ×σ。这么做的原因是,采样这个操作是不可导的,而采样的结果是可导的,这样做个参数变换, Z = μ + ϵ × σ Z=\mu+\epsilon\times\sigma Z=μ+ϵ×σ 这个就可以参与梯度下降,模型就可以训练了。

参考

  1. 苏剑林:变分自编码器(一):原来是这么一回事
  2. 李宏毅老师 Machine Learning (2017,秋,台湾大学) 国语
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225631.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午8:53
下一篇 2026年3月17日 上午8:53


相关推荐

  • 安卓微信本地数据库解密[通俗易懂]

    安卓微信本地数据库解密[通俗易懂]安卓微信数据库解密

    2022年5月6日
    237
  • 【Linux】使用grep命令查找文件内容

    【Linux】使用grep命令查找文件内容1 grep 是 linux 中最为常用的三大文本 awk sed grep 处理工具之一 2 grep 它能使用 正则表达式 搜索文本 并把匹配的行打印出来 3 grep 全称是 GlobalRegula 表示全局正则表达式打印 它的使用权限是所有用户 4 grep 家族总共有三个 grep egrep fgrep 自己了解区别

    2026年3月19日
    3
  • wireshark抓包工具详细说明及操作使用_wireshark ping抓包

    wireshark抓包工具详细说明及操作使用_wireshark ping抓包wireshark是非常流行的网络封包分析软件,功能十分强大。可以截取各种网络封包,显示网络封包的详细信息。使用wireshark的人必须了解网络协议,否则就看不懂wireshark了。为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发送封包。wireshark能获取HTTP,也能获取HTTPS,但是不能解密HTTPS,所以wireshark看不懂HTTPS中的

    2025年9月28日
    5
  • 针对Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解决方案

    针对Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解决方案背景 本项目使用 JDK1 8 编译 maven 工程的时候出现如下错误 Failedtoexec apache maven plugins maven compiler plugin 3 1pom 中如下配置 maven 插件 配置中声明使用 JDK1 8 org apache maven plugins maven compiler plugin 3

    2026年3月17日
    1
  • Pycharm使用技巧——自动调整代码格式汇总!自动化神器!

    Pycharm使用技巧——自动调整代码格式汇总!自动化神器!代码自动填充了空格问题在使用pycharm的代码编辑器时,常常懒得写空格,如下图,但这是不符合代码规范的,而且也会影响可读性。解决方法pycharm有自动调整代码格式的快捷键,默认为Alt+Ctrl+L,按下快捷键后,代码自动填充了空格。自动对齐代码问题在使用pycharm的代码编辑器时,有点时候copy的代码的没有按照代码格式对齐,如下图,但这是不符合代码规范的,而且也会影响可读性。解决方法pycharm有自动调整代码格式的快捷键,默认为Alt+Ctrl+L

    2022年8月27日
    28
  • 使用Pycharm搭建Flask项目

    使用Pycharm搭建Flask项目标题打开 Pycharm 的 file 选择创建新的项目弹出对话框 我们可以看到里面有很多的案例 Django Flask 等等 我们选择生成 Flask 的 demo 程序 可以自己点击修改项目位置 及其环境 Location 可以修改项目的位置 untitled1 处可以修改项目名字 Python 项目解释器请选择自己已有的 gt 点击 Creat 创建 会自己创建环境创建好了之后如下图所示 static 存放静态文件 templates 文件夹 用于放置 html 模板文件 app py 项 管理 件

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号