深度学习算法(第27期)----栈式自编码器

深度学习算法(第26期)----深度网络中的自编码器 今天我们更进一步一起学一下栈式自编码器。

栈式自编码器

跟之前我们学过的其他神经网络一样,自编码器也可以有多个隐藏层。这种有多个隐藏层的自编码器被称为栈式自编码器(类似内存中的堆栈),也称为深度自编码器。增加更多的层,有助于自编码器学到更为复杂的编码,然而,需要注意的是不能够让自编码器太过强大,假设一个自编码器太过强大,而学到了将每一个输入映射为一个任意值,而解码的时候反向映射。显然,这样的自编码器能够很完美的重构训练数据,但是并没有学到任何有效的表现数据的方法,泛化能力必然一塌糊涂。

栈式自编码器一般是一个关于中心隐藏层(编码层)对称的结构,或者说像一个三明治。例如对于我们很熟悉的MNIST数据集的一个自编码器应该是什么样子的呢?如下图:

在这个例子中,有784个输入,接着是一个300个神经元的隐藏层,然后中心隐藏层(编码层)是由150个神经元组成,再接着就又是300个神经元,最终输出为784个神经元(跟输入一致)。

tensorflow 实现

我们可以用常规的深度MLP来实现一个栈式自编码器,如之前所学的一样: 深度学习三人行(第3期)----TensorFlow从DNN入手 如下代码创建了一个MNIST的栈式自编码器,其中用He初始化,ELU激活函数等。

n_inputs = 28 * 28 # for MNIST
n_hidden1 = 300
n_hidden2 = 150 # codings
n_hidden3 = n_hidden1
n_outputs = n_inputs

learning_rate = 0.01
l2_reg = 0.001

X = tf.placeholder(tf.float32, shape=[None, n_inputs])
with tf.contrib.framework.arg_scope(
        [fully_connected],
        activation_fn=tf.nn.elu,
        weights_initializer=tf.contrib.layers.variance_scaling_initializer(),
        weights_regularizer=tf.contrib.layers.l2_regularizer(l2_reg)):
    hidden1 = fully_connected(X, n_hidden1)
    hidden2 = fully_connected(hidden1, n_hidden2) # codings
    hidden3 = fully_connected(hidden2, n_hidden3)
    outputs = fully_connected(hidden3, n_outputs, activation_fn=None)

reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE

reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
loss = tf.add_n([reconstruction_loss] + reg_losses)

optimizer = tf.train.AdamOptimizer(learning_rate)
training_op = optimizer.minimize(loss)

init = tf.global_variables_initializer()

我们可以按照一般流程训练模型,注意这里并没有用到标签。

n_epochs = 5
batch_size = 150

with tf.Session() as sess:
    init.run()
    for epoch in range(n_epochs):
        n_batches = mnist.train.num_examples // batch_size
        for iteration in range(n_batches):
            X_batch, y_batch = mnist.train.next_batch(batch_size)
            sess.run(training_op, feed_dict={X: X_batch})

权重关联

像我们刚才创建的一样,当一个自编码器是完全对称的时候,为了加速训练和放置过拟合,一个通常的做法就是将编码器的权重和解码器的权重捆绑在一起共用,这样权重的数量就能减半。其实在tensorflow中,用fully_connected()函数实现这个权重捆绑还是有一些麻烦的,一般手动定义这些层还是比较简单的,虽然下面代码看起来有些冗余:

activation = tf.nn.elu
regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
initializer = tf.contrib.layers.variance_scaling_initializer()

X = tf.placeholder(tf.float32, shape=[None, n_inputs])

weights1_init = initializer([n_inputs, n_hidden1])
weights2_init = initializer([n_hidden1, n_hidden2])

weights1 = tf.Variable(weights1_init, dtype=tf.float32, name="weights1")
weights2 = tf.Variable(weights2_init, dtype=tf.float32, name="weights2")
weights3 = tf.transpose(weights2, name="weights3") # tied weights
weights4 = tf.transpose(weights1, name="weights4") # tied weights

biases1 = tf.Variable(tf.zeros(n_hidden1), name="biases1")
biases2 = tf.Variable(tf.zeros(n_hidden2), name="biases2")
biases3 = tf.Variable(tf.zeros(n_hidden3), name="biases3")
biases4 = tf.Variable(tf.zeros(n_outputs), name="biases4")

hidden1 = activation(tf.matmul(X, weights1) + biases1)
hidden2 = activation(tf.matmul(hidden1, weights2) + biases2)
hidden3 = activation(tf.matmul(hidden2, weights3) + biases3)
outputs = tf.matmul(hidden3, weights4) + biases4

reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))
reg_loss = regularizer(weights1) + regularizer(weights2)
loss = reconstruction_loss + reg_loss

optimizer = tf.train.AdamOptimizer(learning_rate)
training_op = optimizer.minimize(loss)

init = tf.global_variables_initializer()

这段代码是比较直接的实现了权重捆绑,但是有几点还是需要注意的:

  • 权重3和权重4并不是新的变量,而是权重2和权重1的转置。
  • 因为不是新的变量,所以,没办法对他们进行正则化,所以这里只对权重1和2进行正则化。
  • 偏置没有捆绑,也不需要正则化。

好了,至此,今天我们简单学习了自编码器中栈式自编码器的相关知识,希望有些收获,下期我们将更深一步的学习如何训练一个深度自编码器的相关知识,欢迎留言或进社区共同交流,喜欢的话,就点个“在看”吧,您也可以置顶公众号,第一时间接收最新内容。


智能算法,与您携手,沉淀自己,引领AI!

本文分享自微信公众号 - 智能算法(AI_Algorithm)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JAVAandPython君

深度学习(五)--常量与变量

在这里的 init 是初始化所有的变量,它自己本身也是一个节点,所以我们也要通过session的run()方法对它进行初始化,如果我们注释掉sess.run(i...

8840
来自专栏磐创AI技术团队的专栏

TFLearn:为TensorFlow提供更高级别的API 的深度学习库

TFlearn是一个基于Tensorflow构建的模块化透明深度学习库。它旨在为TensorFlow提供更高级别的API,以促进和加速实验,同时保持完全透明并与...

11820
来自专栏机器之心

TensorFlow 1.x最后一更、Android 10最新特性,这是谷歌开发者日

2019 谷歌开发者大会于 9 月 10 日和 11 日在上海举办,大会将分享众多开发经验与工具。在第一天的 KeyNote 中,谷歌发布了很多开发工具新特性,...

14920
来自专栏ATYUN订阅号

谷歌开源差异化隐私库

谷歌前两日发布了其核心产品(如谷歌Maps)中使用的差别隐私库的开源版本,任何组织或开发人员现在都可以在GitHub上查看隐私库,此举给业内造成了不小的影响。

11720
来自专栏AI研习社

谷歌全面开源 MLIR 及生态联盟,全球 95% 的加速器硬件都在使用

近日谷歌宣布,向非盈利性 LLVM 基金会提供今年 4 月开源的 Multi-Level Intermediate Representation(MLIR)架构...

17120
来自专栏JAVAandPython君

深度学习(二)--tensor张量

关于“tensorflow”这个专栏,我打算一直更新下去,文章基本都是随着我的进度来的,我也是查找了一些资料并根据自己的一些理解写的,可能内容偶尔会...

8120
来自专栏大龄程序员的人工智能之路

TensorFlow助力微信小程序,来自谷歌开发者大会上的商用案例

前段时间一直在研究微信小程序中的 TensorFlow.js 开发,并开发了若干示例小程序,详情请查看之前的文章:

21370
来自专栏AI科技大本营的专栏

TensorFlow全家桶的落地开花 | 2019 Google开发者日

Android 10 原生支持 5G,Flutter 1.9、Dart 2.5 正式发布

18640
来自专栏JAVAandPython君

深度学习(1)---Tensorflow基础概念

- TensorFlow™ 是一个开放源代码软件库,用于进行高性能数值计算• 借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、GPU、TPU)...

7720
来自专栏汇智网教程

Tensorflow边框检测入门【Bouding Box Regression 】

要学习目标检测算法吗?任何一个ML学习者都希望能够给图像中的目标物体圈个漂亮的框框,在这篇文章中我们将学习目标检测中的一个基本概念:边框回归/Bounding ...

10120

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励