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

相关文章

来自专栏AI研习社

按照这几个步骤操作,不实现 RNN 都难!

最近在看RNN模型,为简单起见,本篇就以简单的二进制序列作为训练数据,而不实现具体的论文仿真,主要目的是理解RNN的原理和如何在TensorFlow中构造一个简...

2767
来自专栏深度学习自然语言处理

深度学习数学基础一--最小二乘法

之前总是先上手一些比较高级的神经网络算法,CNN,RNN等。可是总觉得有些知识原理总是羁绊着我进一步理解。这才意识到基础的重要性。所以,就一点一点的从基础数学最...

3069
来自专栏AI科技评论

深度丨机器学习零基础?手把手教你用TensorFlow搭建图像识别系统(三)

AI科技评论按:本文是介绍用TensorFlow构建图像识别系统的第三部分。 在前两部分中,我们构建了一个softmax分类器来标记来自CIFAR-10数据集的...

3236
来自专栏云时之间

Tensorflow 笔记:搭建神经网络

1423
来自专栏海天一树

机器学习(一):k最近邻(kNN)算法

一、概述 kNN算法,即K最近邻(k-NearestNeighbor)分类算法,是最简单的机器学习算法,没有之一。 该算法的思路是:如果一个样本在特征空间中的k...

2565
来自专栏https://www.cnblogs.com/L

【TensorFlow篇】--Tensorflow框架可视化之Tensorboard

TensorBoard是tensorFlow中的可视化界面,可以清楚的看到数据的流向以及各种参数的变化,本文基于一个案例讲解TensorBoard的用法。

822
来自专栏杂七杂八

tensorflow oom报错OOM when allocating tensor with shape

今天在GPU上运行卷积神经网络手写数字,报了如下错误Resource exhausted: OOM when allocating tensor with s...

4089
来自专栏漫漫深度学习路

tensorflow学习笔记(三十):tf.gradients 与 tf.stop_gradient() 与 高阶导数

gradient tensorflow中有一个计算梯度的函数tf.gradients(ys, xs),要注意的是,xs中的x必须要与ys相关,不相关的话,会报错...

5879
来自专栏求索之路

cs231n之SVM算法和SoftMax算法

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

2866
来自专栏数据结构与算法

P3717 [AHOI2017初中组]cover

题目背景 以下为不影响题意的简化版题目。 题目描述 一个n*n的网格图上有m个探测器,每个探测器有个探测半径r,问这n*n个点中有多少个点能被探测到。 输入输出...

2857

扫码关注云+社区