Keras model部署服务--Flask

Keras model部署服务–Flask

深度学习模型被训练后,需要将model部署为一个服务。本文给出一个利用flask部署keras model服务的demo。这个网络的Demo来自于TF的官网,首先引入相应的包:

# Tensorflow classification
from __future__ import absolute_import, division, print_function, unicode_literals
import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
import tensorflow as tf
from tensorflow import keras
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
print(tf.__version__)
# 1.12.0

加载数据

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
# 数据预处理
train_images = train_images / 255.0
test_images = test_images / 255.0

构建网络结构

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# 训练
model.fit(train_images, train_labels, epochs=5)

模型评价

test_loss, test_acc = model.evaluate(test_images, test_labels)
# 10000/10000 [==============================] - 0s 27us/step
# Test acc: 0.8732

保存权重为.h5文件

model.save_weights('./model/weights.h5')

部署部分

# 引入包,构建网络并加载训练好的参数
from flask import Flask, render_template, request
from scipy.misc import imsave, imread, imresize
import numpy as np
import tensorflow as tf
from tensorflow import keras
import re, sys, os
import base64
import cv2
sys.path.append(os.path.abspath('./model'))
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.load_weights('./model/weights.h5')
graph = tf.get_default_graph()

定义数据转化的方法

def b64_to_ndarray(image_b64):
    img_bytes = base64.b64decode(image_b64)
    nparr = np.frombuffer(img_bytes, np.uint8)
    arr = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)
    assert arr.shape == (28, 28)
    arr = arr[None, :, :] / 255.0
    return arr

定义flask服务方法

app = Flask(__name__)
# global model, graph
@app.route('/predict', methods=['POST'])
def predict():
    b64 = request.get_data()
    arr = b64_to_ndarray(b64)
    print(arr.shape)
    with graph.as_default():
        ret = model.predict(arr)
    resp = np.array_str(np.argmax(ret, axis=1))
    return resp

启动web app

port = int(os.environ.get('PORT', 5060))
app.run(host='0.0.0.0', port=port)
# Running on http://0.0.0.0:5060/ (Press CTRL+C to quit)

测试服务调用,我们选择fashion_mnist的一张图片进行测试。

from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

im = test_images[1]
gt = test_labels[1]

对图片进行编码,因为在server端我们用到了cv2进行解码,所以客户端需要用cv2进行编码

import cv2, base64
bb = cv2.imencode('.jpg', im)
im_b64 = base64.b64encode(bb)

调用服务

import requests
import numpy as np
# 注意这里是http服务, not https。
# data参数传进图片的b64编码
ret = requests.post('http://localhost:5060/predict', data=im_b64)
# '[2]'
pred = np.fromstring(ret.text)[0]
print('Prediction right? {}'.format(pred == gt))

你可能感兴趣的:(DeepLearning)