【问题标题】:How to predict in multiple and simultanous Keras classifier sessions in Django?如何在 Django 中同时预测多个 Keras 分类器会话?
【发布时间】:2020-01-10 23:22:26
【问题描述】:

我知道以前有人问过类似的问题,我已经阅读了所有这些问题,但没有一个能解决我的问题。

我有一个 Django 项目,我在其中使用来自 sequence_classifiersCNNSequenceClassifier,这是一个 Keras 模型。模型文件之前已经拟合并保存到特定的目的地,我再次从中加载它们并预测我想要什么。

clf = CNNSequenceClassifier(epochs=2)

当我加载模型时,我这样做是因为我在搜索中找到的建议,即在加载模型之前使用全局模型,然后是其他两行:

global clf
clf = pickle.load(open(modelfilenameandpath, "rb"))
global graph
graph = tf.get_default_graph()

在预测之前我使用 graph.as_default()

with graph.as_default():
    probs = clf.predict_proba(the_new_vecs)
K.clear_session()

我输入K.clear_session() 是因为我在 for 循环中进行预测,有时 for 循环的预测的下一项与最后一项混淆并引发 tensorflow 错误。但显然K.clear_session() 清除了会话并使得新项目的预测很容易正常工作。

问题在于我的views.py 我有两个触发预测的函数。有时我需要同时使用两者。但是由于 probject 使用的是 Tensorflow 后端,因此只定义了一个会话,并且这两个函数的预测混合在一起。 K.clear_session() 在这里没有帮助,因为它只针对那个特定的会话,并且它不希望在同一个会话中出现新的东西。

我真的不知道如何让函数在开始加载模型和/或想要预测它时理解它们,开始一个新的独立会话,以免混淆。 我见过这样的代码:

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

但我不知道将probs = clf.predict_proba(the_new_vecs) 放在哪里。似乎所有这些都需要将您希望在会话中完成的操作作为参数传递给sess.run(),这对我不起作用,或者至少我不知道如何使它起作用。我希望在新会话中完成预测,然后probs 的值非常重要。 global_variables_initializer() 似乎也改变了我所有变量的值。

我也尝试过K.set_session()K.get_session(),但没有成功。

总而言之,我认为我被卡住的原因是我不知道如何使用会话来达到我的目的。我不知道在哪里使用什么代码?!

请帮忙!

【问题讨论】:

    标签: python django tensorflow keras tf.keras


    【解决方案1】:

    我对@9​​87654321@ 图表和会话的理解是:

    tensorflow 图形承载操作,placeholders 和 Variables。 tensorflow 图存在于 tensorflow 会话中(这就是为什么要使用 tensorflow.train.Saver 保存经过训练的模型,您需要类似 Saver.save(sess, the graph) 的东西)。

    下面是一个简单示例,可帮助您理解 keras 模型和 tensorflow 图表之间的关系:

    import tensorflow as tf 
    from keras.layers import Input, Dense
    from keras.models import Model 
    
    tf.reset_default_graph()
    graph_1, graph_2 = tf.Graph(), tf.Graph()
    with graph_1.as_default():
        x_in = Input(shape=(1, ), name='in_graph1')
        pred = Dense(5, name='dense1_graph1')(x_in)
        pred = Dense(1, name='dense2_graph1')(pred)
        model = Model(input=x_in, output=pred)
    with graph_2.as_default():
        x_in = Input(shape=(1, ), name='in_graph2')
        pred = Dense(10, name='dense1_graph2')(x_in)
        pred = Dense(1, name='dense2_graph2')(pred)
        model = Model(input=x_in, output=pred)
    
    
    with tf.Session() as sess:
        default_ops = sess.graph.get_operations()
    
    with graph_1.as_default():
        with tf.Session() as sess:
            one_ops = sess.graph.get_operations()
    
    with graph_2.as_default():
        with tf.Session() as sess:      
            two_ops = sess.graph.get_operations()
    

    运行代码可以看到,default_ops 是一个空列表,这意味着默认图表中没有任何操作。 one_ops 是第一个 keras 模型的操作列表,two_ops 是第二个 keras 模型的操作列表。

    因此,通过使用with graph.as_default()keras 模型可以专门嵌入到tensorflow 图中。

    考虑到这一点,在单个脚本中加载多个keras 模型变得很容易。我认为下面的示例脚本将解决您的困惑:

    import numpy as np
    import tensorflow as tf 
    from keras.layers import Input, Dense
    from keras.models import Model
    from Keras.models import model_from_json
    
    tf.reset_default_graph()
    x = np.linspace(1, 4, 4)
    y = np.random.rand(4)
    
    models = {}
    graph_1, graph_2 = tf.Graph(), tf.Graph()
    
    # graph_1 
    with graph_1.as_default():
        x_in = Input(shape=(1, ), name='in_graph1')
        pred = Dense(5, name='dense1_graph1')(x_in)
        pred = Dense(1, name='dense2_graph1')(pred)
        model = Model(input=x_in, output=pred)
        models['graph_1'] = model
    # graph_2
    with graph_2.as_default():
        x_in = Input(shape=(1, ), name='in_graph2')
        pred = Dense(10, name='dense1_graph2')(x_in)
        pred = Dense(1, name='dense2_graph2')(pred)
        model = Model(input=x_in, output=pred)
        models['graph_2'] = model
    
    # save the two models 
    with tf.Session(graph=graph_1) as sess:
        with open("model_1.json", "w") as source:
            source.write(models['graph_1'].to_json())
        models['graph_1'].save_weights("weights_1.h5")
    with tf.Session(graph=graph_2) as sess:
        with open("model_2.json", "w") as source:
            source.write(models['graph_2'].to_json())
        models['graph_2'].save_weights("weights_2.h5")
    
    ####################################################
    # play with the model 
    pred_one, pred_one_reloaded = [], []
    pred_two, pred_two_reloaded = [], []
    for _ in range(10):
        print(_)
        if _ % 2 == 0:
    
            with graph_1.as_default():
                with tf.Session() as sess:
                    sess.run(tf.global_variables_initializer())
                    pred_one.append(models['graph_1'].predict(x).ravel())
            with tf.Session() as sess:
                with open("model_1.json", "r") as f:
                    model = model_from_json(f.read())
                model.load_weights("weights_1.h5")
                pred_one_reloaded.append(model.predict(x).ravel())
    
        else:
            with graph_2.as_default():
                with tf.Session() as sess:
                    sess.run(tf.global_variables_initializer())
                    pred_two.append(models['graph_2'].predict(x).ravel())
            with tf.Session() as sess:
                with open("model_2.json", "r") as f:
                    model = model_from_json(f.read())
                model.load_weights("weights_2.h5")
                pred_two_reloaded.append(model.predict(x).ravel())
    
    pred_one = np.array(pred_one)
    pred_one_reloaded = np.array(pred_one_reloaded)
    pred_two = np.array(pred_two)
    pred_two_reloaded = np.array(pred_two_reloaded)
    
    print(pred_one)
    print(pred_one_reloaded)
    print(pred_two)
    print(pred_two_reloaded)
    

    【讨论】:

      【解决方案2】:

      此时您有 2 个选项,要么使用多处理库,要么在收到请求时衍生一个新进程。这里要小心使用内存。

      另一个(推荐)是导出您的 TensorFlow 模型以在 tensorflow 服务中提供服务,因为您可以选择加载同一模型的多个实例,这样您就可以同时服务而不必担心内存等问题管理或加载和卸载内存。

      【讨论】:

      • 能否更具体地介绍一下您推荐的解决方案?
      猜你喜欢
      • 2018-01-12
      • 2015-08-11
      • 2019-09-09
      • 2020-08-04
      • 1970-01-01
      • 2021-03-01
      • 2020-06-15
      • 2020-08-12
      • 2019-07-02
      相关资源
      最近更新 更多