从零点一开始机器学习之HDF5模型发布到tensorflow/serving

从零点一开始机器学习之HDF5模型发布到tensorflow/serving

赶鸭子上架搞机器学习,此系列希望能够帮助新手入门,或者其他开发人员快速上手机器学习,并用在项目中(我们刚开始可能是“掉包侠”,但是对于后续理论的学习也是必不可少的喔)
为什么是0.1而不是0呢?应为我是从其他语言体系转到机器学习中,以前积累的一些其他经验可以快速帮助我们上手,所以是0.1。
如果本文对你有所帮助,欢迎评论点赞收藏,如有错误,欢迎指正。

系列文章目录

从零点一开始机器学习之晦涩难懂的各种概念
从零点一开始机器学习之Win10 64位下安装Cuda+Cudnn
从零点一开始机器学习之GPU运算性能和CPU性能对比(GPU算力表)
从零点一开始机器学习之TF1.0版本HDF5转换为saved_model
从零点一开始机器学习之HDF5模型发布到tensorflow/serving
Python中tensorflow Import使用错误集合
Python中使用Flask:Docker发布Flask API


前言

我们基于keras训练生成了一个.hdf5的模型数据,如果将其部署,让其他用户调用呢?那么tensorflow/serving可能是一个不错的选择
环境说明 环境和版本很重要,大量的博客没有环境说明和版本介绍,对新人很不友好
Python版本:Python36
tensorflow版本:tensorflow-cpu 2.6.0
tensorflow/serving版本:最新cpu版本
docker版本:Docker version 19.03.12, build 48a66213fe

一、HDF5模型转换

2.0版本转换

hdf5模型不支持直接在tensorflow/serving环境下部署,我们首先需要将.hdf5模型转换为saved_model形式的模型。
由于tensorflow2.0版本对1.0版本系列的不兼容,导致了1.0版本的转换方法和2.0版本的方法不同,由于博主使用的是2.0系列,那么先说2.0系列的转换,超级简单(比1.0)

import tensorflow as tf
tf.keras.backend.clear_session()
hdf5_model = tf.keras.models.load_model("./h5_model/vggmodel_29-0.09-0.97.hdf5")#hdf5模型路径
hdf5_model.save("./wi/1",save_format='tf')#saved_model模型存储路径 1为版本号,如果现在不写,后面也需要手动创建

就这样我们就有一个saved_model形式的模型了,我们看看模型包含什么内容

F:\WI
└─1
    │  keras_metadata.pb
    │  saved_model.pb
    │  
    ├─assets
    └─variables
            variables.data-00000-of-00001
            variables.index

1就是我们的版本号,在进行部署的时候,指定模型路径只需要精确到saved_model_dir,tf.serving会自动选择版本最大的模型进行服务

1.0版本转换

1.0版本的转换就要复杂和麻烦的多了,需要先将hdf5模型转换为pd模型,在将pb模型转换为saved_model形式模型
转换传送门从零点一开始机器学习之TF1.0版本HDF5转换为saved_model

二、基于Docker的tensorflow/serving 服务准备

1.docker环境搭建

docker基础传送门
docker版本

[root@localhost ~]# docker -v
Docker version 19.03.12, build 48a66213fe

2.tensorflow/serving镜像拉取

拉取tensorflow/serving镜像,cpu版本的可以直接拉取tensorflow/serving,docker会自动拉取latest版本

docker pull tensorflow/serving

查看拉取的镜像结果

[root@localhost ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tensorflow/serving   latest              e874bf5e4700        8 months ago        406MB

3.官方demo运行

我们先不直接发布我们自己的模型,先发布一个官方的模型看看是否成功
下载官方代码

mkdir -p /tmp/tfserving
cd /tmp/tfserving
git clone https://github.com/tensorflow/serving

下载完成后,查看对应目录

[root@localhost tfserving]# cd /tmp/tfserving/serving/
[root@localhost serving]# ls
AUTHORS  CONTRIBUTING.md  LICENSE  README.md  RELEASE.md  tensorflow_serving  third_party  tools  WORKSPACE

启动一个demo的容器

docker run -p 8502:8501 --mount type=bind,source=/tmp/tfserving/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu,target=/models/half_plus_two -e MODEL_NAME=half_plus_two -t tensorflow/serving &

把/tmp/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu路径挂载到/models/half_plus_two,这样tensorflow_serving就可以加载models下的模型了,然后开放内部8501的http接口。更多参数含义参考docker参数含义。
测试模型其实就是 y = 0.5 * x + 2。即输入一个数,输出是对应的y
运行成功
在这里插入图片描述

docker ps 查看运行效果
在这里插入图片描述
测试一下
在这里插入图片描述

三、发布我们自己的模型

1.saved_model模型上传

将我们的转换后的saved_model模型上传的服务器中,博主路径为


[root@localhost llpcode]# cd /home/llpcode/wi/
[root@localhost wi]# ls
1

2.启动基于模型的tensorflow/serving容器

接下来就是将我们自己的模型挂载到tensorflow/serving镜像中,并启动一个容器,tensorflow/serving有两种调用方式一种是grpc(端口8500),一种是api(端口8501),我们选择api模式,
启动容器命令如下:

docker run -p 8503:8501 --mount type=bind,source=/home/llpcode/wi,target=/models/wwxci -e MODEL_NAME=wwxci -t tensorflow/serving --model_base_path=/models/wwxci/ &

我们的映射端口:8503
模型路径:source=/home/llpcode/wi(不含版本号)
模型名称:wwxci(等会请求api时名称)
SavedModel格式模型的文件夹绝对地址(不含版本号) :–model_base_path=/models/wwxci/
启动成功后可以用docker ps 查看正在运行的容器。

a.查看模型概况

浏览器访问:http://192.168.xxx.xxx:8503/v1/models/wwxci

{
 "model_version_status": [
  {
   "version": "1",
   "state": "AVAILABLE",
   "status": {
    "error_code": "OK",
    "error_message": ""
   }
  }
 ]
}

b. 查看模型metadata 数据情况:

浏览器访问:http://192.168.50.137:8503/v1/models/wwxci/metadata
{
“model_spec”:{
“name”: “wwxci”,
“signature_name”: “”,
“version”: “1”
}
,
“metadata”: {“signature_def”: {
“signature_def”: {
“serving_default”: {
“inputs”: {
“image_input”: {
“dtype”: “DT_FLOAT”,
“tensor_shape”: {
“dim”: [
{
“size”: “-1”,
“name”: “”
},
{
“size”: “64”,
“name”: “”
},
{
“size”: “64”,
“name”: “”
},
{
“size”: “3”,
“name”: “”
}
],
“unknown_rank”: false
},
“name”: “serving_default_image_input:0”
}
},
“outputs”: {
“predictions”: {
“dtype”: “DT_FLOAT”,
“tensor_shape”: {
“dim”: [
{
“size”: “-1”,
“name”: “”
},
{
“size”: “17”,
“name”: “”
}
],
“unknown_rank”: false
},
“name”: “StatefulPartitionedCall:0”
}
},
“method_name”: “tensorflow/serving/predict”
},
“__saved_model_init_op”: {
“inputs”: {},
“outputs”: {
“__saved_model_init_op”: {
“dtype”: “DT_INVALID”,
“tensor_shape”: {
“dim”: [],
“unknown_rank”: true
},
“name”: “NoOp”
}
},
“method_name”: “”
}
}
}
}
}

3.模型测试

test.py代码,部分敏感信息以处理,结合自己模型

import json,requests
import cv2                                    
import numpy as np
import time

label_dict21={0:['分类1','insuracnce'], 1:['分类2','banflow'],2:['分类3','certificates'], 3:['分类4','dobule']}#图像分类 中文对应字典 ,需要做对应调整
def LoadImage(image_path):
    img = cv2.imread(image_path)
    img = cv2.resize(img, dsize = (64, 64), interpolation = cv2.INTER_AREA)
    img = img.astype("float32") / 255.0
    return np.array(img[:, :, :3])

img=LoadImage("./result/123.jpg")
data = json.dumps({"signature_name": "serving_default", "instances": np.array([img]).tolist()})
headers = {"content-type": "application/json"}
start = time.clock()


json_response = requests.post('http://192.168.xxx.xxx:8503/v1/models/wwxci:predict', 
        data=data, headers=headers)#访问地址
end = time.clock()
print("运行耗时"+str(end - start))
predictions = json.loads(json_response.text)["predictions"]
print(json_response.text)
res = np.argmax(predictions)
print(label_dict21[int(res)][0],predictions[0][np.argmax(predictions)])

运行效果
在这里插入图片描述

四、模型的持续热更新

现在,我们从新构建一个模型版本2,然后上传到模型路径中,解压模型

[root@localhost wi]# ls
1  2  2.tar.gz

这个时候我们不需要重启,直接查看模型概况
浏览器访问:http://192.168.xxx.xxx:8503/v1/models/wwxci
这样模型就在不重启的情况的下进行了热更新,版本1结束,版本2可用

{
 "model_version_status": [
  {
   "version": "2",
   "state": "AVAILABLE",
   "status": {
    "error_code": "OK",
    "error_message": ""
   }
  },
  {
   "version": "1",
   "state": "END",
   "status": {
    "error_code": "OK",
    "error_message": ""
   }
  }
 ]
}

后记

到此我们就完成了一个最简单的模型发布

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值