用Docker部署TensorFlow Serving服务

2021-02-19 14:19:06 浏览数 (1)

文章目录

    • 1. 安装 Docker
    • 2. 使用 Docker 部署
    • 3. 请求服务
      • 3.1 手写数字例子
      • 3.2 猫狗分类例子

参考:

https://tf.wiki/zh_hans/deployment/serving.html#

https://tensorflow.google.cn/tfx/serving/docker

1. 安装 Docker

以下均为 centos7 环境

参考文章:docker安装等操作

2. 使用 Docker 部署

  • 拉镜像 docker pull tensorflow/serving
  • 模型路径,版本号1,2,默认加载最大数字的
  • bash 输入命令,注意路径,mymodel跟请求的代码保持一致
代码语言:javascript复制
docker run -p 8501:8501 --mount type=bind,source=/home/dnn/project/tf2,target=/models/mymodel -e MODEL_NAME=mymodel -t tensorflow/serving
  • 手写数字识别 模型代码 导出模型
代码语言:javascript复制
# 手写数字 tf 实现
import numpy as np
import tensorflow as tf

class MNistLoader():
    def __init__(self):
        data = tf.keras.datasets.mnist
        # 加载数据
        (self.train_data, self.train_label), (self.test_data, self.test_label) = data.load_data()
        # 扩展维度,灰度图1通道 [batch_size, 28, 28, chanels=1]
        self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0, axis=-1)
        self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1)
        self.train_label = self.train_label.astype(np.int32)
        self.test_label = self.test_label.astype(np.int32)
        # 样本个数
        self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]

    def get_batch(self, batch_size):
        # 从训练集里随机取出 batch_size 个样本
        idx = np.random.randint(0, self.num_train_data, batch_size)
        return self.train_data[idx, :], self.train_label[idx]

# 自定义多层感知机模型
class MLPmodel(tf.keras.Model):
    def __init__(self):
        super().__init__()
        # 除第一维以外的维度展平
        self.flatten = tf.keras.layers.Flatten()
        self.dense1 = tf.keras.layers.Dense(units=100, activation='relu')
        self.dense2 = tf.keras.layers.Dense(units=10)

    @tf.function # 计算图模式,导出需要
    def call(self, input):
        x = self.flatten(input)
        x = self.dense1(x)
        x = self.dense2(x)
        output = tf.nn.softmax(x)
        return output

num_epochs = 5
batch_size = 50
learning_rate = 1e-4

mymodel = MLPmodel()

data_loader = MNistLoader()

mymodel.compile(
    optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate),
    loss=tf.keras.losses.sparse_categorical_crossentropy,
    metrics=[tf.keras.metrics.sparse_categorical_accuracy]
)
mymodel.fit(data_loader.train_data, data_loader.train_label,
            batch_size=batch_size,epochs=num_epochs)

# 导出模型
tf.saved_model.save(mymodel, "./2")
# 载入模型
mymodel = tf.saved_model.load('./2')

res = mymodel.call(data_loader.test_data)
print(res)

3. 请求服务

3.1 手写数字例子

代码语言:javascript复制
import numpy as np
import tensorflow as tf
import json
import requests
import matplotlib.pyplot as plt


class MNistLoader():
    def __init__(self):
        data = tf.keras.datasets.mnist
        # 加载数据
        (self.train_data, self.train_label), (self.test_data, self.test_label) = data.load_data()
        # 扩展维度,灰度图1通道 [batch_size, 28, 28, chanels=1]
        self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0, axis=-1)
        self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1)
        self.train_label = self.train_label.astype(np.int32)
        self.test_label = self.test_label.astype(np.int32)
        # 样本个数
        self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]

    def get_batch(self, batch_size):
        # 从训练集里随机取出 batch_size 个样本
        idx = np.random.randint(0, self.num_train_data, batch_size)
        return self.train_data[idx, :], self.train_label[idx]


size = 6
dataloader = MNistLoader()

data = json.dumps({
    'instances': dataloader.test_data[0:size].tolist()
})

headers = {'content-type': 'application/json'}

json_response = requests.post(
    url='http://localhost:8501/v1/models/mymodel:predict',
    data=data, headers=headers
)

pred = np.array(json.loads(json_response.text)['predictions'])
print("预测结果:", np.argmax(pred, axis=-1))

# 打印图片
plt.subplots(1, size)
idx = 1
for img in dataloader.test_data[0:size]:
    plt.subplot(1, size, idx)
    plt.imshow(img)
    idx  = 1
plt.show()

输出:

代码语言:javascript复制
预测结果: [7 2 1 0 4 1]

跟图片显示一致

3.2 猫狗分类例子

模型代码

训练完后,导出模型

代码语言:javascript复制
tf.saved_model.save(model, './3')
代码语言:javascript复制
import numpy as np
import tensorflow as tf
import json
import requests
import matplotlib.pyplot as plt

test_pic = ["./dogs-vs-cats/test/1.jpg","./dogs-vs-cats/test/7.jpg"]
 # 狗1, 猫0
test_data = np.array([_decode_and_resize(f).numpy() for f in test_pic])

data = json.dumps({
    'instances': test_data.tolist()
})

headers = {'content-type': 'application/json'}

json_response = requests.post(
    url='http://localhost:8501/v1/models/mymodel:predict',
    data=data, headers=headers
)
pred = np.array(json.loads(json_response.text)['predictions'])
print("预测结果:", np.argmax(pred, axis=-1))

for img in test_data:
    plt.imshow(img)
    plt.show()

输出:

代码语言:javascript复制
预测结果: [1 0] # 狗,猫

0 人点赞