管理多个会话和图形的合理方法

时间:2018-11-08 11:31:56

标签: python tensorflow keras

我想在多个会话中管理多个Keras模型。构建我的应用程序后,除了创建,保存和加载模型外,还可以同时运行它们。

解决这种情况的正确方法是什么?

当前,一个模型由包装类的实例表示。它用于训练,保存,加载和预测。每个实例分别创建一个tf.Graphtf.Session,它们被用在需要实际模型的每个函数中。

class NN:
    def __init__(self):
        self.graph = tf.Graph()
        self.session = tf.Session(graph=self.graph)

    def predict(self, x):
        with self.graph.as_default():
            with self.session.as_default():
                return self.model.predict(x)

使用with语句创建相似的函数来编译网络,拟合,保存(权重为.h5,模型为JSON)和加载。因此,只要需要模型,就可以将图和会话置于上下文中。

这导致了一个奇怪的错误(进一步的情况是Q),让我感到奇怪的是,处理此问题的标准方法是什么。在创建或加载模型之前,我试图释放所有可能的资源,但是并没有帮助。该功能只是从互联网上刮除的所有可能例程的汇编,纯粹是猜测。

def _new_session(self):
    if self.session is not None:
        self.session.close()
    k.clear_session()
    gc.collect()
    self.graph = tf.Graph()
    self.session = tf.Session(graph=self.graph)

我没有找到类似情况的好的文档。因此,我非常感谢对此有任何真正的见识。


我可能需要删除旧问题,因为它遍地都是。在问的时候,我不知道发生了什么。但是现在就在那里。


出现了一些具体问题。

  • 在模型上加载和进行预测有效,但编译和拟合无效,尽管仅编译即可。两种情况有什么不同吗?加载的模型是否完全相同?
  • 在处理模型时应在什么时候创建新的上下文? (例如,在加载,编译,拟合时,可能并非每次预测都如此)
  • 释放先前上下文的资源时需要采取哪些措施?处置网络或创建新上下文时都是如此。
  • 为什么要为多个模型准确地进行上下文切换?
  • 鉴于在图和会话上执行不同的操作,图与会话的作用是什么?

更新

  • 编译,安装和保存一个网络可以有效地解决上下文问题。在相同上下文中对另一个模型执行相同操作也可以(或者至少不会产生错误)。
  • 除上述内容外,在训练后以及两个模型都加载已保存的模型并预测工作!现在,我不确定该预测是否正确,但是再次,没有错误。这只是乞求我上面提出的问题:为什么需要不同的上下文?

最终,该错误的根本问题是通过更新所有程序包({有点尴尬)resolved

1 个答案:

答案 0 :(得分:0)

编辑:实际上,再次看到K.get_session()的工作方式,它应该返回当前的默认会话,因此我不确定set_session在那儿做任何有意义的事情。万一您想尝试,我会留下答案,但这可能无济于事。


也许您可以使它与类似这样的东西一起工作:

from contextlib import contextmanager

class NN:
    def __init__(self):
        self.graph = tf.Graph()
        self.session = tf.Session(graph=self.graph)

    def predict(self, x):
        with self._context():
            return self.model.predict(x)

    @contextmanager
    def _context(self):
        prev_sess = K.get_session()
        K.set_session(self.session)
        with self.graph.as_default(), self.session.as_default():
            yield
        K.set_session(prev_sess)

请注意,Keras会话对象是一个全局变量,因此只要您不尝试从多个线程中使用这些上下文,我想这应该起作用。