AE,VAE,dVAE和VQVAE
Auto-Encoder
自编码器是一种 无监督 的数据压缩、降维和特征表示方法,一般使用深度神经网络构成;其通过一个编码器和解码器 重构输入,通常使用 MAE 作为损失函数,编码器学习输入的低维表示,解码器用于重构中间表示为输入。
自编码器也有一些变体,如降噪自编码器,为输入添加一定的噪声,以增强网络的泛化性。
Variational Auto-Encoder
假设我们有一些样本 ,其总体使用 来表示,如果我们能根据样本得到总体的分布表示,直接从中采样 便可以得到所有的样本了;但是我们很难衡量训练所得到的是否真的是 这个分布,因为我们只有一些样本,KL 散度没法算出分布的相似度;GAN 的思路很直接粗犷:既然没有合适的度量,那我干脆把这个度量也用神经网络训练出来吧,因此产生了 WGAN ;而 VAE 将这个分布进行了变换:
这里的 也是一个分布,通常假设标准正态分布,我们先从 中采样一个 ,再根据这个样本计算出一个 ,从而实现曲线救国;然而这里的 并不一定对应与 ,因此实际上在 VAE 中假设 这个后验分布是正态分布,对于任意真实样本 ,假设其后验分布 是正态分布,并且这个后验分布是独立的,专属于 ,我们需要将采样的 还原为 。
为了估算后验分布,可以通过正态分布的均值和方差 ,可以通过 两个 神经网络(最简单的做法就是在解码器之后跟两个 )来估算 和 ,这里是因为方差总是正的。
通过编码器来估算 每个 后验分布的均值和方差,解码器从中采样 ,用于生成 ,训练时再最小化距离 。
事实上,VAE 是为每个样本构造专属的正态分布,然后采样来重构。
重参数化技巧
对于得到的均值和方差,我们需要进行采样——即随机生成服从所得到的均值和方差的向量,然而该采样是不可导的,因此使用了重参数化技巧——在乘以方差加上均值:
这里表示 服从标准正态分布从 中采样一个 ,相当于从 中采样一个 ,然后让 。
这里要把 也考虑进去,这样才算概率,否则就是 概率密度函数。
代码表示为:
def reparameterize(self, mu: Tensor, logvar: Tensor) -> Tensor:
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return eps * std + mu
这样便能够梯度下降了。
分布标准化
重构过程受到噪声影响,因为重构输入通过编码器计算得出,噪声强度与其方差有关,因此为了降低重构损失,网络会偏向将方差降为 ,因此 就退化成了 。
从上一小节的重参数化方法中可以看到 ,其中需要从标准正态分布进行采样,可以认为是 噪声,而标准差可以控制噪声的强度。
要求所有的 都向标准正态分布看齐,这样
也是标准正态分布,便可以放心的从 中采样了,当然这里只是近似成立。
原论文直接采用了计算一般正态分布和标准正态分布直接的散度作为监督,计算公式为:
该式前面的部分是监督均值 ,后半部分监督方差,由于均值和方差是一个多元独立向量,因此使用下标表示其中的一个分量。
VAE 的本质
本质上就是在我们常规的自编码器的基础上,对 的结果(在 中对应着计算均值的网络)加上了“高斯噪声”,使得结果 能够对噪声有鲁棒性;而那个额外的 (目的是让均值为 ,方差为 ),事实上就是相当于对 的一个正则项,希望 出来的东西均有零均值。
该损失相当于引入了高斯噪声,是一种对抗的过程
为什么使用正态分布
正态分布拥有良好的非零性,否则 散度会无穷大;写代码时可以防止这种除零错误,但依然避免不了 占比很大,因此模型会迅速降低 ,也就是后验分布 迅速趋于先验分布 ,而噪声和重构无法起到对抗作用。
变分
的变分下界,是直接基于 散度就得到的。所以直接承认了 散度的话, 就没有变分的什么事了。叫变分的原因是因为它的推导过程用到了 散度及其性质。
Conditional VAE
条件 VAE 是想用额外的监督信息引导生成,朴素 VAE 中需要让均值接近 ,而条件 VAE 可以是接近标签 (也可以是其他),只需要将 KL Loss 修改为: