近年,随着有监督学习的低枝果实被采摘的所剩无几,无监督学习成为了研究热点。VAE(Variational Auto-Encoder,变分自编码器)[1,2] 和 GAN(Generative Adversarial Networks) 等模型,受到越来越多的关注。
笔者最近也在学习 VAE 的知识(从深度学习角度)。首先,作为工程师,我想要正确的实现 VAE 算法,以及了解 VAE 能够帮助我们解决什么实际问题;作为人工智能从业者,我同时希望在一定程度上了解背后的原理。
作为学习笔记,本文按照由简到繁的顺序,首先介绍 VAE 的具体算法实现;然后,再从直观上解释 VAE 的原理;最后,对 VAE 的数学原理进行回顾。我们会在适当的地方,对变分、自编码、无监督、生成模型等概念进行介绍。
我们会看到,同许多机器算法一样,VAE 背后的数学比较复杂,然而,工程实现上却非常简单。
1. 算法实现
这里介绍 VAE 的一个比较简单的实现,尽量与文章[1] Section 3 的实验设置保持一致。完整代码可以参见 repo。
1.1 输入:
数据集 X⊂Rn。
做为例子,可以设想 X 为 MNIST 数据集。因此,我们有六万张 0~9 的手写体 的灰度图(训练集), 大小为 28×28。进一步,将每个像素归一化到[0,1],则 X⊂[0,1]784 。
图1. MNIST demo (图片来源)
1.2 输出:
一个输入为 m 维,输出为 n 维的神经网络,不妨称之为 decoder [1](或称 generative model [2])(图1)。
图 2. decoder
在输入输出维度满足要求的前提下,decoder 以为 任何结构——MLP、CNN,RNN 或其他。 由于我们已经将输入数据规一化到 [0, 1] 区间,因此,我们令 decoder 的输出也在这个范围内。这可以通过在 decoder 的最后一层加上 sigmoid 激活实现 :
f(x)=11+e−x 作为例子,我们取 m = 100,decoder 的为最普遍的全连接网络(MLP)。基于 Keras Functional API 的定义如下:
1.
n, m =
784
,
2
2.
hidden_dim =
256
3.
batch_size =
100
4.
5.
## Encoder
6.
z = Input(batch_shape=(batch_size, m))
7.
h_decoded = Dense(hidden_dim, activation=
'tanh'
)(z)
8.
x_hat = Dense(n, activation=
'sigmoid'
)(h_decoded)