图像分类和张量流服务

image classify and tensorflow serving

首先抱歉,我不是很清楚这个问题,但我正在研究 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 然后它会预测它

当我编译代码时 return 在尝试保存模型时出现了很多错误。你能检查一下并告诉我保存模型说明是否正确吗?

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

我试图发表评论,因为我没有给你肯定的答案,但我没有足够的答案 space。希望此信息对您有所帮助,并且可以通过 "answer".

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

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

此外,我认为您不想使用与模型相同的代码来制作图像 downloading/processing。TFServe 不应该 运行 pre-post 加工;只需托管您的模型。

所以你可以做的是创建类似 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

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

主要思想是您的模型应该保存到一个 artifact/binary 中,它可以 运行 并且不需要您的代码 运行。这使您可以将建模与数据预处理和 post 处理分开,并为您的模型提供一个与 运行 更一致的地方;例如您无需担心模型依赖项的竞争版本 运行.

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

所以,在真正了解 Tensorflow 的人给出真正的答案之前,我希望这能有所帮助。