【深度学习】VAE变分自编码器原理推导+Python代码实现

1、前言

变分自编码器是近些年较火的一个生成模型,我个人认为其本质上仍然是一个概率图模型,只是在此基础上引入了神经网络。本文将就变分自编码器(VAE)进行简单的原理讲解和数学推导。

论文: Auto-Encoding Variational Bayes

视频:【VAE变分自编码器原理解析-哔哩哔哩】

2、引入

2.1、高斯混合模型

生成模型,可以简单的理解为生成数据 ( 不止,但我们暂且就这么理解它 ) \boxed{(不止,但我们暂且就这么理解它)} (不止,但我们暂且就这么理解它)。假如现在我们有样本数据,而我们发现这些样本符合正态分布且样本具有充分的代表性,因此我们计算出样本的均值和方差,就能得到样本的概率分布。然后从正态分布中抽样,就能得到样本。 这种生成样本的过程就是生成过程 \boxed{\mathbf{这种生成样本的过程就是生成过程}} 这种生成样本的过程就是生成过程

可是,假如我们的数据长这样

在这里插入图片描述

很显然,它的数据是由两个不同的正态分布构成。我们可以计算出这些样本的概率分布。但是一种更为常见的方法就是将其当作是两个正态分布。我们引入一个隐变量z。

假设 z 的取值为 0 , 1 \boxed{\mathbf{假设z的取值为0,1}} 假设z的取值为01,如果z为0,我们就从蓝色的概率分布中抽样;否则为1,则从橙色的概率分布中抽样。这就是生成过程。

但是这个隐变量z是什么?它其实就是隐藏特征 训练数据 x 的抽象出来的特征 \boxed{\mathbf{训练数据x的抽象出来的特征}} 训练数据x的抽象出来的特征,比如,如果x偏小,我们则认为它数据蓝色正太分布,否则为橙色。这个 “偏小” \boxed{“偏小”} 偏小就是特征,我们把它的取值为0,1(0代表偏小,1代表偏大)。

那这种模型我们如何取训练它呢?如何去找出这个z呢? 一种很直观的方法就是重构代价最小 \boxed{\mathbf{一种很直观的方法就是重构代价最小}} 一种很直观的方法就是重构代价最小,我们希望,给一个训练数据x,由x去预测隐变量z,再由隐变量z预测回x,得到的误差最小。比如假如我们是蓝色正态分布,去提取特征z,得到的z再返回来预测x,结果得到的却是橙色的正态分布,这是不可取的。其模型图如下

在这里插入图片描述

这个模型被称为GMM高斯混合模型

2.2、变分自编码器(VAE)

那它和VAE有什么关联呢?其实VAE的模型图跟这个原理差不多。只是有些许改变, 隐变量 z 的维度是连续且高维的,不再是简单的离散分布 \boxed{\mathbf{隐变量z的维度是连续且高维的,不再是简单的离散分布}} 隐变量z的维度是连续且高维的,不再是简单的离散分布,因为假如我们生成的是图片,我们需要提取出来的特征明显是要很多的,传统的GMM无法做到。

在VAE中, q ( z ∣ x ) q(z|x) q(zx) (也就是用样本 x 预测变量 z ) \boxed{(也就是用样本x预测变量z)} (也就是用样本x预测变量z,其服从高斯分布,接下来,我们来看模型图

在这里插入图片描述

也就是将训练样本x给神经网络,让神经网络计算出均值和协方差矩阵 μ , log ⁡ σ 2 \mu,\log \sigma^2 μ,logσ2 取 log ⁡ 的原因是传统的神经网络输出值总是有正有负 \boxed{\mathbf{取\log的原因是传统的神经网络输出值总是有正有负}} log的原因是传统的神经网络输出值总是有正有负。有了这两个值就可以在对应的高斯分布中采样,得到隐变量z。再让z经过神经网络重构回样本,得到新样本。这就是整个VAE的大致过程了。

再次强调 训练过程我们希望每次重构的时候,新样本和训练样本尽可能的相似 \boxed{\mathbf{训练过程我们希望每次重构的时候,新样本和训练样本尽可能的相似}} 训练过程我们希望每次重构的时候,新样本和训练样本尽可能的相似

如果我们这样直接去训练的化,可以吗?可以!但是会有个问题,神经网络会趋向于将协方差变0,而让概率分布 q ( z ∣ x ) q(z|x) q(zx)将不再具备随机性,概率分布空间会坍缩成一个点,每次采样都是均值,这种情况我们俗称过拟合。

为什么协方差会变成0?因为采样具有随机性,也就是存在噪声,噪声是肯定会增加重构的误差的。神经网络为了让误差最小,是肯定让这个随机性越小越好,因为只有这样,才能重构误差最小

但是我们肯定是希望有随机性的,为什么?因为有随机性,我们才可以生成不同的样本啊!

所以,对于概率分布 q ( z ∣ x ) q(z|x) q(zx),我们不希望它的协方差为0,所以我们需要对其进行约束。在论文中,它对其进行约束,要求它尽量的往 N ( 0 , I ) N(0,I) N(0,I)靠近( 其实与先验分布 P ( z ) 有关,后续数学推导中可见 , 假设 P ( z ) ∼ N ( z ∣ 0 , I ) \boxed{其实与先验分布P(z)有关,后续数学推导中可见,假设P(z)\sim N(z|0,I)} 其实与先验分布P(z)有关,后续数学推导中可见,假设P(z)N(z∣0,I)

所以,有KL散度去衡量两个概率分布的相似性
min ⁡ K L ( P ( z ∣ x ) ∣ ∣ P ( z ) ) \min KL\left(P(z|x)||P(z)\right) minKL(P(zx)∣∣P(z))
KL散度是大于等于0的值,越小则证明越相似
K L ( q ( x ) ∣ ∣ p ( x ) ) = ∫ x q ( x ) log ⁡ q ( x ) p ( x ) d x KL(q(x)||p(x))=\int_x q(x)\log\frac{q(x)}{p(x)}dx KL(q(x)∣∣p(x))=xq(x)logp(x)q(x)dx
所以,我们就是两个优化目标
①最小化重构代价 ②最小化上述的 K L 散度 \boxed{\mathbf{①最小化重构代价}}\\ \boxed{\mathbf{②最小化上述的KL散度}} 最小化重构代价最小化上述的KL散度
依照这两个条件,建立目标函数,直接梯度下降 ( 其实还需要重参数化,后面会讲到 ) \boxed{\mathbf{(其实还需要重参数化,后面会讲到)}} (其实还需要重参数化,后面会讲到),刷刷刷地往下降,最终收敛。

下面,我们就对其进行简单的数学推导,并以此推导出目标函数

3、原理推导

3.1、引入目标函数

以VAE的简略图为例

在这里插入图片描述

设我们有N个样本
X = ( x 1 , x 2 , ⋯   , x N ) X=\begin{pmatrix}x^1,x^2,\cdots,x^N\end{pmatrix} X=(x1,x2,,xN)
定义隐变量先验分布 P ( z ) ∼ N ( 0 , I ) P(z) \sim N(0,I) P(z)N(0,I)。很自然的想法,我们直接对x求log极大似然,假设我们有N的样本,记作X。设所需求解的参数为 θ \theta θ,似然函数记为 P θ ( ∣ x ) P_\theta(|x) Pθ(x),为了简便,以下省略 θ \theta θ,第 i i i个样本记为 x i x^{i} xi,某个样本的第 j j j个维度记作 x j x_j xj

log ⁡ P ( X ) = log ⁡ P ( x 1 ) P ( x 2 ) ⋯ P ( x N ) = log ⁡ ∏ i = 1 N P ( x i ) = ∑ i = 1 N log ⁡ P ( x i ) \begin{aligned}\log P(X)=&\log P(x^1)P(x^2)\cdots P(x^N)\\=&\log\prod\limits_{i=1}^N P(x^i)\\=&\sum\limits_{i=1}^N\log P(x^i)\end{aligned} logP(X)===logP(x1)P(x2)P(xN)logi=1NP(xi)i=1NlogP(xi)
现在,我们先单独看看里面某一个样本的似然,某个样本记为 x x x
log ⁡ P ( x ) = log ⁡ P ( x , z ) P ( z ∣ x ) = log ⁡ P ( x , z ) − log ⁡ P ( z ∣ x ) \begin{aligned}\log P(x)=&\log\frac{P(x,z)}{P(z|x)}\\=&\log P(x,z) -\log P(z|x)\end{aligned} logP(x)==logP(zx)P(x,z)logP(x,z)logP(zx)
引入一个 q ϕ ( z ∣ x ) q_\phi(z|x) qϕ(zx)分布, ϕ \phi ϕ是它的参数,为了简便,后续省略掉 ϕ \phi ϕ,直接记为 q ( z ∣ x ) q(z|x) q(zx)

log ⁡ P ( x ) \log P(x) logP(x)等式左右分别对 q ( z ∣ x ) q(z|x) q(zx)求积分
左边: ∫ z log ⁡ P ( x ) q ( z ∣ x ) d z = log ⁡ P ( x ) ∫ z q ( z ∣ x ) d z = log ⁡ P ( x ) \begin{aligned}&\mathbf{左边:}\int_z \log P(x)q(z|x)dz=\log P(x)\int_z q(z|x)dz=\log P(x) \\\end{aligned} 左边:zlogP(x)q(zx)dz=logP(x)zq(zx)dz=logP(x)
所以左边等于右边
log ⁡ P ( x ) = ∫ z ( log ⁡ P ( x , z ) − log ⁡ P ( z ∣ x ) ) q ( z ∣ x ) d z = ∫ z ( log ⁡ P ( x , z ) q ( z ∣ x ) − log ⁡ P ( z ∣ x ) q ( z ∣ x ) ) q ( z ∣ x ) d z = ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z − ∫ z log ⁡ P ( z ∣ x ) q ( z ∣ x ) q ( z ∣ x ) d z = ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z ⏟ ① + K L ( q ( z ∣ x ) ∣ ∣ P ( z ∣ x ) ) ⏟ ② \begin{align}\log P(x)=&\int_z (\log P(x,z)-\log P(z|x))q(z|x)dz\tag{a}\\=&\int_z (\log \frac{P(x,z)}{q(z|x)}-\log \frac{P(z|x)}{q(z|x)})q(z|x)dz\tag{b}\\=&\int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz-\int_z\log\frac{P(z|x)}{q(z|x)}q(z|x)dz\nonumber\\=&\underbrace{\int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz}_{①}+\underbrace{KL(q(z|x)||P(z|x))}_{②}\nonumber\end{align} logP(x)====z(logP(x,z)logP(zx))q(zx)dzz(logq(zx)P(x,z)logq(zx)P(zx))q(zx)dzzlogq(zx)P(x,z)q(zx)dzzlogq(zx)P(zx)q(zx)dz zlogq(zx)P(x,z)q(zx)dz+ KL(q(zx)∣∣P(zx))(a)(b)
(式a)到(式b)用到了 log ⁡ \log log的性质。

那么,现在,我们开始极大似然,似然函数的参数为 θ \theta θ
max ⁡ θ log ⁡ P ( x ) = max ⁡ θ ( ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z ⏟ ① + K L ( q ( z ∣ x ) ∣ ∣ P ( z ∣ x ) ) ⏟ ② ) \max\limits_{\theta}\log P(x)=\max\limits_{\theta}\left(\underbrace{\int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz}_{①}+\underbrace{KL(q(z|x)||P(z|x))}_{②}\right) θmaxlogP(x)=θmax zlogq(zx)P(x,z)q(zx)dz+ KL(q(zx)∣∣P(zx))
因为 P ( z ∣ x ) P(z|x) P(zx)我们算不出来(原因请看,分母的积分计算不了)
P ( z ∣ x ) = P ( z , x ) P ( x ) = P ( x ∣ z ) P ( z ) ∫ P ( x ∣ z ) P ( z ) d z P(z|x)=\frac{P(z,x)}{P(x)}=\frac{P(x|z)P(z)}{\int P(x|z)P(z)dz} P(zx)=P(x)P(z,x)=P(xz)P(z)dzP(xz)P(z)
故而,使用 q ( z ∣ x ) q(z|x) q(zx)去逼近,所以,更新q的参数 ϕ \phi ϕ,以最小化第②项。
min ⁡ ϕ K L ( q ( z ∣ x ) ∣ ∣ P ( z ∣ x ) ) \min\limits_{\phi} KL(q(z|x)||P(z|x)) ϕminKL(q(zx)∣∣P(zx))
在给定x跟 θ \theta θ的情况下, log ⁡ P ( x ) \log P(x) logP(x)的值是确定的,所以最小化第②项,就等于最大化第①项
max ⁡ ϕ ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z ↔ min ⁡ ϕ K L ( q ( z ∣ x ) ∣ ∣ P ( z ∣ x ) ) \max\limits_{\phi} \int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz \leftrightarrow\min\limits_{\phi} KL(q(z|x)||P(z|x)) ϕmaxzlogq(zx)P(x,z)q(zx)dzϕminKL(q(zx)∣∣P(zx))
举个例子,在VAE中,里面的参数 θ , ϕ \theta,\phi θ,ϕ,其实都是用神经网络去逼近的。所以,如果按照刚刚提到的,步骤就长这样
步骤①:固定 θ 参数,利用梯度下降 , 更新参数 ϕ , 以最小化② 步骤②:固定 ϕ 参数,利用梯度下降 , 更新参数 θ , 以最大化① \mathbf{步骤①:固定\theta参数,利用梯度下降,更新参数\phi,以最小化②}\\\mathbf{步骤②:固定\phi参数,利用梯度下降,更新参数\theta,以最大化①} 步骤:固定θ参数,利用梯度下降,更新参数ϕ,以最小化步骤:固定ϕ参数,利用梯度下降,更新参数θ,以最大化

按照上面提到的,我们可以把第一步改成
步骤①:固定 θ 参数,利用梯度下降 , 更新参数 ϕ , 以最大化① \mathbf{步骤①:固定\theta参数,利用梯度下降,更新参数\phi,以最大化①} 步骤:固定θ参数,利用梯度下降,更新参数ϕ,以最大化
更一般地,我们把它们写成一起
max ⁡ θ , ϕ ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z \max\limits_{\theta,\phi} \int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz θ,ϕmaxzlogq(zx)P(x,z)q(zx)dz
由于KL散度是大于等于0的,所以第①项,就被称为变分下界。
log ⁡ P ( x ) ≥ ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z \log P(x)\ge\int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz logP(x)zlogq(zx)P(x,z)q(zx)dz

好,现在我们只需要最大化其变分下界(以下省略掉参数)
max ⁡ ∫ z log ⁡ P ( x , z ) q ( z ∣ x ) q ( z ∣ x ) d z = max ⁡ ∫ z log ⁡ P ( x ∣ z ) P ( z ) q ( z ∣ x ) q ( z ∣ x ) d z = max ⁡ ∫ z ( log ⁡ P ( z ) q ( z ∣ x ) + log ⁡ P ( x ∣ z ) ) q ( z ∣ x ) d z = max ⁡ ∫ z log ⁡ P ( x ∣ z ) q ( z ∣ x ) d z − ∫ log ⁡ q ( z ∣ x ) P ( z ) q ( z ∣ x ) d z = max ⁡ ( E z ∼ q ( z ∣ x ) [ log ⁡ P ( x ∣ z ) ] ⏟ ① − K L ( q ( z ∣ x ) ∣ ∣ P ( z ) ) ⏟ ② ) \begin{aligned}&\max \int_{z}\log\frac{P(x,z)}{q(z|x)}q(z|x)dz\\=&\max \int_z\log \frac{P(x|z)P(z)}{q(z|x)}q(z|x)dz\\=&\max \int_z \left(\log \frac{P(z)}{q(z|x)}+\log P(x|z)\right)q(z|x)dz\\=&\max \int_z\log P(x|z)q(z|x)dz-\int \log \frac{q(z|x)}{P(z)}q(z|x)dz\\=&\max \left(\underbrace{\mathbb{E}_{z\sim q(z|x)}\left[\log P(x|z)\right]}_{①} -\underbrace{KL(q(z|x)||P(z))}_{②}\right)\end{aligned} ====maxzlogq(zx)P(x,z)q(zx)dzmaxzlogq(zx)P(xz)P(z)q(zx)dzmaxz(logq(zx)P(z)+logP(xz))q(zx)dzmaxzlogP(xz)q(zx)dzlogP(z)q(zx)q(zx)dzmax( Ezq(zx)[logP(xz)] KL(q(zx)∣∣P(z)))

发现了吗,最大化里面的第一项就期望,不就是从 q ( z ∣ x ) q(z|x) q(zx)采样z,再让 log ⁡ P ( x ∣ z ) \log P(x|z) logP(xz)概率最大。这不就是重构代价最小吗;而对于第二项,最大化 − K L -KL KL散度,就相当于最小化 K L KL KL散度。这和我们上面提到的两个优化目标是一样的。

3.2、细化目标函数

既然得到了目标函数,那么我们就对 log ⁡ P ( x ∣ z ) \log P(x|z) logP(xz)似然和KL散度都求出具体的表达。

先来看 K L 散度 \boxed{先来看KL散度} 先来看KL散度

q ( z j ∣ x ) ∼ N ( μ ϕ , σ ϕ 2 ) P ( z j ) ∼ N ( 0 , 1 ) q(z_j|x)\sim N(\mu_\phi,\sigma_\phi^2)\\P(z_j)\sim N(0,1) q(zjx)N(μϕ,σϕ2)P(zj)N(0,1)
q ( z ∣ x ) q(z|x) q(zx)需要逼近 P ( z ) P(z) P(z),而 P ( z ) ∼ N ( 0 , I ) P(z) \sim N(0,I) P(z)N(0,I)的多维高斯分布,并且各个维度之间相互独立,所以 q ( z ∣ x ) q(z|x) q(zx)也是如此设定,

那么最小化其KL散度,只需要对每一个维度求KL最小即可,单独看某一个维度,设某一个维度为 z j z_j zj,设 q ( z j ∣ x ) ∼ N ( μ ϕ , σ ϕ 2 ) q(z_j|x)\sim N(\mu_{\phi},\sigma^2_\phi) q(zjx)N(μϕ,σϕ2)(后续为了简便,也同样将 ϕ \phi ϕ隐去)
min ⁡ K L ( q ( z j ∣ x ) ∣ ∣ P ( z j ) ) = min ⁡ ∫ q ( z j ∣ x ) log ⁡ q ( z j ∣ x ) P ( z j ) d z j = min ⁡ ∫ q ( z j ∣ x ) log ⁡ N ( μ , σ 2 ) N ( 0 , 1 ) d z j = min ⁡ ∫ q ( z j ∣ x ) log ⁡ 1 2 π σ exp ⁡ { − ( z j − μ ) 2 2 σ 2 } 1 2 π exp ⁡ { − z j 2 2 } d z j = min ⁡ ∫ q ( z j ∣ x ) log ⁡ 1 σ exp ⁡ { − ( z j − μ ) 2 2 σ 2 } exp ⁡ { − z j 2 2 } d z j = min ⁡ ∫ q ( z j ∣ x ) ( log ⁡ 1 σ + log ⁡ exp ⁡ { − ( z j − μ ) 2 2 σ 2 } exp ⁡ { − z j 2 2 } ) d z j = min ⁡ ∫ q ( z j ∣ x ) ( log ⁡ 1 σ + log ⁡ exp ⁡ { − ( z j − μ ) 2 2 σ 2 + z j 2 2 } ) d z j = min ⁡ ∫ q ( z j ∣ x ) ( log ⁡ 1 σ − ( z j − μ ) 2 2 σ 2 + z j 2 2 ) d z j = min ⁡ ∫ q ( z j ∣ x ) 1 2 ( 2 log ⁡ 1 σ − ( z j − μ ) 2 σ 2 + z j 2 ) d z j = min ⁡ 1 2 ∫ q ( z j ∣ x ) ( z j 2 − log ⁡ σ 2 − ( z j − μ ) 2 σ 2 ) d z j \begin{aligned}&\min KL(q(z_j|x)||P(z_j))\\=&\min \int q(z_j|x) \log\frac{q(z_j|x)}{P(z_j)}dz_j\\=&\min \int q(z_j|x)\log \frac{N(\mu,\sigma^2)}{N(0,1)}dz_j\\=&\min \int q(z_j|x) \log \frac{\frac{1}{\sqrt{2\pi}\sigma}\exp\{-\frac{(z_j-\mu)^2}{2\sigma^2}\}}{\frac{1}{\sqrt{2\pi}}\exp \{-\frac{z_j^2}{2}\}}dz_j\\=&\min \int q(z_j|x) \log \frac{\frac{1}{\sigma}\exp\{-\frac{(z_j-\mu)^2}{2\sigma^2}\}}{\exp \{-\frac{z_j^2}{2}\}}dz_j\\=&\min \int q(z_j|x) \left(\log \frac{1}{\sigma}+\log\frac{\exp\{-\frac{(z_j-\mu)^2}{2\sigma^2}\}}{\exp \{-\frac{z_j^2}{2}\}}\right)dz_j\\=&\min \int q(z_j|x) \left(\log \frac{1}{\sigma}+\log\exp\{-\frac{(z_j-\mu)^2}{2\sigma^2}+\frac{z_j^2}{2}\}\right)dz_j\\=&\min \int q(z_j|x) \left(\log \frac{1}{\sigma}-\frac{(z_j-\mu)^2}{2\sigma^2}+\frac{z_j^2}{2}\right)dz_j\\=&\min \int q(z_j|x) \frac{1}{2}\left(2\log \frac{1}{\sigma}-\frac{(z_j-\mu)^2}{\sigma^2}+z_j^2\right)dz_j\\=&\min \frac{1}{2}\int q(z_j|x)\left(z_j^2-\log \sigma^2-\frac{(z_j-\mu)^2}{\sigma^2}\right)dz_j\end{aligned} =========minKL(q(zjx)∣∣P(zj))minq(zjx)logP(zj)q(zjx)dzjminq(zjx)logN(0,1)N(μ,σ2)dzjminq(zjx)log2π 1exp{2zj2}2π σ1exp{2σ2(zjμ)2}dzjminq(zjx)logexp{2zj2}σ1exp{2σ2(zjμ)2}dzjminq(zjx) logσ1+logexp{2zj2}exp{2σ2(zjμ)2} dzjminq(zjx)(logσ1+logexp{2σ2(zjμ)2+2zj2})dzjminq(zjx)(logσ12σ2(zjμ)2+2zj2)dzjminq(zjx)21(2logσ1σ2(zjμ)2+zj2)dzjmin21q(zjx)(zj2logσ2σ2(zjμ)2)dzj
可以分为三部分
min ⁡ K L ( q ( z j ∣ x ) ∣ ∣ P ( z j ) ) = min ⁡ 1 2 ( ∫ q ( z j ∣ x ) z j 2 d z j − ∫ q ( z j ∣ x ) log ⁡ σ 2 d z j − ∫ z q ( z j ∣ x ) ( z j − μ ) 2 σ 2 d z j ) \min KL(q(z_j|x)||P(z_j))=\min\frac{1}{2}\left( \int q(z_j|x)z_j^2 dz_j -\int q(z_j|x)\log \sigma^2 dz_j-\int_z q(z_j|x)\frac{(z_j-\mu)^2}{\sigma^2}dz_j\right) minKL(q(zjx)∣∣P(zj))=min21(q(zjx)zj2dzjq(zjx)logσ2dzjzq(zjx)σ2(zjμ)2dzj)

①: ∫ z q ( z j ∣ x ) z j 2 d z = E [ z j 2 ] = D ( z j ) + E [ z j ] 2 = σ 2 + μ 2 ②: ∫ z q ( z j ∣ x ) log ⁡ σ 2 d z j = log ⁡ σ 2 ∫ z q ( z j ∣ x ) d z j = log ⁡ σ 2 ③: ∫ z q ( z j ∣ x ) ( z j μ ) 2 σ 2 d z j = 1 σ 2 ∫ z q ( z j ∣ x ) ( z j μ ) 2 d z j = 1 σ 2 E [ ( z j − μ ) 2 ] = 1 \begin{align}①:&\int_z q(z_j|x)z_j^2 dz=\mathbb{E}[z_j^2]=D(z_j)+\mathbb{E}[z_j]^2=\sigma^2+\mu^2\tag{A}\\②:&\int_z q(z_j|x)\log \sigma^2dz_j=\log\sigma^2\int_zq(z_j|x)dz_j=\log \sigma^2\tag{B} \\③:&\int_zq(z_j|x)\frac{(z_j\mu)^2}{\sigma^2}dz_j=\frac{1}{\sigma^2}\int_z q(z_j|x)(z_j\mu)^2dz_j=\frac{1}{\sigma^2}\mathbb{E}[(z_j-\mu)^2]=1\tag{C}\end{align} zq(zjx)zj2dz=E[zj2]=D(zj)+E[zj]2=σ2+μ2zq(zjx)logσ2dzj=logσ2zq(zjx)dzj=logσ2zq(zjx)σ2(zjμ)2dzj=σ21zq(zjx)(zjμ)2dzj=σ21E[(zjμ)2]=1(A)(B)(C)
对于(式 A ),里面用到了方差的计算公式 D ( z ) = E ( z 2 ) − E ( z ) 2 \boxed{\mathbf{对于(式A),里面用到了方差的计算公式D(z)=E(z^2)-E(z)^2}} 对于(式A),里面用到了方差的计算公式D(z)=E(z2)E(z)2

对于(式 B ) , 是因为 q ( x j ∣ x ) 积分为 1 \boxed{\mathbf{对于(式B),是因为q(x_j|x)积分为1}} 对于(式B,是因为q(xj∣x)积分为1

对于(式 C ) \boxed{\mathbf{对于(式C)}} 对于(式C
1 σ 2 E [ ( z j − μ ) 2 ] = 1 σ 2 E [ z j 2 − 2 μ z j + μ 2 ] = 1 σ 2 ( E ( z j 2 ) − 2 μ E ( z j ) + μ 2 ) = 1 σ 2 ( σ 2 + μ 2 − 2 μ 2 + μ 2 ) = 1 \begin{aligned}&\frac{1}{\sigma^2}\mathbb{E}[(z_j-\mu)^2]\\\\=&\frac{1}{\sigma^2}\mathbb{E}[z_j^2-2\mu z_j +\mu^2]\\=&\frac{1}{\sigma^2}\left(\mathbb{E}(z_j^2)-2\mu\mathbb{E}(z_j)+\mu^2\right)\\=&\frac{1}{\sigma^2}\left(\sigma^2+\mu^2-2\mu^2+\mu^2\right)\\=&1\end{aligned} ====σ21E[(zjμ)2]σ21E[zj22μzj+μ2]σ21(E(zj2)2μE(zj)+μ2)σ21(σ2+μ22μ2+μ2)1
如果你熟悉高斯分布的高阶矩的话,式A和式C完全就是二阶原点矩和中心距,是直接可以的得出答案的。

所以对于所有维度的 K L 散度 , 有 ( 假设隐变量有 J 维 ) \boxed{\mathbf{所以对于所有维度的KL散度,有(假设隐变量有J维)}} 所以对于所有维度的KL散度,(假设隐变量有J)
min ⁡ 1 2 ∑ j = 1 J ( σ j 2 + μ j 2 − log ⁡ σ j 2 − 1 ) \min \frac{1}{2}\sum\limits_{j=1}^J(\sigma^2_j+\mu^2_j-\log \sigma^2_j -1 ) min21j=1J(σj2+μj2logσj21)

再来看 log ⁡ P ( x ∣ z ) 极大似然,即 max ⁡ E q ( z ∣ x ) [ log ⁡ P ( x ∣ z ) ] \boxed{\mathbf{再来看\log P(x|z)极大似然,即\max \mathbb{E}_{q(z|x)}[\log P(x|z)]}} 再来看logP(x∣z)极大似然,即maxEq(z∣x)[logP(x∣z)]

值得注意的是,我看很多文章中都说此处就直接采用均方差来计算。这种说法是不准确的,在论文中提到 P ( x ∣ z ) P(x|z) P(xz)是服从一个概率分布的,而不是无端的就计算其差值。它不像是GAN一样,对于其隐藏在内部的概率分布不作约束,VAE是仍然对 P ( x ∣ z ) P(x|z) P(xz)进行约束。

在这里插入图片描述

“ log ⁡ p θ ( x ( i ) ∣ z ( i , l ) ) 是伯努利或高斯 M L P ,这取决于我们建模的数据类型” \boxed{“\log p_θ (x^{(i)} |z^{(i,l)} )是伯努利或高斯MLP,这取决于我们建模的数据类型”} logpθ(x(i)z(i,l))是伯努利或高斯MLP,这取决于我们建模的数据类型

当然了,其实我们也可以不对其概率分布进行约束,归根究底,其让然是最小重构代价,那么我们的目标函数如果可以充分表达出“最小重构代价”,那么是什么又有何关系呢?

在论文中,其假设 P ( x ∣ z ) ∼ N ( μ , σ 2 I ) P(x|z) \sim N(\mu,\sigma^2 I) P(xz)N(μ,σ2I),其中 μ \mu μ σ 2 \sigma^2 σ2都是需要使用神经网络去逼近。

但是,一般地,我们假设 P ( x ∣ z ) ∼ ( f ( z ) , c I ) P(x|z) \sim (f(z),cI) P(xz)(f(z),cI),也就是其均值用神经网络去逼近,对于其协方差矩阵,我们设定为常数c和 I I I相乘,所以依然是各个维度之间相互独立。我们来看看它的极大似然估计得什么(假设采样n个样本)

max ⁡ E q ( z ∣ x ) [ log ⁡ P ( x ∣ z ) ] ≈ max ⁡ 1 n ∑ i = 1 n log ⁡ P ( x i ∣ z i ) = max ⁡ 1 n ∑ i = 1 n log ⁡ 1 2 π D / 2 ∣ c I ∣ 1 / 2 exp ⁡ { − 1 2 ( x i − f ( z i ) ) T ( c I ) − 1 ( x i − f ( z i ) ) } = max ⁡ 1 n ∑ i = 1 n log ⁡ 1 2 π D / 2 ∣ c I ∣ 1 / 2 − 1 2 ( x i − f ( z i ) ) T ( c I ) − 1 ( x i − f ( z i ) ) ∝ min ⁡ 1 n ∑ i = 1 n ( x i − f ( z i ) ) T ( x i − f ( z i ) ) = min ⁡ 1 n ∑ i = 1 n ∣ ∣ x i − f ( z i ) ∣ ∣ 2 \begin{aligned}\max \mathbb{E}_{q(z|x)}[\log P(x|z)]\approx&\max\frac{1}{n}\sum\limits_{i=1}^n\log P(x^i|z^i)\\=&\max\frac{1}{n}\sum\limits_{i=1}^n\log \frac{1}{{2\pi }^{D/2}|cI|^{1/2}}\exp\left\{-\frac{1}{2}(x^i-f(z^i))^T(cI)^{-1}(x^i-f(z^i))\right\}\\=&\max\frac{1}{n}\sum\limits_{i=1}^n\log \frac{1}{{2\pi }^{D/2}|cI|^{1/2}}-\frac{1}{2}(x^i-f(z^i))^T(cI)^{-1}(x^i-f(z^i))\\\propto &\min \frac{1}{n}\sum\limits_{i=1}^n(x^i-f(z^i))^T(x^i-f(z^i))\\=&\min \frac{1}{n}\sum\limits_{i=1}^n||x^i-f(z^i)||^2\end{aligned} maxEq(zx)[logP(xz)]===maxn1i=1nlogP(xizi)maxn1i=1nlog2πD/2cI1/21exp{21(xif(zi))T(cI)1(xif(zi))}maxn1i=1nlog2πD/2cI1/2121(xif(zi))T(cI)1(xif(zi))minn1i=1n(xif(zi))T(xif(zi))minn1i=1n∣∣xif(zi)2
可以看到,这就是一个均方差

综合得到最终目标函数表达式 \boxed{\mathbf{综合得到最终目标函数表达式}} 综合得到最终目标函数表达式
min ⁡ ( 1 2 ∑ j = 1 J ( σ j 2 + μ j 2 − log ⁡ σ j 2 − 1 ) + 1 n ∑ i = 1 n ∣ ∣ x i − f ( z i ) ∣ ∣ 2 ) \min \left(\frac{1}{2}\sum\limits_{j=1}^J(\sigma^2_j+\mu^2_j-\log \sigma^2_j -1 )+\frac{1}{n}\sum\limits_{i=1}^n||x^i-f(z^i)||^2\right) min(21j=1J(σj2+μj2logσj21)+n1i=1n∣∣xif(zi)2)

3.3、重参数化技巧

有了目标函数,理论上我们直接梯度下降就可以了。然而,别忘了,我们是从 q ( z ∣ x ) q(z|x) q(zx)中采样出z来。可是我们却是用的神经网络去计算的均值和方差,得到的高斯分布再去采样,这种情况是不可导的。中间都已经出现了一个断层了。神经网络是一层套一层的计算。而采样计算了一层之后,从这一层中去采样新的值,再计算下一层。因此,采样本身是不可导的。

所以要引入重参数化技巧,假定 q ( z ∣ x ) ∼ N ( μ , σ 2 ) q(z|x) \sim N(\mu,\sigma^2) q(zx)N(μ,σ2)。那么可以构造一个概率分布 p ( ϵ ) ∼ N ( 0 , 1 ) p(\epsilon) \sim N(0,1) p(ϵ)N(0,1)。有
z = μ + ϵ σ z=\mu +\epsilon\sigma z=μ+ϵσ
我们从 P ( ϵ ) P(\epsilon) P(ϵ)采样,然后利用上述公式,就相当于得到了从 q ( z ∣ x ) q(z|x) q(zx)采样的采样值。

证明 \boxed{\mathbf{证明}} 证明
E ( z ) = E ( μ ) + E ( ϵ ) σ = μ V a r ( z ) = E [ ( z − μ ) 2 ] = E [ ( ϵ σ ) 2 ] = σ 2 \begin{aligned}\mathbb{E}(z)=&\mathbb{E}(\mu)+\mathbb{E}(\epsilon)\sigma=\mu\\Var(z)=&\mathbb{E}[(z-\mu)^2]=\mathbb{E}[(\epsilon\sigma)^2]=\sigma^2\end{aligned} E(z)=Var(z)=E(μ)+E(ϵ)σ=μE[(zμ)2]=E[(ϵσ)2]=σ2

4、代码实现

在这里插入图片描述

效果一般,不晓得论文里面用了什么手段,效果看起来比这个好。(这个结果甚至还是我加了一层隐藏层的)

import torch
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision.transforms import transforms
from  torch import nn
from tqdm import tqdm
import matplotlib.pyplot as plt
class VAE(nn.Module):
    def __init__(self,input_dim,hidden_dim,gaussian_dim):
        super().__init__()
        #编码器
        #隐藏层
        self.fc1=nn.Sequential(
            nn.Linear(in_features=input_dim,out_features=hidden_dim),
            nn.Tanh(),
            nn.Linear(in_features=hidden_dim, out_features=256),
            nn.Tanh(),
        )
        #μ和logσ^2
        self.mu=nn.Linear(in_features=256,out_features=gaussian_dim)
        self.log_sigma=nn.Linear(in_features=256,out_features=gaussian_dim)



        #解码(重构)
        self.fc2=nn.Sequential(
            nn.Linear(in_features=gaussian_dim,out_features=256),
            nn.Tanh(),
            nn.Linear(in_features=256, out_features=512),
            nn.Tanh(),
            nn.Linear(in_features=512,out_features=input_dim),
            nn.Sigmoid() #图片被转为为0,1的值了,故用此函数
        )
    def forward(self,x):
        #隐藏层
        h=self.fc1(x)

        #计算期望和log方差
        mu=self.mu(h)
        log_sigma=self.log_sigma(h)

        #重参数化
        h_sample=self.reparameterization(mu,log_sigma)

        #重构
        reconsitution=self.fc2(h_sample)

        return reconsitution,mu,log_sigma

    def reparameterization(self,mu,log_sigma):
        #重参数化
        sigma=torch.exp(log_sigma*0.5) #计算σ
        e=torch.randn_like(input=sigma,device=device)

        result=mu+e*sigma #依据重参数化技巧可得

        return result
    def predict(self,new_x): #预测
        reconsitution=self.fc2(new_x)

        return reconsitution
def train():

    transformer = transforms.Compose([
        transforms.ToTensor(),
    ]) #归一化
    data = MNIST("./data", transform=transformer,download=True) #载入数据

    dataloader = DataLoader(data, batch_size=128, shuffle=True) #写入加载器

    model = VAE(784, 512, 20).to(device) #初始化模型

    optimer = torch.optim.Adam(model.parameters(), lr=1e-3) #初始化优化器

    loss_fn = nn.MSELoss(reduction="sum") #均方差损失
    epochs = 100 #训练100轮

    for epoch in torch.arange(epochs):
        all_loss = 0
        dataloader_len = len(dataloader.dataset)

        for data in tqdm(dataloader, desc="第{}轮梯度下降".format(epoch)):
            sample, label = data
            sample = sample.to(device)
            sample = sample.reshape(-1, 784) #重塑
            result, mu, log_sigma = model(sample) #预测

            loss_likelihood = loss_fn(sample, result) #计算似然损失

            #计算KL损失
            loss_KL = torch.pow(mu, 2) + torch.exp(log_sigma) - log_sigma - 1

            #总损失
            loss = loss_likelihood + 0.5 * torch.sum(loss_KL)

            #梯度归0并反向传播和更新
            optimer.zero_grad()

            loss.backward()

            optimer.step()
            with torch.no_grad():
                all_loss += loss.item()
        print("函数损失为:{}".format(all_loss / dataloader_len))
        torch.save(model, "./model/VAE.pth")
if __name__ == '__main__':
    #是否有闲置GPU
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    #训练
    train()

    #载入模型,预测
    model=torch.load("./model/VAE (1).pth",map_location="cpu")
    #预测20个样本
    x=torch.randn(size=(20,20))
    result=model.predict(x).detach().numpy()
    result=result.reshape(-1,28,28)
    #绘图
    for i in range(20):
        plt.subplot(4,5,i+1)
        plt.imshow(result[i])
        plt.gray()
    plt.show()

5、结束

以上,就是VAE的原理和推导过程了。能力有限,过程并不严谨,如有问题,还望指出。阿里嘎多

在这里插入图片描述

  • 15
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值