ckp模型和冻结网络的pb和saved_model的一些调用方法(部署前查看一些值时候正确,如签名,模型的名字)
重载模型:
导入对应的模型,然后查看张量图
import tensorflow as tf
with tf.Session() as sess:
saver = tf.train.import_meta_graph('ckp-10000.meta')
saver.restore(sess, 'ckp-10000')
tensor_list = tf.get_default_graph().as_graph_def().node
for i in tensor_list:
print(i.name)
# 如果是没有ckp后缀, 只有这三个model-1000.data**/model-10000.index/model-10000.meta文件的
with tf.Session() as sess:
saver = tf.train.import_meta_graph('./model/new_cw2vec_ATT_GRU_model-10000.meta')
saver.restore(sess, tf.train.latest_checkpoint('./model/'))
tensor_list = tf.get_default_graph().as_graph_def().node
print(tensor_list)
for i in tensor_list:
print(i.name)
1.查看打印出的张量名在与代码对比,找到预测的张量名(即时我们在代码中没有定义相应的操作名,tensorflow会帮我们定义)我们这里进行预测的得到结果的是metrics/ArgMax
2.利用分词表进行sentence_to_id
的操作,然后feed数据
相关代码如下
sentence = '首先和评论手机,手机质感和流畅的还是很不错,系统很好就是新系统bug有点多,总体评价来说还是很不错的一个购物外形外观延用了苹果手机的一惯外形和材质,拿在手里很有质感和重量,去实体门店看过了,经常断货,没想到京东有,就果断拍下了!择这款手机的主要原因是它的 屏幕介于苹果11PRO和11PRO MAX 之间,对于我来讲,简直是为我定制的一样,怎样挑剔的我,都无话可说了!屏幕的分辨率也是很棒的,音效我感觉比以前的苹果手机也有进步。拍照效果一如既往的好啊,像素高的超前,还增加了广角拍摄,十分满意!运行速度流畅,反应速度很快,完美!'
import jieba
import numpy as np
sentence_list = jieba.cut(sentence)
words = ' '.join([word for word in sentence_list])
id_words = vocab.sentence_to_id(words)
id_words = id_words[0: 120]
padding_num = 120 - len(id_words)
id_words = id_words + [0 for _ in range(padding_num)]
id_words_list = []
for _ in range(100):
id_words_list.append(id_words)
print(np.asarray(id_words_list, dtype=np.int32).shape)
word_np = np.asarray(id_words_list, dtype=np.int32)
simple_word = np.asarray(id_words)
lstm_graph_path = r'.\deep_learn\jd_deep_learn\jd_lstm_runout\lstm_model\ckp-10000.meta'
lstm_model_path = r'.\deep_learn\jd_deep_learn\jd_lstm_runout\lstm_model\ckp-10000'
with tf.Session() as sess:
saver = tf.train.import_meta_graph(lstm_graph_path)
saver.restore(sess, lstm_model_path)
tensor_inputs = tf.get_default_graph().get_tensor_by_name('Placeholder:0')
tensor_outpus = tf.get_default_graph().get_tensor_by_name('metrics/ArgMax:0')
tensor_keep_prob = tf.get_default_graph().get_tensor_by_name('keep_prob:0')
pred = sess.run(tensor_outpus, feed_dict={tensor_inputs: word_np, tensor_keep_prob:1})
print(pred[0])
pb格式有两种形式,一种是冻结网络pb,另一种是saved_model
读取两种不同的pb模型的参考文章
ckpt 格式转 pb 格式
参考文章
from tensorflow.python.framework import graph_util
with tf.Session() as sess:
saver = tf.train.import_meta_graph(lstm_graph_path)
saver.restore(sess, lstm_model_path)
graph_def = tf.get_default_graph().as_graph_def()
output_graph_def = graph_util.convert_variables_to_constants(
sess, graph_def,['metrics/ArgMax']
)
with tf.gfile.GFile('.\deep_learn\jd_deep_learn\jd_lstm_runout\lstm_model\jd_comment_lstm_model.pb', 'w') as gf:
serialized_graph = output_graph_def.SerializeToString()
gf.write(serialized_graph)
冻结网络pb模型预测
def load_model(model_path):
if not os.path.exists(model_path):
raise ValueError("model is not exists")
model_graph = tf.Graph()
with model_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(model_path, 'rb') as gf:
serialized_data = gf.read()
od_graph_def.ParseFromString(serialized_data)
tf.import_graph_def(od_graph_def, name='')
return model_graph
model_path = r'.\deep_learn\jd_deep_learn\jd_lstm_runout\lstm_model\jd_comment_lstm_model.pb'
model_graph = load_model(model_path)
inputs_x = model_graph.get_tensor_by_name('Placeholder:0')
outputs = model_graph.get_tensor_by_name('metrics/ArgMax:0')
keep_prob = model_graph.get_tensor_by_name('keep_prob:0')
with model_graph.as_default():
with tf.Session(graph=model_graph) as sess:
for i in model_graph.as_graph_def().node:
print(i.name)
pred = sess.run(outputs, feed_dict={inputs_x: word_np, keep_prob:1})
print(pred[0])
通过tensorflow_serving部署,serving需要的是saved_model模型
参考文章1
参考文章2
部署文件pd和variables需要在一个版本号的文件夹内,docker部署的是挂载版本号文件夹的上一层文件,可能是因为在模型转换的过程中,没有添加版本号。
查看saved_model的签名
saved_model_cli show --dir=./ --all
这样会出现模型的签名和输入和输出
当我在使用tf.saved_model.signature_def_utils.build_signature_def()
函数,method_name
为自定义时,部署时,始终无法调用成功
当使用tensorflow定义的签名时,在调用时出现的gRPC
服务器不可以用的情况,在使用docker
官网的tensorflow/serving:1.13.1
的images
回归例子,还是出现同样的错误,但是使用curl
命令使用RESTful API
时能够调用成功。
docker部署时使用自己的签名
参考文章
docker run -p 8051:8501 --mount type=bind,source=/home/perfectman/jd_comment_cnn/, \
target=/models/jd_comment_cnn \
-t --entrypoint=tensorflow_model_server tensorflow/serving:1.13.1 \
--port=8501 --model_name=jd_comment_cnn \
--model_base_path=/models/jd_comment_cnn \
--saved_model_tags=jd_comment_cnn &
使用下面方法进行查看签名,模型名时候正确
from tensorflow import saved_model
with tf.Session(graph=tf.Graph()) as sess:
MetaGraphDef = saved_model.loader.load(sess,['jd_comment_cnn'], export_dir=".\deep_learn\jd_deep_learn\jd_cnn_runout\jd_comment_cnn_serving")
SignatureDef_d = MetaGraphDef.signature_def
SignatureDef = SignatureDef_d['jd_comment_cnn_signature']
# graph = tf.get_default_graph()
# x = sess.graph.get_tensor_by_name("Placeholder:0")
# y = sess.graph.get_tensor_by_name("metrics/ArgMax:0")
# keep_prob2 = sess.graph.get_tensor_by_name('keep_prob:0')
x_TensorInfo = SignatureDef.inputs['inputs']
keep_prob2_TensorInfo = SignatureDef.inputs['keep_prob']
y_TensorInfo = SignatureDef.outputs['outputs']
x = saved_model.utils.get_tensor_from_tensor_info(x_TensorInfo, sess.graph)
keep_prob2 = saved_model.utils.get_tensor_from_tensor_info(keep_prob2_TensorInfo, sess.graph)
y = saved_model.utils.get_tensor_from_tensor_info(y_TensorInfo, sess.graph)
pred = sess.run(y, feed_dict={x: word_np, keep_prob2:1})
print(pred[0])
在使用Python
的requests
包进行对tensorflow_serving
调用时,始终无法成功错误如下:
在使用pycharm自带的REST Client调用时能够成功
在使用docker部署调用不成功之后,再尝试用tensorflow_serving直接部署
调用成功
**原因有可能是因为docker images 版本的问题,下面尝试最新的tensorflow_serving:latest
**镜像
最终发现是端口的问题
docker代码
docker run -p 8500:8500 --mount type=bind,source=/home/perfectman/jd_comment_lstm_predict,target=/models/jd_comment_lstm_predict -e MODEL_NAME=jd_comment_lstm_predict -t tensorflow/serving:1.13.1 &
这里应该选择8500端口而不是8501,因为在docker
运行时,tensorflow/serving
的gRPC API
默认使用的是8500这个端口,如果没有改变使用参数去改变docker
内部的运行端口的话,就不需要把映射端口改成8051
下面是tensorflow/serving部署的一些文章
参考文章1
参考文章2
参考文章3
参考文章4
参考文章5
接下来解决next_batch的问题
在训练代码中,使用的是100维度,但是我们在实际预测的时候使用是维度为1的单条。