Skip to main content
 首页 » 编程设计

python之如何在 Django 的多个同时进行的 Keras 分类器 session 中进行预测

2024年09月03日39sxdcgaq8080

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

我有一个 Django 项目,我在其中使用 sequence_classifiers 中的 CNNSequenceClassifier,这是一个 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() 清除了 session 并使新项目的预测很容易正常工作。

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

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

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

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

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

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

请帮忙!

请您参考如下方法:

我对 tensorflow 图和 session 的理解是:

tensorflow 图表包含操作、placeholder 和 Variable。 tensorflow 图存在于 tensorflow session 中(这就是为什么要使用 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)