来自我的个人网站: http://wangbch.com
变分自编码器(VAE) 参考自:http://blog.csdn.net/jackytintin/article/details/53641885 - 自编码器(autoencoder) 是一种非监督式学习的神经网络模型,采用原始数据作为输入和输出,含有一个数量小于输入输出的隐藏层。 - 从输入到隐藏层,这一段神经元数量下降,被称为”encoder”,也可以称为模式识别模型或判别模型;而从隐藏层到输出,这一段神经元数量上升,被称为”decoder”,也称生成模型。因而编码器在一定程度上是类似于GAN的 - 由于隐藏层数量小于输入,所以会对数据进行压缩,之后输出神经元数量大于隐藏层,压缩后的隐藏层相互组合重现原始输出 - 它尝试使用一个函数,将输入逼近输出,经过训练之后,撤去输入层,仅凭隐藏层也可以实现重现输出 - 这样隐藏层就需要做到提取主要成分的任务。这样的功能实现了隐藏层对于数据特征的提取,类似于主成分分析(PCA) - 稀疏自编码器(sparse autoencoder) 中的隐藏层数量会多于输入输出,此时需要抑制神经元。激活函数会使神经元处于抑制状态,这种抑制是稀疏性限制。比如采用sigmoid作为激活函数,就引入一个接近于0的稀疏性参数,这样会使得神经元的输出接近于0,从而在经过sigmoid函数之后会被抑制 - 需要注意的是,在编码器中使用的维度变换,可以为任意结构如MLP, CNN, RNN等 - 变分自编码器(VAE) 常常和GAN一同被提及,它们都属于生成模型,采用少量样本即可实现训练。步骤如下(结合后面的模型结构进行分析): 1. encoder或判别器将输入的n维数据转换为2个m维数据,其中第一个视作**m个高斯分布的均值,第二个视作**m个高斯分布方差的对数 2. 根据上述2个m维的数据,生成m维的服从高斯分布的随机数 3. 高斯分布先生成(None, m)的正态分布矩阵a,然后out = mean + exp(log_var/2) * a 输出encoder层的结果,注意是先生成N(0,1)再乘,而不是直接生成N(mean,log_var),这样只涉及线性操作 4. 模型结构如下:
layershapenotesinput(None, n)输入encoder(None, ?)判别器,可采用MLP,CNN,RNN等mean(None, m)均值,连接到hidden层log_var(None, m)方差对数,和mean层并列,直接连接到hidden层gaussian_out(None, m)生成高斯分布随机数decoder(None, ?)生成器output(None, n)恢复原始输出- 变分自编码器的意义以及和GAN的简单对比: 变分自编码器将decoder训练过后,根据正态分布的随机数,即可生成原始图像。而训练出的encoder,也可以作为数据降维,高维数据可视化的手段。 - 与GAN的差异在于,VAE采用原始数据输入和输出,目的是训练encoder和decoder的能力,使其重现输入 - 而GAN的discriminator(和encoder类似)并不是抽取高维特征,而是直接辨别真假结果,但是训练时也会逐渐习得特征。GAN的generator(和decoder)类似,是从随机数中生成数据用于判别,并逐渐训练使其接近原始输入 - VAE和GAN是非常相似的,GAN的G-D模型,实际上可以理解为VAE的decoder,而GAN的D模型,也可理解为VAE的encoder - VAE的输入经过encoder之后,会提取均值和对数方差,这就是对于不同特征的样本,生成了不同特征的随机数,之后用随机数做生成 ,就不依赖于特定输入输出,GAN也是采用随机数作为输入生成,但是GAN的随机数的特征是固定的,VAE的随机数的特征(均值和方差),会保留与输入的相关性。
在创建了完整的VAE模型并增添loss函数之后,将喂入手写数据集用于训练(注意这里只会喂入image,没有任何label,因为是非监督的);训练完成之后将输入和z_mean连在一起构成新的模型,喂入手写数据集进行可视化;之后将(latent_dim, )作为输入节点,最终生成的图片作为输出节点,构建decoder模型,喂入随机数生成图片 1. 构建完整训练模型:首先将输入节点,即原始数据x,和输出节点,即生成的结果,一起作为参数传递到4.的layer中,用以定义损失函数。之后创建训练模型,将原始输入和损失函数作为节点连接(此时损失函数中就包含了运算图的信息)vae = Model(x, y),之后创建优化函数,喂入手写数字数据集进行训练 2. 构建encoder模型:用encoder = Model(x, z_mean)连接输入和z_mean输出节点,之后喂入手写数据进行预测,作图 3. 构建generator模型:采用generator = Model(decoder_input, _x_decoder_mean)
这个例子将上个例子的全连接隐藏层变为了卷积和反卷积层,也是采用<layer>(<parameter>)(<last_layer>)的方式构建完整VAE网络以及encoder和decoder,具体完整VAE模型结构如下
layershapeinput(None, 28, 28, 1)conv2d(None, 28, 28, 1)conv2d(None, 14, 14, 64)conv2d(None, 14, 14, 64)conv2d(None, 14, 14, 64)flatten(None, 12544)dense_out(None, 128)以下z_mean和z_log_var是并列关系直接连接到dense_outz_mean(None, 2)z_log_var(None, 2)dense_decoder_in(None, 128)dense(None, 12544)reshape(None, 14, 14, 64)deconv2d(None, 14, 14, 64)deconv2d(None, 14, 14, 64)deconv2d(None, 29, 29, 64)conv2d(None, 28, 28, 1)自建层(None, 28, 28, 1)和(None, 28, 28, 1),求取loss训练完成之后,用于特征提取的encoder的完整结构如下:
layershapeinput(None, 28, 28, 1)conv2d(None, 28, 28, 1)conv2d(None, 14, 14, 64)conv2d(None, 14, 14, 64)conv2d(None, 14, 14, 64)flatten(None, 12544)dense(None, 128)dense(None, 2)decoder的结构如下:
layershapeinput(None, 2)dense(None, 128)dense(None, 12544)reshape(None, 14, 14, 64)deconv2d(None, 14, 14, 64)deconv2d(None, 14, 14, 64)deconv2d(None, 29, 29, 64)conv2d(None, 28, 28, 1)完整的VAE模型相当于将encoder和decoder连接在一起,并增加loss函数用于训练
不过有时候我也这样想,当我们睁开眼睛,辨别物体的时候,是不是就像机器那样开始读取图像数据集,并训练成标签。而当我们闭上眼睛的时候,是不是就看到了那些训练好的卷积网络的隐藏层权重图像?而当我们做梦,是不是就相当于将训练好的标签经过decoder又返回变成图形?这样一想,突然感觉深度学习非常值得深入讨论,如何结合我们的大脑,构建强大的机器? 也许有一天,如果我们构建了一个和大脑完全相同的神经网络结构,加上传感器,也许就能够完完全全创造一个人类的复制品,但是,人类研究这样久之后得到的东西,自然界又是怎样发展而来,达到如此小的功耗的呢?
