首先,很抱歉,我对此问题并不满意,但我正在研究张量流服务以及如何将CNN投入生产。诚挚的是,文档对我很困惑。希望您能帮助您更好地了解保存模型架构。因此,请以老师的身份答复我,我想进一步了解整个流程。
我正在开发一个简单的cnn以将图像分类为4个输出。 我需要张量流服务才能投入生产。 输入中的图像可以是任意大小,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请求预测图像时,模型可以为我提供预测结果 谢谢
答案 0 :(得分:1)
我试图发表评论,因为我没有为您提供肯定的答案,但是我没有足够的空间。希望此信息对您有所帮助,并且可以通过“答案”。
无论如何,很难说出像我这样的Tensorflow newb是什么问题而没有看到任何错误。
我注意到的一件事是,对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知道者出现真正的答案之前,我希望这会有所帮助。