受监控的培训课程如何运作?

时间:2017-04-06 03:36:11

标签: python tensorflow

我试图了解使用tf.Sessiontf.train.MonitoredTrainingSession之间的区别,以及我可能更喜欢使用QFileDialog//#define NOMENUCLASS 1 #ifdef NOMENUCLASS class Q_WIDGETS_EXPORT QNoMenuFileDialog : public QFileDialog { public: QNoMenuFileDialog(); ~QNoMenuFileDialog(); protected: void ShowContextMenu(const QPoint& pos); }; void QNoMenuFileDialog::ShowContextMenu(const QPoint& pos) {} QNoMenuFileDialog::QNoMenuFileDialog(){} QNoMenuFileDialog::~QNoMenuFileDialog(){} #endif void MainWindow::on_pushButton_2_clicked() { QStringList mimeTypeFilters; mimeTypeFilters << "image/jpeg" /*will show "JPEG image (*.jpeg *.jpg *.jpe)*/ << "image/png" /*will show "PNG image (*.png)"*/ << "application/octet-stream"; /*will show "All files (*)"*/ #ifdef NOMENUCLASS /*1. try to disable the right click menu using a invalid function ShowContextMenu --failed */ QNoMenuFileDialog dialog; dialog.setMimeTypeFilters(mimeTypeFilters); dialog.setContextMenuPolicy(Qt::NoContextMenu); #else /*2. try to disable the right click menu using setContextMenuPolicy(Qt::PreventContextMenu) --failed */ QFileDialog dialog; dialog.setContextMenuPolicy(Qt::PreventContextMenu); #endif if(dialog.exec() == QDialog::Accepted) { QString path = dialog.selectedFiles()[0]; QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path); } else { QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files.")); } } 的区别。似乎当我使用后者时,我可以避免许多琐事和#34;例如初始化变量,启动队列运行程序或为汇总操作设置文件编写器。另一方面,通过受监控的培训会话,我无法指定我想明确使用的计算图。所有这些对我来说似乎都很神秘。这些类是如何创建的,我不理解这些背后的哲学吗?

1 个答案:

答案 0 :(得分:28)

我无法对如何创建这些类提供一些见解,但我认为这些内容与您如何使用它们有关。

tf.Session是python TensorFlow API中的低级对象,而 如你所说,tf.train.MonitoredTrainingSession附带了许多方便的功能,特别适用于大多数常见情况。

在介绍tf.train.MonitoredTrainingSession的一些好处之前,让我回答一下有关会话使用的图表的问题。您可以使用上下文管理器tf.Graph指定MonitoredTrainingSession使用的with your_graph.as_default()

from __future__ import print_function
import tensorflow as tf

def example():
    g1 = tf.Graph()
    with g1.as_default():
        # Define operations and tensors in `g`.
        c1 = tf.constant(42)
        assert c1.graph is g1

    g2 = tf.Graph()
    with g2.as_default():
        # Define operations and tensors in `g`.
        c2 = tf.constant(3.14)
        assert c2.graph is g2

    # MonitoredTrainingSession example
    with g1.as_default():
        with tf.train.MonitoredTrainingSession() as sess:
            print(c1.eval(session=sess))
            # Next line raises
            # ValueError: Cannot use the given session to evaluate tensor:
            # the tensor's graph is different from the session's graph.
            try:
                print(c2.eval(session=sess))
            except ValueError as e:
                print(e)

    # Session example
    with tf.Session(graph=g2) as sess:
        print(c2.eval(session=sess))
        # Next line raises
        # ValueError: Cannot use the given session to evaluate tensor:
        # the tensor's graph is different from the session's graph.
        try:
            print(c1.eval(session=sess))
        except ValueError as e:
            print(e)

if __name__ == '__main__':
    example()

所以,正如你所说,使用MonitoredTrainingSession的好处是,这个对象需要处理

  • 初始化变量,
  • 启动队列跑步者以及
  • 设置文件编写器,

但它的优点还在于使代码易于分发,因为它的工作方式也不同,具体取决于您是否将运行流程指定为主服务器。

例如,你可以运行类似:

def run_my_model(train_op, session_args):
    with tf.train.MonitoredTrainingSession(**session_args) as sess:
        sess.run(train_op)

您将以非分布式方式致电:

run_my_model(train_op, {})`

或以分布式方式(有关输入的更多信息,请参阅distributed doc):

run_my_model(train_op, {"master": server.target,
                        "is_chief": (FLAGS.task_index == 0)})

另一方面,使用原始tf.Session对象的好处是,您没有tf.train.MonitoredTrainingSession的额外好处,如果您不打算使用它可能很有用它们或者如果你想获得更多控制(例如关于如何启动队列)。

编辑(根据评论): 对于操作初始化,您必须执行类似的操作(参见official doc

# Define your graph and your ops
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init_p)
    sess.run(your_graph_ops,...)

对于QueueRunner,我会推荐您到official doc,在那里您可以找到更完整的示例。

EDIT2:

了解tf.train.MonitoredTrainingSession如何运作的主要概念是_WrappedSession类:

  

此包装器用作各种会话包装器的基类     提供额外的功能,如监控,协调,     和恢复。

tf.train.MonitoredTrainingSession以这种方式工作(截至version 1.1):

  • 首先检查它是主人还是工人(参见词汇问题的distributed doc)。
  • 它开始提供的钩子(例如,StopAtStepHook将在此阶段检索global_step张量。
  • 它会创建一个Chief(或Worker会话)的会话,该会话包含在_HookedSession中,并被_CoordinatedSession包裹在_RecoverableSession中。<登记/> Chief / Worker个会话负责运行Scaffold提供的初始化操作。
      scaffold: A `Scaffold` used for gathering or building supportive ops. If
    not specified a default one is created. It's used to finalize the graph.
    
  • chief会话还会处理所有检查点部分:例如使用Saver。{/ li>中的Scaffold从检查点恢复
  • _HookedSession基本上用来装饰run方法:它在相关时调用_call_hook_before_runafter_run方法。
  • 在创建时,_CoordinatedSession会构建一个Coordinator来启动队列运行程序,并负责关闭它们。
  • _RecoverableSession将确保在tf.errors.AbortedError的情况下重试。

总之,tf.train.MonitoredTrainingSession避免了大量的锅炉板代码,同时可以通过钩子机制轻松扩展。