前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习算法(第28期)----如何高效的训练自编码器?

深度学习算法(第28期)----如何高效的训练自编码器?

作者头像
智能算法
发布2019-10-08 15:49:07
1.5K0
发布2019-10-08 15:49:07
举报
文章被收录于专栏:智能算法

上期我们一起学习了深度学习中的栈式自编码器的相关知识,

深度学习算法(第27期)----栈式自编码器 今天我们一起学一下如何高效的训练自编码器。

多图训练

上期我们学过在tensorflow中如何实现一个栈式自编码器,当然那样的自编码器训练起来注定是很慢的。那么通常的做法是一次训练一个浅浅的自编码器,然后堆到一起成为一个栈式自编码器,这在训练一些比较深的自编码器的时候十分有用,如下图:

在训练的第一阶段,第一个自编码器学习如何重构输入。在训练的第二个阶段,第二个自编码器学习如何重构第一个自编码器的隐藏层。最后,把这两个自编码器堆叠起来。我们可以很容易的用这种方法训练更深的自编码器。 为了实现这种多阶段的训练算法,最简单的方法就是对每一个阶段用不同的图。 训练完一个自编码器后,您只需通过它运行训练集并捕获隐藏层的输出,然后把这个输出作为下一个自编码器的训练集。一旦所有自编码器都以这种方式进行了训练,我们只需要简单的复制每个自编码器的权重和偏置,然后把它们堆叠起来形成深度自编码器。实现这种方法非常简单,所以我们不在这里详细说明。

单图训练

另一种方法是使用包含整个栈式自编码器的单个图,以及执行每个训练阶段的一些额外操作,如下图:

这里需要解释下:

  • 图中的中间列是完整的栈式自编码器。这部分可以在训练后使用。
  • 左边的一系列操作是训练的第一阶段,它创建一个绕过隐藏层2和3的输出层。该输出层与栈式自编码器的输出层共享相同的权重和偏置。该输出层上面是在使之尽可能接近输入的训练操作。因此,该阶段将训练隐藏层1和输出层(即第一自编码器)的权重和偏置。
  • 右边的训练操作相当于是训练的第二个阶段,它旨在使得隐藏层3尽可能的逼近隐藏层1。注意到,在训练第二个阶段的时候,我们必须冻结隐藏层1,这个阶段,我们将训练隐藏层2和隐藏层3的权重和偏置。
代码实现

代码如下:

代码语言:javascript
复制
[...] # Build the whole stacked autoencoder normally.
# In this example, the weights are not tied.

optimizer = tf.train.AdamOptimizer(learning_rate)

with tf.name_scope("phase1"):
    phase1_outputs = tf.matmul(hidden1, weights4) + biases4
    phase1_reconstruction_loss = tf.reduce_mean(tf.square(phase1_outputs - X))
    phase1_reg_loss = regularizer(weights1) + regularizer(weights4)
    phase1_loss = phase1_reconstruction_loss + phase1_reg_loss
    phase1_training_op = optimizer.minimize(phase1_loss)
    
with tf.name_scope("phase2"):
    phase2_reconstruction_loss = tf.reduce_mean(tf.square(hidden3 - hidden1))
    phase2_reg_loss = regularizer(weights2) + regularizer(weights3)
    phase2_loss = phase2_reconstruction_loss + phase2_reg_loss
    train_vars = [weights2, biases2, weights3, biases3]
    phase2_training_op = optimizer.minimize(phase2_loss, var_list=train_vars)

第一阶段相对比较简单:我们只创建一个跳过隐藏层2和3的输出层,然后构建训练操作以最小化输出和输入之间的距离(加上一些正则化)。

第二阶段只是增加了将隐藏层3和隐藏层1的输出之间的距离最小化的操作(包括一些正则化)。更重要的是,我们向minim()方法提供可训练变量的列表,确保省略权重1和偏差1;这有效地冻结了阶段2期间的隐藏层1。

在执行阶段,我们需要做的就是为阶段1做一些迭代进行训练操作,然后阶段2训练运行更多的迭代。

由于隐藏层1在阶段2期间被冻结,所以对于任何给定的训练实例其输出将总是相同的。 为了避免在每个时期重新计算隐藏层1的输出,我们可以在阶段1结束时用整个训练集计算它,然后直接在阶段2中输入隐藏层1的缓存输出。这在性能上可以有所提升。

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 智能算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多图训练
  • 单图训练
  • 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档