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 条评论
登录 后参与评论

相关文章

来自专栏Petrichor的专栏

matplotlib: 绘制平面图/表格

1804
来自专栏游遵文的专栏

机器学习优化算法:梯度下降(Gradient Descent)

优化算法 ( Optimization Algorithm ) 是机器学习理论中重要的组成部分,每年 ICML 会议中,总会有很多关于优化算法 Paper 以及...

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

干货 | Tensorflow设计简单分类网络实现猫狗图像分类训练与测试

第一层:32个feature map 5x5卷积、步长为2、最大值池化 局部相应归一化处理(LRN) 第二层:64个feature map 3x3卷积、步长为...

1974
来自专栏fangyangcoder

tensorflow笔记(四)之MNIST手写识别系列一

http://www.cnblogs.com/fydeblog/p/7436310.html

1131
来自专栏量子位

如何利用卷积自编码器对图片进行降噪?

作者:天雨粟 量子位 已获授权编辑发布 前言 这周工作太忙,本来想更把Attention tranlsation写出来,但一直抽不出时间,等后面有时间再来写,先...

3136
来自专栏数据小魔方

撬动地球需要一个杠杆,看懂图表需要一条参考线

今天要跟大家介绍一下图表中用作对比的参考线制作技巧 ▽ 参考线能够更明显的 突出真实值与目标值之间的差距 ? ? 今天要介绍两种参考线的制作思路 散点图法——...

2836
来自专栏小樱的经验随笔

51Nod 1080 两个数的平方和(数论,经典题)

1080 两个数的平方和 基准时间限制:1 秒 空间限制:131072 KB 分值: 5         难度:1级算法题 给出一个整数N,将N表示为2个整数...

3556
来自专栏WOLFRAM

如何使用DensityHistogram加入直方图元素

1732
来自专栏专知

【最新TensorFlow1.4.0教程02】利用Eager Execution 自定义操作和梯度 (可在 GPU 运行)

点击上方“专知”关注获取更多AI知识! 【导读】主题链路知识是我们专知的核心功能之一,为用户提供AI领域系统性的知识学习服务,一站式学习人工智能的知识,包含人工...

4986
来自专栏求索之路

cs231n之KNN算法

1.环境搭建以及前置条件 1.前置环境: 1.mac 2.pycharm 3.python3 4.Anaconda 2.环境搭建: 1.官网下载并安装Ana...

3229

扫码关注云+社区