Keras(Tensorflow后端)错误-在图表中找不到在feed_devices或fetch_devices中指定的Tensor输入_1:0

Mat*_*die 6 python keras tensorflow

当我尝试使用简单的模型进行预测时,我得到了以下错误:

在图表中找不到在feed_devices或fetch_devices中指定的张量输入_1:0

在行:

seatbelt_model.predict(image_arr, verbose=1)
Run Code Online (Sandbox Code Playgroud)

在代码中:

from tensorflow import keras
import tensorflow as tf
import numpy as np

graph = tf.get_default_graph()

seatbelt_model = keras.models.load_model(filepath='./graphs/seatbelt_A_3_81.h5')

class SeatbeltPredictor:
    INPUT_SHAPE = (-1, 120, 160, 1)

    @staticmethod
    def predict_seatbelt(image_arr):
        with graph.as_default():
            image_arr = np.array(image_arr).reshape(SeatbeltPredictor.INPUT_SHAPE)
            predicted_labels = seatbelt_model.predict(image_arr, verbose=1)
            return predicted_labels
Run Code Online (Sandbox Code Playgroud)

该模型具有以下形状:

input_layer = keras.layers.Input(shape=(IMAGE_HEIGHT, IMAGE_WIDTH, 1))
conv_0 = keras.layers.Conv2D(filters=32, kernel_size=[5, 5], activation=tf.nn.relu, padding="SAME")(input_layer)
pool_0 = keras.layers.MaxPool2D(pool_size=[2, 2], strides=2, padding="VALID")(conv_0)
conv_1 = keras.layers.Conv2D(filters=32, kernel_size=[5, 5], activation=tf.nn.relu, padding="SAME")(pool_0)
pool_1 = keras.layers.MaxPool2D(pool_size=[2, 2], strides=2, padding="VALID")(conv_1)
flat_0 = keras.layers.Flatten()(pool_1)
dense_0 = keras.layers.Dense(units=1024, activation=tf.nn.relu)(flat_0)
drop_0 = keras.layers.Dropout(rate=0.4, trainable=True)(dense_0)
dense_1 = keras.layers.Dense(units=2, activation=tf.nn.softmax)(drop_0)
Run Code Online (Sandbox Code Playgroud)

如果运行以下命令,将得到张量结果:

graph.get_tensor_by_name('input_1:0')
<tf.Tensor 'input_1:0' shape=(?, 120, 160, 1) dtype=float32>
Run Code Online (Sandbox Code Playgroud)

第一层的名称为input_1

image_arr的形状为(1,120,160,1)

Tensorflow 1.12

有任何想法吗?

Mat*_*die 16

好吧,在经历了许多痛苦和折磨之后,我发现了以下内容:

尽管模型具有Session和Graph,但是在某些张量流方法中,使用了默认的Session和Graph。为了解决这个问题,我必须明确地说我想同时使用Session和Graph作为默认值:

with session.as_default():
    with session.graph.as_default():
Run Code Online (Sandbox Code Playgroud)

完整代码:

from tensorflow import keras
import tensorflow as tf
import numpy as np
import log

config = tf.ConfigProto(
    device_count={'GPU': 1},
    intra_op_parallelism_threads=1,
    allow_soft_placement=True
)

config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.6

session = tf.Session(config=config)

keras.backend.set_session(session)

seatbelt_model = keras.models.load_model(filepath='./seatbelt.h5')

SEATBEL_INPUT_SHAPE = (-1, 120, 160, 1)

def predict_seatbelt(image_arr):
    try:
        with session.as_default():
            with session.graph.as_default():
                image_arr = np.array(image_arr).reshape(SEATBEL_INPUT_SHAPE)
                predicted_labels = seatbelt_model.predict(image_arr, verbose=1)
                return predicted_labels
    except Exception as ex:
        log.log('Seatbelt Prediction Error', ex, ex.__traceback__.tb_lineno)
Run Code Online (Sandbox Code Playgroud)


Pra*_*ell 5

这是部署多个模型(尤其是在应用程序中)时面临的一个非常常见的问题flask。处理此问题的最佳方法是在加载任何 keras 模型之前设置session保存graph。如果您尝试使用pickled模型来预测标签,这特别有帮助。

脚步

  • 只需在加载模型之前保存session和即可。graph
  • 在不同的线程中,加载这些保存的变量,然后使用模型的predict函数。

完整代码示例:

主班

import pickle
import tensorflow as tf
from tensorflow.python.keras.backend import set_session

# your other file/class
import UserDefinedClass

class Main(object):

    def __init__(self):
        return

    def load_models(self):

        # Loading a generic model
        model1 = pickle.load(open(model1_path, "rb"))

        # Loading a keras model
        session = tf.Session()
        graph = tf.get_default_graph()
        set_session(session)
        model2 = pickle.load(open(model2_path, "rb"))

        # Pass 'session', 'graph' to other classes
        userClassOBJ = UserDefinedClass(session, graph, model1, model2) 
        return

    def run(self, X):
        # X is input
        GenericLabels, KerasLables = userClassOBJ.SomeFunction(X)
Run Code Online (Sandbox Code Playgroud)

不同线程或flask_call中的其他一些文件/类:

from tensorflow.python.keras.backend import set_session

class UserDefinedClass(object):

    def __init__(self, session, graph, model1, model2):
        self.session = session
        self.graph = graph
        self.Generic_model = model1
        self.Keras_model = model2
        return

    def SomeFunction(self, X):

        # Generic model prediction
        Generic_labels = self.Generic_model.predict(X)
        print("Generic model prediction done!!")

        # Keras model prediciton
        with self.graph.as_default():
            set_session(self.session)
            Keras_labels = self.Keras_model.predict(X, verbose=0)
            print("Keras model prediction done!!")
        return Generic_labels, Keras_labels 
Run Code Online (Sandbox Code Playgroud)