Abstract:Deep Learning是一个很大的领域,其中GAN是Deep Learning的明星,希望大家可以通过本文来简单的了解一下GAN这个模型以及这个模型的一些运用。本文介绍关于GAN的一些知识以及GAN的思想如何转移到ALI中,以及通过Google的Deep Learning框架TensorFlow,通过MNIST数据来实现ALI模型。所涉及到Tensorflow的一些很简单的一些解说,包括tf.Variable()和tf.placeholder()的一些用法以及区别,同时给出一小段代码案例。虽然提到了最简单的两个Tensorflow,tf.Variable()和tf.placeholder(),但是在本文中,不深入解释更多的关于TensorFlow的运用以及神经网络是如何搭建的。最后,我们将结果组合成模型。
使用Tensorflow建立ALI模型
背景
由于这次做项目的时候用到ALI这个Model,朋友希望自己能够为ALI和GAN来写一点自己的想法,故作此文。
生成模型已经成为建复杂高维数据集模型的常用的框架,面对复杂性时如同降维二向箔打击。
什么是ALI模型?
ALI(adversarially learned inference),中文直译过来呢,就是对抗学习推理了吧?
在这里简单的给大家介绍一下ALI模型。既然有一个Adversarial在里面,那想必就和GAN有一点关系了。而GAN(Generative Adversarial Networks)即“生成对抗网络”就是Deep Learning入门神书的作者Ian Goodfellow的神作。
GAN的idea就是同时训练两个模型,一个生成模型,一个Discriminative Model。我们把生成模型简写成G,Discriminative Model简称为D。而实现的方法,是让两个网络相互竞争。
生成模型是用来获取数据的分布情况的,而D则是用来估计来自训练数据的概率的。生成模型的训练过程就是想办法把D的错误概率给最大化。在任意函数G和D的空间中,存在唯一的解决方案,G恢复训练数据分布,D等于1/2。在G和D由多层感知器定义的情况下,整个系统可以用BP来进行训练。
在Training或Generating样本的期间,不需要任何马尔科夫链或展开的近似推理网络。,也就是活生生的把推理给绕过去了。当然还有Autoregressive Approaches(自回归方法)放弃潜在的表征,而是直接对输入变量之间的关系进行建模。或多或少的砍掉或者放弃掉一些东西。
自回归模型可以生成相当出色的样本,但是牺牲掉了速度。同时其要求学习之前数据的抽象表达。而基于GAN的方法代表了一个很好的妥协:他们学习一个生成模型,生成比最佳VAE技术更高质量的样本,而不牺牲采样速度,并且还利用潜在代表在生成过程中。然而,GAN缺乏有效的推理机制,使得GANs无法在抽象层面推理数据。因此大牛们在研究如何优雅的将GANs其他的方法进行结合,出杂交种,其实本质意义上就是在两个短板中互相妥协罢了。
ALI是个通过Generation Network和Inference Network。 两个Model来对怼。也就是将Inference Machine(或encoder)和深度定向G Model(decoder)投入到类似GAN的对抗框架中学习。
训练一个鉴别器,以便将来自解码器的联合样本的数据和相应的潜在变量的联合样本与编码器(或近似后验)区分开,而编码器和解码器被一起训练以愚弄鉴别器。我们不仅要求鉴别器区分合成样本与实际数据,而且要求它区分数据空间和潜在变量之间的两个联合分布。生成网络将样本从随机潜在变量映射到数据空间,而推理网络将数据空间中的训练示例映射到潜在变量的空间。
ALI概念图
我们可以针对GAN得出以下构想:
两个一个生成器,一个判别器共两个神经网络重复博弈。
今天用Tensorflow实现一下,同时解释一些Tensorflow的Concept
在这里,我们设置好我们的参数。
导入大名鼎鼎的MNIST数据
一个简单的科普
很多人其实经常就是Tensorflow的第一步就愣住了,卧槽???这是什么玩意???为了让大家不至于——“卧槽这是什么玩意?”简单的给大家说一下tf.placeholder:
其实大家看模型的时候(包括看Keras或者TensorLayer),其实经常可以看到两个很经典东西:
tf.Variable()
tf.placeholder()
这两个有什么区别呢?
为了训练我们的example,我们首先要立个placeholder。tf.placeholder是用来feed我们需要训练的example的,同时tf.placeholder是必须用feed_dict来fed!!!
给大家举个例子:
在这里呢,sess.run(y_example)是会被弄死的,因为你只能用feed_dict来fed我们的tf.placeholder,但是我们对比一下tf.Variable的话,tf.Variable是通过run()调用来维护状态的,也就是说,在之前的我们的sess.run(y_example)是可以受用于tf.Variable的。
通过构造tf.Variable来向图中添加变量。同时tf.Variable()的构造函数需要给定任何类型和形状的Tensor变量的初始值。初始值定义变量的类型和形状,其变量的type和shape是固定的。因此,在这里我们主要使用tf.placeholder来feed我们需要训练的example的。
OK,现在进入正题
先定义几个简单的小函数,包括一些必要的log和sample的函数以及后期用到的导出结果的可视化函数。
由于这一环节没有任何的难点,不做多余阐述:
在这里解释一下Q、P、D三个函数:
Q函数,将
现在我们通过tf.Session()来跑模型。最后,说一下这个很经常出现Session()。Tensorflow以Graph的计算而得名,而Session()封装了执行Operation对象的环境。通过Session可以执行图的计算。与Session相近的有tf.InteractiveSession()
tf.InteractiveSession()将自己安装为构建中的默认Session。而简单直接的方法也有这般:
常规会话会在with语句中创建时将其自身作为默认会话。一般我们在代码中的用法是这样的,我也比较常用Session()这个方法就是了:
总结一下一般的启动逻辑:
因此,tensorflow就将底层给配置好之后,我们在tensorflow这个大环境里愉快的奔跑。而难点就在于Variable的各种的设置和run的操作方法。初期,Variable被大量的套路给设定好,我们可以通过别人的轮子,来配适。
但是Deep Learning的从业者的核心价值应该在于能够自己的将自己想做的数据导入自己的模型,而不是简单的调参或者利用别人的轮子滚来滚去。各种算法和一些主流的实现就像加减乘除一般了然于胸,并且有自己做轮子的能力。
将模型训练十万次(如果有想法的,请换一台支持GPU的电脑,要不然可能会等很久。),我们将1000Iteration为一个单位,print一次:
由于导出大量的图片,我在这里就给大家看一下对比图,
最早的图:
不久之后:
本文由ALI Paper, arxiv依照Tensorflow重现。ALI的概念非本人提出,本人根据自己对ALI的理解通过Tensorflow进行实现,并且运行于Jupyter中。所有代码在Windows10,Python3.5,TensorflowGPU版(1.1.0rc2)完美运行。限于本人水平,可能有出现一定的错误,如有失误,欢迎交流。同时,由于本人学习Deep Learning的时候直接接触英文材料,故一些专有名词的翻译可能存在一些偏差。故一些专有名词直接保留为原单词,不做翻译。ALI的翻译没有参考过任何相关中文信息,由本人直接查阅在Arxiv上ALI的原文所得。如果有想来交流的小伙伴,欢迎私信。
Reference
1、ALI Paper, arxiv
2、GAN - Paper, NIPS
3、GAN - Goodfellow
4、生成模型与判别模型 zouxy09,csdn
5、Adversarial machine learning - ACM Digital Library
Running Graph
PyLive预告:TensorFlow入门完全详解
主讲人:chen_h
主讲人介绍:一直从事算法设计工作,曾独立设计聊天机器人。目前在上海纽约大学养小白鼠,并且写写博客。
主讲时间:5月19日(本周五)晚上21:00-22:00
参与方法:长按上方二维码扫描,或者点击阅读原文参与
Python 中 文 社 区
Python中文开发者的精神家园
合作、投稿请联系微信号:
pythonpost
声明:本文为作者原创作品,未经作者授权同意禁止转载。文章内容仅用于学习、研究,请勿用于非法用途,任何由此引发的法律纠纷自行负责。