keras训练了个二分类的模型。需求是把keras模型跑到 tensorflow serving上 (TensorFlow Serving 系统用于在生产环境中运行模型)

keras模型转 tensorflow模型

我把 keras模型转tensorflow serving模型所使用的方法如下:

1、要拿到算法训练好的keras模型文件(一个HDF5文件)

该文件应该包含:

  • 模型的结构,以便重构该模型
  • 模型的权重
  • 训练配置(损失函数,优化器等)
  • 优化器的状态,以便于从上次训练中断的地方开始

2、编写 keras模型转tensorflow serving模型的代码

import pandas as pd
import os
import tensorflow as tf tf.logging.set_verbosity(tf.logging.INFO)
...
def build_model():
############
...
return model def save_model_for_production(model, version, path='prod_models'):
tf.keras.backend.set_learning_phase(1)
if not os.path.exists(path):
os.mkdir(path)
export_path = os.path.join(
tf.compat.as_bytes(path),
tf.compat.as_bytes(version))
builder = tf.saved_model.builder.SavedModelBuilder(export_path) model_input = tf.saved_model.utils.build_tensor_info(model.input)
model_output = tf.saved_model.utils.build_tensor_info(model.output) prediction_signature = (
tf.saved_model.signature_def_utils.build_signature_def(
inputs={'inputs': model_input},
outputs={'output': model_output},
method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)) with tf.keras.backend.get_session() as sess:
builder.add_meta_graph_and_variables(
sess=sess, tags=[tf.saved_model.tag_constants.SERVING],
signature_def_map={
'predict':
prediction_signature,
}) builder.save() if __name__ == '__main__':
model_file = './my_model.h5'
if (os.path.isfile(model_file)):
print('model file detected. Loading.')
model = tf.keras.models.load_model(model_file)
else:
print('No model file detected. Starting from scratch.')
model = build_model()
model.compile(loss='binary_crossentropy', optimizer="adam", metrics=['accuracy'])
model.save(model_file) model.fit(X_train, y_train, batch_size=100, epochs=1, validation_data=(X_test, y_test))
model.summary() export_path = "tf-model"
save_model_for_production(model, "1", export_path)

上面的例子将模型保存到 tf-model目录下
tf-model目录结构如下:

tf-model/
└── 1
├── saved_model.pb
└── variables
├── variables.data-00000-of-00001
└── variables.index

saved_model.pb 是能在 tensorflow serving跑起来的模型。

3、跑模型

tensorflow_model_server --port=9000 --model_name="username" --model_base_path="/data/models/tf-model/"

标准输出如下(算法模型已成功跑起来了):

Running ModelServer at 0.0.0.0:00 ...

4、客户端代码

#!/usr/bin/env python
# encoding: utf-8 """
@version: v1.0
@author: zwqjoy
@contact: zwqjoy@163.com
@site: https://blog.csdn.net/zwqjoy
@file: client
@time: 2018/6/29 15:02
""" from __future__ import print_function
from grpc.beta import implementations
import tensorflow as tf from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2
import numpy as np tf.app.flags.DEFINE_string('server', 'localhost:9000',
'PredictionService host:port')
FLAGS = tf.app.flags.FLAGS def main(_):
host, port = FLAGS.server.split(':')
channel = implementations.insecure_channel(host, int(port))
stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)
# Send request # See prediction_service.proto for gRPC request/response details.
data = np.array([4, 0, 0, 0, 1, 0, 1])
data = data.astype(np.float32) request = predict_pb2.PredictRequest()
request.model_spec.name = 'username' # 这个name跟tensorflow_model_server --model_name="username" 对应
request.model_spec.signature_name = 'predict' # 这个signature_name 跟signature_def_map 对应
request.inputs['inputs'].CopyFrom(
tf.contrib.util.make_tensor_proto(data, shape=(1, 7))) # shape跟 keras的model.input类型对应
result = stub.Predict(request, 10.0) # 10 secs timeout
print(result) if __name__ == '__main__':
tf.app.run()

客户端跑出的结果是:

outputs {
key: "output"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1
}
}
float_val: 0.976889811523
}
}
float_val: 0.976889811523 就是我们需要的结果(概率)

keras模型转 tensorflow模型的一些说明

1、 keras 保存模型

可以使用model.save(filepath)将Keras模型和权重保存在一个HDF5文件中,该文件将包含:

  • 模型的结构,以便重构该模型
  • 模型的权重
  • 训练配置(损失函数,优化器等)
  • 优化器的状态,以便于从上次训练中断的地方开始

当然这个 HDF5 也可以是用下面的代码生成

from keras.models import load_model
model.save('my_model.h5')

2、 keras 加载模型

keras 加载模型(中间部分代码省略了):

import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
from keras.models import load_model
# 载入数据
(x_train,y_train),(x_test,y_test) = mnist.load_data()
# (60000,28,28)
print('x_shape:',x_train.shape)
# (60000)
print('y_shape:',y_train.shape)
# (60000,28,28)->(60000,784)
x_train = x_train.reshape(x_train.shape[0],-1)/255.0
x_test = x_test.reshape(x_test.shape[0],-1)/255.0
# 换one hot格式
y_train = np_utils.to_categorical(y_train,num_classes=10)
y_test = np_utils.to_categorical(y_test,num_classes=10) # 载入模型
model = load_model('model.h5') # 评估模型
loss,accuracy = model.evaluate(x_test,y_test) print('\ntest loss',loss)
print('accuracy',accuracy) # 训练模型
model.fit(x_train,y_train,batch_size=64,epochs=2) # 评估模型
loss,accuracy = model.evaluate(x_test,y_test) print('\ntest loss',loss)
print('accuracy',accuracy) # 保存参数,载入参数
model.save_weights('my_model_weights.h5')
model.load_weights('my_model_weights.h5')

keras 模型转tensorflow serving 模型的一些坑

希望能让新手少走一些弯路

坑1:过时的生成方法

有些方法已经过时了(例如下面这种):

from tensorflow_serving.session_bundle import exporter

export_path = ... # where to save the exported graph
export_version = ... # version number (integer) saver = tf.train.Saver(sharded=True)
model_exporter = exporter.Exporter(saver)
signature = exporter.classification_signature(input_tensor=model.input,
scores_tensor=model.output)
model_exporter.init(sess.graph.as_graph_def(),
default_graph_signature=signature)
model_exporter.export(export_path, tf.constant(export_version), sess)

如果使用这种过时的方法,用tensorflow serving 跑模型的时候会提示:

WARNING:tensorflow:From test.py:107: Exporter.export (from tensorflow.contrib.session_bundle.exporter) is deprecated and will be removed after 2017-06-30.
Instructions for updating:
No longer supported. Switch to SavedModel immediately.

从warning中 显然可以知道这种方法要被抛弃了,不再支持这种方法了, 建议我们转用 SaveModel方法。

填坑大法: 使用 SaveModel

def save_model_for_production(model, version, path='prod_models'):
tf.keras.backend.set_learning_phase(1)
if not os.path.exists(path):
os.mkdir(path)
export_path = os.path.join(
tf.compat.as_bytes(path),
tf.compat.as_bytes(version))
builder = tf.saved_model.builder.SavedModelBuilder(export_path) model_input = tf.saved_model.utils.build_tensor_info(model.input)
model_output = tf.saved_model.utils.build_tensor_info(model.output) prediction_signature = (
tf.saved_model.signature_def_utils.build_signature_def(
inputs={'inputs': model_input},
outputs={'output': model_output},
method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)) with tf.keras.backend.get_session() as sess:
builder.add_meta_graph_and_variables(
sess=sess, tags=[tf.saved_model.tag_constants.SERVING],
signature_def_map={
'predict':
prediction_signature,
}) builder.save()

参考:

https://www.jianshu.com/p/91aae37f1da6 

Deploying Keras model on Tensorflow Serving with GPU support

https://github.com/amir-abdi/keras_to_tensorflow

Deploying Keras model on Tensorflow Serving--的更多相关文章

  1. Problem after converting keras model into Tensorflow pb - 将keras模型转换为Tensorflow pb后的问题

    I'm using keras 2.1.* with tensorflow 1.13.* backend. I save my model during training with .h5 forma ...

  2. 学习笔记TF067:TensorFlow Serving、Flod、计算加速,机器学习评测体系,公开数据集

    TensorFlow Serving https://tensorflow.github.io/serving/ . 生产环境灵活.高性能机器学习模型服务系统.适合基于实际数据大规模运行,产生多个模型 ...

  3. tensorflow 2.0 技巧 | 自定义tf.keras.Model的坑

    自定义tf.keras.Model需要注意的点 model.save() subclass Model 是不能直接save的,save成.h5,但是能够save_weights,或者save_form ...

  4. tensorflow 模型保存与加载 和TensorFlow serving + grpc + docker项目部署

    TensorFlow 模型保存与加载 TensorFlow中总共有两种保存和加载模型的方法.第一种是利用 tf.train.Saver() 来保存,第二种就是利用 SavedModel 来保存模型,接 ...

  5. 通过Docker构建TensorFlow Serving

    最近在用Docker搭建TensorFlow Serving, 在查阅了官方资料后,发现其文档内有不少冗余的步骤,便一步步排查,终于找到了更简单的Docker镜像构建方法.这里有两种方式: 版本一: ...

  6. tensorflow serving

    1.安装tensorflow serving 1.1确保当前环境已经安装并可运行tensorflow 从github上下载源码 git clone --recurse-submodules https ...

  7. tensorflow serving 之minist_saved_model.py解读

    最近在学习tensorflow serving,但是就这样平淡看代码可能觉得不能真正思考,就想着写个文章看看,自己写给自己的,就像自己对着镜子演讲一样,写个文章也像自己给自己讲课,这样思考的比较深,学 ...

  8. Tensorflow Serving 模型部署和服务

    http://blog.csdn.net/wangjian1204/article/details/68928656 本文转载自:https://zhuanlan.zhihu.com/p/233614 ...

  9. Tensorflow Serving Docker compose 部署服务细节(Ubuntu)

    [摘要] Tensorflow Serving 是tf模型持久化的重要工具,本篇介绍如何通过Docker compose搭建并调试TensorFlow Serving TensorFlow Servi ...

随机推荐

  1. Django模板继承和引用

    一.模板继承 1.模板继承可以在创建一个基本“骨架”后,被其它子模板继承并覆盖,通过修改基础模板可以修改子模板中的所有框架 2.在模板teacher文件夹下创建基础模板 {% block xxx}与{ ...

  2. #pragma常用预处理指令

    #pragma pack(1):1字节对齐#pragma once:指定头文件被编译一次#pragma message("message"):编译时输出message文本#prag ...

  3. 爬虫学习笔记-urllib库

    urllib库是python中一个最基本的网络请求库.可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据. urlopen函数:在python3的urllib库中,所有和网络 ...

  4. STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收

    参考资料:1.ST HAL库官网资料 2.https://blog.csdn.net/u014470361/article/details/79206352#comments 一.STM32CubeM ...

  5. azure cosmos db (mongo DB)

    使用.net mongo的操作类操作azure(微软云)cosmosdb时,发现在做delete的操作的时候可以传一个文档对象,但是最后这个文档会解析成具体的sql语句,而当文档特别大时这样就出先了转 ...

  6. U-Boot bootargs简析

    Linux内核启动时需要一些配置信息,如根文件系统的类型.flash分区情况.串口终端的编号.内存的使用情况等等,而由于U-Boot和Linux Kernel的镜像是独立的两个文件,所以只能两者约定好 ...

  7. rails5 后台入门(api mode)

    1. Installation (Centos为例) 1.1安装rvm (http://rvm.io/) gpg2 --recv-keys 409B6B1796C275462A1703113804BB ...

  8. 在码云(gitee)上展开程序类课程教学

    码云主要提供了源代码管理(Git/SVN)功能,最近又推出了高校版让普通老师也能利用起来以供教学使用. 学生与老师不仅能利用其管理代码,更重要的是我们的程序教学能通过对git的使用来引入业界流行的软件 ...

  9. vs2012升级vs2017后的一些坑

    异常信息:未能加载文件或程序集"System.Web.Helpers... 未能加载文件或程序集"System.Web.Helpers, Version=2.0.0.0, Cult ...

  10. Android开发 - 掌握ConstraintLayout(十一)复杂动画!如此简单!

    介绍 本系列我们已经介绍了ConstraintLayout的基本用法.学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章. 使用 ...