TensorFlow 网络优化步骤与一般方法

深度学习中,网络的优化是训练过程中很重要的一部分,现在有很多的优化策略,而他们的核心的内容都是梯度下降。 理论的部分大家可以参考: 理解梯度下降在机器学习模型优化中的应用,其中介绍了批量梯度下降,随机梯度下降与小批量梯度下降的基本概念。 An overview of gradient descent optimization algorithms,其中介绍了各种改进的优化方法,包括动量法,adagrad等等

而在本文的内容中重要讨论的是TensorFlow中实现这些优化方法的一般步骤,先贴上代码(该代码是整个可以运行dome的优化部分,也就是说单独无法运行)

 # 构建训练操作
  def _build_train_op(self):
    # 学习率/步长
    self.lrn_rate = tf.constant(self.hps.lrn_rate, tf.float32)
    tf.summary.scalar('learning_rate', self.lrn_rate)

    # 计算训练参数的梯度
    trainable_variables = tf.trainable_variables()
    grads = tf.gradients(self.cost, trainable_variables)

    # 设置优化方法 其实是在实例化对象 optimizer
    if self.hps.optimizer == 'sgd':
      optimizer = tf.train.GradientDescentOptimizer(self.lrn_rate)
    elif self.hps.optimizer == 'mom':
      optimizer = tf.train.MomentumOptimizer(self.lrn_rate, 0.9)

    # 梯度优化操作  optimizer对象中的方法 
    apply_op = optimizer.apply_gradients(
                        zip(grads, trainable_variables),
                        global_step=self.global_step, 
                        name='train_step')

    # 合并BN更新操作
    train_ops = [apply_op] + self._extra_train_ops
    # 建立优化操作组
    self.train_op = tf.group(*train_ops)

1.确定学习率

self.lrn_rate = tf.constant(self.hps.lrn_rate, tf.float32)

学习率时由self.hps.lrn_rate这个东西来的,下面会说具体是什么。

2.计算梯度 使用梯度下降的优化算法当然要计算梯度,TensorFlow中提供了tf.gradients函数:

grads = tf.gradients(self.cost, trainable_variables)

self.cost为定义好的loss function,trainable_variables为所有需要训练的变量,其中trainable_variables是直接用tf.trainable_variables()参数得到的(在这里可以看下计算梯度的公式,不就是loss对w求偏导么,也就不难理解为啥是这两个参数)

3.设置优化策略 这个过程其实是实例化一个对象出来,叫做optimizer,上面的代码选择使用随机梯度下降还是动量。比如:

optimizer = tf.train.MomentumOptimizer(self.lrn_rate, 0.9)

tf.train.MomentumOptimizer是一个类,提供了动量优化方法,对象的初始化参数有学习率和一个超参数(这个参数要看公式才知道是什么意思)

4.执行优化(定义优化的op) 在上面的三步中确定了优化需要的所有东西:步长,梯度,方法,那么就能确定最后的优化操作了,直接使用实例化出来的那么对象—optimizer,下面提供的方法apply_gradients,最后返回值是一个op。其中需要的注意的地方是第一个参数:zip(grads, trainable_variables),这个东西的目的是为了把梯度和参数关联起来,因为我们知道,在梯度下降过程中,要训练的变量个数决定了loss surcafe的维度,那么当然每一个维度上都会有一个自己的梯度。

5.加入BN 按道理讲,这一部分和梯度下降没有关系,他只是把批归一化的操作加入到了梯度优化上,组合成新的操作 — train_ops。最后就是利用tf.group函数把多个操作合并为一个。并让一个Session去run这个op就好了。

从上面的代码中,我们知道了梯度优化过程中的一般步骤以及需要的变量是如何得到的,但是学习速率没有涉及,下面的代码说明了学习率如何确定:

  class _LearningRateSetterHook(tf.train.SessionRunHook):

    def begin(self):
      #初始学习率
      self._lrn_rate = 0.1

    def before_run(self, run_context):
      return tf.train.SessionRunArgs(
                      # 获取全局Step
                      model.global_step,
                      # 设置学习率
                      feed_dict={model.lrn_rate: self._lrn_rate})  

    def after_run(self, run_context, run_values):
      # 动态更新学习率
      train_step = run_values.results
      if train_step < 40000:
        self._lrn_rate = 0.1
      elif train_step < 60000:
        self._lrn_rate = 0.01
      elif train_step < 80000:
        self._lrn_rate = 0.001
      else:
        self._lrn_rate = 0.0001
  # 建立可监控的Session
  with tf.train.MonitoredTrainingSession(
      checkpoint_dir='temp',
      hooks=[logging_hook, _LearningRateSetterHook()],
      chief_only_hooks=[summary_hook],
      # 禁用默认的SummarySaverHook,save_summaries_steps设置为0
      save_summaries_steps=0,
      #设备的软分配
      config=tf.ConfigProto(allow_soft_placement=True)) as mon_sess:
    while not mon_sess.should_stop():
      # 执行优化训练操作
      mon_sess.run(model.train_op)

可以看到,专门建立了_LearningRateSetterHook类来做学习率的更新,该代码没有涉及到自适应学习率的方法,而是根据执行步数逐步降低学习率。 在后面定义了可监控的Session — tf.train.MonitoredTrainingSession,并将学习率更新的类加入到Session中。 最后如果没有达到终止条件,则一直执行mon_sess.run(model.train_op),而model.train_op就是第一个代码中最后定的:self.train_op = tf.group(*train_ops),即优化方法和批归一化(这里不说批归一化)。 hook这个词在代码中常常看到,首先它是个变量的名,用什么词都可以,之所以大家都选择hook是因为变量涉及的部分就像钩子一样挂在graph上。

以上就是一个模型训练中的优化部分的代码,使用了动量的方法,手动设置学习率。除此之外,TensorFlow还提供了很多其他的优化方法,比如: adagrad:在TensorFlow中的 tf.train.AdagradOptimizer类下封装。 Adam:在TensorFlow中的 tf.train.AdamOptimizer类下封装。 具体可以参考TensorFlow Training

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏desperate633

小白也能看懂的BP反向传播算法之Towards-Backpropagation

想要理解backpropagation反向传播算法,就必须先理解微分!本文会以一个简单的神经元的例子来讲解backpropagation反向传播算法中的微分的概...

741
来自专栏贾志刚-OpenCV学堂

使用tensorflow layers相关API快速构建卷积神经网络

tf.layers包中包含了CNN卷积神经网络的大多数层类型,当前封装支持的层包括:

773
来自专栏技术碎碎念

动态规划之最长公共子序列(LCS)

最长公共子序列(LCS,Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条...

2758
来自专栏有趣的Python

3- OpenCV+TensorFlow 入门人工智能图像处理-TensorFlow入门

tensorflow基础入门 思考一个问题: 如何刚好学习TensorFlow 类比为一门开发语言,学会语法,api的调用, 原理性掌握。 语言的要素: 基础...

7068
来自专栏北京马哥教育

高阶实战 | 如何用Python检测伪造的视频

译者注:本文以一段自打24小时耳光的视频为例子,介绍了如何利用均值哈希算法来检查重复视频帧。以下是译文。 有人在网上上传了一段视频,他打了自己24个小时的耳光。...

3105
来自专栏Jack-Cui

Caffe学习笔记(三):cifar10_quick_train_test.prototxt配置文件分析

运行平台: Ubuntu14.04     在上篇笔记中,已经记录了如何进行图片数据格式的转换和生成txt列表清单文件。本篇笔记主要记录如何计算图片数据的均值和...

2708
来自专栏机器之心

教程 | 在Python和TensorFlow上构建Word2Vec词嵌入模型

选自adventuresinmachinelearning 机器之心编译 参与:李诗萌、刘晓坤 本文详细介绍了 word2vector 模型的模型架构,以及 T...

4017
来自专栏null的专栏

利用Theano理解深度学习——Logistic Regression

一、Logistic Regression 1、LR模型 image.png 2、损失函数 image.png 3、随机梯度下降法 为了求解LR模型中的参数,在...

33510
来自专栏Small Code

梯度下降优化算法概述

原文作者简介:Sebastian Ruder 是我非常喜欢的一个博客作者,是 NLP 方向的博士生,目前供职于一家做 NLP 相关服务的爱尔兰公司 AYLIE...

6527
来自专栏有趣的Python

TensorFlow应用实战-8-训练神经网络

2313

扫码关注云+社区