我试图了解使用tf.Session
和tf.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;例如初始化变量,启动队列运行程序或为汇总操作设置文件编写器。另一方面,通过受监控的培训会话,我无法指定我想明确使用的计算图。所有这些对我来说似乎都很神秘。这些类是如何创建的,我不理解这些背后的哲学吗?
答案 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):
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_run
和after_run
方法。 _CoordinatedSession
会构建一个Coordinator
来启动队列运行程序,并负责关闭它们。_RecoverableSession
将确保在tf.errors.AbortedError
的情况下重试。总之,tf.train.MonitoredTrainingSession
避免了大量的锅炉板代码,同时可以通过钩子机制轻松扩展。