【问题标题】:image classify and tensorflow serving图像分类和张量流服务
【发布时间】:2019-04-11 00:21:09
【问题描述】:

首先抱歉,我对这个问题并不准确,但我正在研究 tensorflow-serving 以及如何将我的 cnn 投入生产。真诚的文档让我很困惑。我希望你能帮助更好地理解保存模型架构。所以请以老师的身份回复我,我想了解更多关于整个流程的信息。

我正在开发一个简单的 cnn 来将图像分类为 4 个输出。 我需要 tensorflow-serving 将其投入生产。 输入中的图像可以是 watherver 大小,CNN 应该首先调整它的大小并进行预测。 代码在这里

import numpy as np
import tensorflow as tf
from tensorflow import keras
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot as plt
from scipy.misc import toimage
from keras.models import Sequential
from keras.layers import *
from keras.optimizers import *
from tensorflow.python.saved_model import builder as saved_model_builder
from tensorflow.python.saved_model import tag_constants, signature_constants, signature_def_utils_impl
import cv2



#train_path='Garage/train'
#train_datagen = ImageDataGenerator(rescale=1./255)
#train_batch = train_datagen.flow_from_directory(train_path, target_size=(64,64), class_mode='categorical', batch_size=10, color_mode='grayscale')


#validation_datagen = ImageDataGenerator(rescale=1./255)
#validation_batch = validation_datagen.flow_from_directory(
#        './Garage/validation',
#        target_size=(64, 64),
#        batch_size=3,
#        class_mode='categorical', color_mode='grayscale')

model = Sequential()
model.add(InputLayer(input_shape=[64,64,1]))
model.add(Conv2D(filters=32,kernel_size=5,strides=1,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=5,padding='same'))

model.add(Conv2D(filters=50,kernel_size=5,strides=1,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=5,padding='same'))

model.add(Conv2D(filters=80,kernel_size=5,strides=1,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=5,padding='same'))

model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512,activation='relu'))
model.add(Dropout(rate=0.5))
model.add(Dense(4,activation='softmax'))
optimizer=Adam(lr=1e-3)

model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
#model.fit_generator(
#        train_batch,
#        epochs=50,
#        steps_per_epoch=6,
#        validation_data=validation_batch,
#        validation_steps=5)

model.load_weights('model.h5')

#score = model.evaluate_generator(validation_batch,steps=3)
#print('Test loss:', score[0])
#print('Test accuracy:', score[1])

#model.save('model.h5')


from PIL import Image
import requests
from io import BytesIO

response = requests.get('http://192.168.3.21:7451/shot.jpg')
image_pil = Image.open(BytesIO(response.content))
image = np.asarray(image_pil)

img2 = cv2.resize(image,(64,64))
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
img = np.reshape(img2,[1,64,64,1])

classes = model.predict_classes(img)

print(classes)

model_version="1"

sess = tf.Session()

#setting values for the sake of saving the model in the proper format
x = model.input
y = model.output

prediction_signature = tf.saved_model.signature_def_utils.predict_signature_def({"inputs":x}, {"prediction":y})

valid_prediction_signature = tf.saved_model.signature_def_utils.is_valid_signature(prediction_signature)
if(valid_prediction_signature == False):
    raise ValueError("Error: Prediction signature not valid!")

builder = saved_model_builder.SavedModelBuilder('./'+model_version)
legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')

# Add the meta_graph and the variables to the builder
builder.add_meta_graph_and_variables(
      sess, [tag_constants.SERVING],
      signature_def_map={
           signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:prediction_signature, },
      legacy_init_op=legacy_init_op)

# save the graph
builder.save()

代码将从摄像头拍摄照片http://192.168.3.21:7451/shot.jpg 然后它会预测它

当我编译代码时,它会在尝试保存模型时返回很多错误。请您检查一下并告诉我保存模型说明是否正确?

我使用 x = model.input 作为服务的输入,但我希望它将图片作为服务器的输入。 实际上我很困惑,对不起。 范围是当我通过 gRPC 请求预测图像时,模型可以给我预测结果 谢谢

【问题讨论】:

    标签: tensorflow-serving


    【解决方案1】:

    我试图发表评论,因为我没有确定的答案给你,但我没有足够的空间。希望这些信息对您有所帮助,并且可以作为“答案”。

    无论如何,对于像我这样的 Tensorflow 新手来说,如果没有看到任何错误,很难说出问题所在。

    我注意到的一件事是predict_signature_def() 的方法调用似乎没有遵循我在here 找到的方法签名。

    另外,我认为您不希望在与模型相同的代码中进行图像下载/处理。TFServe 不应该运行预处理;只需托管您的模型。

    因此,您可以创建一个类似 RESTful 服务的东西来接受图像,然后在其上运行预处理并将处理后的图像作为请求的一部分发送到 TFServe。它看起来像这样:

    user+image 
        -> requests classification to RESTful service 
        -> REST API receives image
        -> REST service resizes image
        -> REST service makes classification request to TFS (where your model is)
        -> TFS receives request, including resized/preprocessed image
        -> TFS invokes classification using your model and the arguments you sent
        -> TFS responds to REST service with model's response
        -> REST service responds to user with the classification from your model
    

    这种方式很糟糕,因为在网络中传递图像效率低下并且速度可能很慢,但您可以在找到痛点时进行优化。

    主要思想是您的模型应该保存到可以运行且不需要您的代码运行的工件/二进制文件中。这使您可以将建模与数据预处理和后处理分开,并为您的模型提供更一致的运行位置;例如您无需担心模型运行时依赖的竞争版本。

    不利的一面是,在将这些部件从看起来像你拥有的整体架构中分离出来之后,让它们很好地适应可能需要一些学习曲线。

    所以,在真正了解 Tensorflow 的人提供真正的答案之前,我希望这会有所帮助。

    【讨论】:

    • 谢谢!你看起来不像新手 :) 你是对的,预处理不在 ML 图的范围内。你提到的流程的用法很有趣......我需要深入研究它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 2016-11-06
    • 2017-03-23
    • 1970-01-01
    • 2020-02-29
    相关资源
    最近更新 更多