管理多个会话和图形的合理方法 [英] Sound way of managing multiple sessions and graphs

查看:166
本文介绍了管理多个会话和图形的合理方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to manage multiple Keras models in multiple sessions. My application is constructed such that models can be live at the same time, in addition to creating, saving and loading them.

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

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

Currently one model is represented by an instance of a wrapper class. This is used in the training, saving, loading and prediction. One tf.Graph and tf.Session is created per instance, and they are used in every function requiring the actual model.

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)和加载.因此,只要需要模型,就可以将图和会话置于上下文中.

Similar functions using the with statements are created for compiling the network, fitting, saving (weights to .h5 and model to JSON) and loading. So whenever the model is needed, the graph and session are brought to context.

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

This resulted in a strange error (Q for further context), and I was left wondering, what is the standard way of dealing with this. I tried to release all possible resources before creating or loading a model, but it hasn't helped. This function is just a compilation of all possible routines scraped off the internet, and is purely guesswork.

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)

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

I've not found good documentation of a similar situation. So I'd very much appreciate any real insight into this.

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

I might need to delete the old question, as it's quite all over the place. At the time of asking I had no idea what was going on. But it's there for now.

出现了一些具体问题.

  • 在模型上加载和进行预测有效,编译和拟合无效,尽管仅编译即可.两种情况有什么不同吗?加载的模型是否完全相同?
  • 在处理模型时应在什么时候创建新的上下文? (例如,在加载,编译,拟合时,可能并非每次预测都如此)
  • 释放先前上下文的资源时需要采取哪些行动?丢弃网络时或创建新上下文时.
  • 为什么要为多个模型准确地进行上下文切换?
  • 鉴于在图和会话上执行不同的操作,图与会话的作用是什么?
  • 编译,安装和保存一个网络可以有效地解决上下文问题.在相同上下文中对另一个模型执行相同操作也可以(或者至少不会产生错误).
  • 除上述内容外,在训练后以及两个模型都加载已保存的模型并预测工作!现在,我不确定预测是否正确,但是再次,没有错误.这只是在乞求我上面提出的问题:为什么需要不同的上下文?
  • Compiling, fitting and saving one network works without any context trickery. Doing the same for another model in the same context works too (or at least does not produce an error).
  • In addition to above, loading the saved model and predicting works too, right after the training and for both models! Now I'm not sure whether the prediction is made correctly, but again, no error. This only begs the question I posed above even more: why are the different contexts needed?

该错误的根本问题终于(有点尴尬)已解决通过更新所有软件包.

The underlying issue with the error has been finally (and somewhat embarassingly) resolved by updating all packages.

推荐答案

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

Actually, seeing again how K.get_session() works, it should return the current default session, so I'm not sure set_session is doing anything meaningful there. I'll leave the answer just in case you want to try but probably this won't help.

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

Maybe you can get it to work with something like this:

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会话对象是一个全局变量,因此只要您不尝试从多个线程中使用这些上下文,我想这应该可以工作.

Note that the Keras session object is a global variable, so I suppose this should work as long as you don't try to use these contexts from multiple threads.

这篇关于管理多个会话和图形的合理方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆