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. vue.js报错:Module build failed: Error: No parser and no file path given, couldn't infer a parser.

    ERROR Failed to compile with 2 errors 12:00:33 error in ./src/App.vue Module build failed: Error: No ...

  2. 2018-04-10 我的GitHub诞生的日子,欢迎大家吐槽批评

    我的GitHub,诞生的日子,欢迎大家吐槽与批评,嘻嘻 首先是自己想刷一下LeetCode上的代码,其次创建了自己的读书笔记以及面试经验与教训 下边是仓库的Git链接,欢迎大家的批评与修正,谢谢: L ...

  3. bootstrap中的dropdown组件扩展hover事件

    bootstrap的下拉组件,需要点击click时,方可展示下拉列表.因此对于喜欢简单少操作的大家来说,点击一下多少带来不便,因此,引入hover监听,鼠标经过自动展示下拉框.其实在bootstrap ...

  4. Exp5 MSF基础运用 20154320 李超

    实验后回答问题 用自己的话解释什么是exploit,payload,encode. exploit:起运输的作用,将数据传输到对方主机. payload:其实就是指装载的“具体内容”.就相当于shel ...

  5. vue webpack打包后 iconfont引入路径不对

    vue webpack打包后 iconfont引入路径不对 { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', option ...

  6. 可遇不可求的Question之Mysql在不重启服务的情况下修改运行时变量篇

    比方说在一些实际生产环境中,想改个MYSQL的配置,但是又不想停止服务重起MYSQL,有什么办法呢?使用SET命令可以做到,请看下面几个例子: 1.设置key_buffer_size的大小为10M. ...

  7. 用JavaScript制作简单的计算器

    <html > <head> <title>简单计算器</title> <style type="text/css"> ...

  8. react native (2) 嵌入h5页面 设置顶部导航

    嵌入h5页面 1.新建好页面 2. import { WebView } from 'react-native'; 3.<WebView source={{ uri: '要引入的页面路径' }} ...

  9. repo跟svn的区别

    Git与SVN区别 Git和SVN正好相反,git提倡开发时拉分支,各干各的,相互独立,发版本时打标签:而svn呢,平时大家都在主干上干活,发版本时拉个分支,所以呢,svn经常会提交冲突,经常要合并代 ...

  10. Python之路【第二篇】计算机组成

    硬件组成:输入单元.输出单元.中央处理单元.存储单元 南桥:I/O操作 北桥:CPU操作   0/1的单位称为bit(位) bit是计算机中能识别的最小单位. 字节是计算机中最小的存储单位. 8bit ...