zoukankan      html  css  js  c++  java
  • Tensorflow-slim 学习笔记(二)第一层目录代码解读

    通过阅读代码来学习,一向时最直接快速的。本章将讲解slim的第一层目录tensorflow/tensorflow/contrib/slim/python/slim的代码。

    本层代码主要包括learning.py, evaluation.py, summary.py, queue.py和model_analyzer.py,分别对应模型的训练,测试,日志记录,队列管理和模型分析部分。

    让巴默索泪来带你由易到难来阅读下这些代码吧。以下内容基本按照难度排序。

    1. 模型分析模块 model_analyzer.py

    这段代码提供了分析Tensorflow图中的运算和变量的工具。

      #To analyze the operations in a graph:

      images, labels = LoadData(...)  
      predictions = MyModel(images)

      slim.model_analyzer.analyze_ops(tf.get_default_graph(), print_info=True)

      #To analyze the model variables in a graph:

      variables = tf.model_variables()  

      slim.model_analyzer.analyze_vars(variables, print_info=False)

    2. queue.py提供了队列内容管理代码

    3. summaries.py 包括了生成日至纪录的辅助函数, summaries_test.py是它的一个测试,使用例子见下:

      import tensorflow as tf
      slim = tf.contrib.slim

      slim.summaries.add_histogram_summaries(slim.variables.get_model_variables())
      slim.summaries.add_scalar_summary(total_loss, 'Total Loss')
      slim.summaries.add_scalar_summary(learning_rate, 'Learning Rate')
      slim.summaries.add_histogram_summaries(my_tensors)
      slim.summaries.add_zero_fraction_summaries(my_tensors)

    4.  evaluation.py一般不会使用slim的代码,故忽略。

    5. 最重要的训练模型的代码在learning.py中,其中learning_test.py是一个测试例子

        learning.py中包括训练模型所需的多个函数,包括操作梯度,生成一个训练操作(train_op, 一个计算loss并应用梯度的操作)以及训练的循环函数。训练循环要求用户传入train_op就可以进行优化。注意在这里训练循环使用了tf.train.Supervisor以及在它代码实现中的managed_session,这可以保证机器可以从运行失败中恢复训练。Supervisor是对负责训练程序的Coordinator,Saver和SessionManager的封装。下面是一个简单的例子:

      # Load data and create the model:

      images, labels = LoadData(...)
      predictions = MyModel(images)

      # Define the loss:
      slim.losses.log_loss(predictions, labels)
      total_loss = slim.losses.get_total_loss()

      # Define the optimizer:
      optimizer = tf.train.MomentumOptimizer(FLAGS.learning_rate, FLAGS.momentum)

      # Create the train_op
      train_op = slim.learning.create_train_op(total_loss, optimizer)

      # Run training.
      slim.learning.train(train_op, my_log_dir)

    训练必须首先定义一个 train_op, 它的作用包括:(1)计算损失(2)将梯度运用于参数的更新(3)返回损失值

    train_op有时还必须在训练时,执行额外的非梯度更新的操作,比如batch_norm。batch_norm在训练时需要执行一系列非梯度的更新操作。slim.learning.create_train_op允许用户同时将update_ops的列表以及梯度更新操作同时传递给函数。

      train_op = slim.learning.create_train_op(total_loss, optimizer, update_ops)  

    默认情况下,slim.learning.create_train_op包括了所有在tf.GraphKeys.UPDATE_OPS集合中的更新操作。而且,slim的slim.batch_norm函数将moving mean和moving variance的更新加入了这个集合。因此,使用slim.batch_norm的用户不用考虑任务多余的步骤就能保证moving mean 和moving variance的更新会被正确的计算。如果用户需要加入额外的更新操作,可以使用下面的代码:

      # Force TF-Slim NOT to use ANY update_ops:
      train_op = slim.learning.create_train_op(
      total_loss,
      optimizer,
      update_ops=[])

      # Use an alternative set of update ops:
      train_op = slim.learning.create_train_op(
      total_loss,
      optimizer,
      update_ops=my_other_update_ops)

      # Use an alternative set of update ops in addition to the default updates:
      tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, my_update0)
      tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, my_update1)

      train_op = slim.learning.create_train_op(
      total_loss,
      optimizer)

      # Which is the same as:
      train_op = slim.learning.create_train_op(
      total_loss,
      optimizer,
      update_ops=tf.get_collection(tf.GraphKeys.UPDATE_OPS))

    learning训练最重要的有两个函数:create_train_op以及train

    (1)def create_train_op(total_loss,
                         optimizer,
                                     global_step=_USE_GLOBAL_STEP,
                                           update_ops=None,
                                           variables_to_train=None,
                                           clip_gradient_norm=0,
                                           summarize_gradients=False,
                                           gate_gradients=tf_optimizer.Optimizer.GATE_OP,
                                           aggregation_method=None,
                                           colocate_gradients_with_ops=False,
                                           gradient_multipliers=None,
                                           check_numerics=True)

            clip_gradient_norm:当它大于0时,梯度被截止于这个值。

    返回值时一个Tensor,它计算了梯度并返回了loss值。

    (2)def train(train_op,

    logdir,
    train_step_fn=train_step,
    train_step_kwargs=_USE_DEFAULT,
    log_every_n_steps=1,
    graph=None,
    master='',
    is_chief=True,
    global_step=None,
    number_of_steps=None,
    init_op=_USE_DEFAULT,
    init_feed_dict=None,
    local_init_op=_USE_DEFAULT,
    init_fn=None,
    ready_op=_USE_DEFAULT,
    summary_op=_USE_DEFAULT,
    save_summaries_secs=600,
    summary_writer=_USE_DEFAULT,
    startup_delay_steps=0,
    saver=None,
    save_interval_secs=600,
    sync_optimizer=None,
    session_config=None,
    trace_every_n_steps=None)

    这个函数使用Tensorflow的supervisor运行了一个训练循环。当使用sync_optimizer时,梯度计算是同步进行的。否则,梯度计算是异步进行的。

    参数:

    log_every_n_steps:损失函数和step的打印频率

    master:tensorflow master的地址

    is_chief:指定是否训练是有主副本实现的,当进行多副本训练时。

    sync_optimizer:   一个tf.SyncReplicasOptimizer 或它们的一个列表。如果提供了这个参数,梯度更新会是同步的,如果使用None,则更新是异步的。

     

  • 相关阅读:
    201671010135 2016--2017<java程序设计:学习总结>
    201671010135 2016--2017--《java程序设计:图形程序设计》
    201671010135 2016--2017--《java程序设计:第就章存在问题》
    201671010135 2016--2017--《java程序设计:泛型数组设计学习总结》
    201671010135 2016--2017--《java程序设计:第七章 异常,断言和日志》
    2016710101352016-2017-2 《JAVA程序设计》第八周学习总结
    201671010145 赵乾 学习统计
    201671010145 2016-2017 《JAVA程序设计》Java线程:线程的同步-同步方法
    201671010145 2016-2017《Java程序设计》Java中进程与线程的区别
    201671010145 2016-2017《Java程序设计》 如何进行JAVA项目打包部署?
  • 原文地址:https://www.cnblogs.com/bmsl/p/dongbin_bmsl_02.html
Copyright © 2011-2022 走看看