赶鸭子上架搞机器学习,此系列希望能够帮助新手入门,或者其他开发人员快速上手机器学习,并用在项目中(我们刚开始可能是“掉包侠”,但是对于后续理论的学习也是必不可少的喔)
为什么是0.1而不是0呢?应为我是从其他语言体系转到机器学习中,以前积累的一些其他经验可以快速帮助我们上手,所以是0.1。
如果本文对你有所帮助,欢迎评论点赞收藏,如有错误,欢迎指正。
从零点一开始机器学习之晦涩难懂的各种概念
从零点一开始机器学习之Win10 64位下安装Cuda+Cudnn
从零点一开始机器学习之GPU运算性能和CPU性能对比(GPU算力表)
从零点一开始机器学习之TF1.0版本HDF5转换为saved_model
从零点一开始机器学习之HDF5模型发布到tensorflow/serving
Python中tensorflow Import使用错误集合2035298)
在tf1.0版本系列下我们应该如何转换hdf5到saved_model形式呢?如下所示,此代码未在1.0环境下运行验证。
环境说明 环境和版本很重要,大量的博客没有环境说明和版本介绍,对新人很不友好
tensorflow版本:tf2.0系列
vggmodel_22-0.15-0.95.hdf5:
h52pb_1.py代码
# -*- coding: utf-8 -*-
import os
import tensorflow as tf
from tensorflow.python.framework import graph_util
from tensorflow.python.framework import graph_io
from pathlib import Path
from absl import app
from absl import flags
from absl import logging
import keras
from keras import backend as K
from keras.models import model_from_json
from keras_contrib.layers import CRF
from keras_contrib.losses import crf_loss
from keras_contrib.metrics import crf_accuracy
from keras_bert import get_custom_objects
custom_objects = get_custom_objects()
for key, value in {'CRF': CRF, 'crf_loss': crf_loss, 'crf_accuracy': crf_accuracy}.items():
custom_objects[key] = value
K.set_learning_phase(0)
FLAGS = flags.FLAGS
flags.DEFINE_string('input_model', "./h5_model/vggmodel_22-0.15-0.95.hdf5", 'Path to the input model.')
flags.DEFINE_string('input_model_json', None, 'Path to the input model '
'architecture in json format.')
flags.DEFINE_string('output_model', "./pb_model/example_ner.pb", 'Path where the converted model will '
'be stored.')
flags.DEFINE_boolean('save_graph_def', False,
'Whether to save the graphdef.pbtxt file which contains '
'the graph definition in ASCII format.')
flags.DEFINE_string('output_nodes_prefix', None,
'If set, the output nodes will be renamed to '
'`output_nodes_prefix`+i, where `i` will numerate the '
'number of of output nodes of the network.')
flags.DEFINE_boolean('quantize', False,
'If set, the resultant TensorFlow graph weights will be '
'converted from float into eight-bit equivalents. See '
'documentation here: '
'https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms')
flags.DEFINE_boolean('channels_first', False,
'Whether channels are the first dimension of a tensor. '
'The default is TensorFlow behaviour where channels are '
'the last dimension.')
flags.DEFINE_boolean('output_meta_ckpt', False,
'If set to True, exports the model as .meta, .index, and '
'.data files, with a checkpoint file. These can be later '
'loaded in TensorFlow to continue training.')
flags.mark_flag_as_required('input_model')
flags.mark_flag_as_required('output_model')
def load_model(input_model_path, input_json_path):
if not Path(input_model_path).exists():
raise FileNotFoundError(
'Model file `{}` does not exist.'.format(input_model_path))
try:
# 下面一行已经修改,在改回普通的Keras加载模型时,需要去掉custom_objects
model = keras.models.load_model(input_model_path, custom_objects=custom_objects)
return model
except FileNotFoundError as err:
logging.error('Input mode file (%s) does not exist.', FLAGS.input_model)
raise err
except ValueError as wrong_file_err:
if input_json_path:
if not Path(input_json_path).exists():
raise FileNotFoundError(
'Model description json file `{}` does not exist.'.format(
input_json_path))
try:
model = model_from_json(open(str(input_json_path)).read())
model.load_weights(input_model_path)
return model
except Exception as err:
logging.error("Couldn't load model from json.")
raise err
else:
logging.error(
'Input file specified only holds the weights, and not '
'the model definition. Save the model using '
'model.save(filename.h5) which will contain the network '
'architecture as well as its weights. If the model is '
'saved using model.save_weights(filename), the flag '
'input_model_json should also be set to the '
'architecture which is exported separately in a '
'json format. Check the keras documentation for more details '
'(https://keras.io/getting-started/faq/)')
raise wrong_file_err
def main(args):
logging.info("begin====================================================")
# If output_model path is relative and in cwd, make it absolute from root
output_model = FLAGS.output_model
if str(Path(output_model).parent) == '.':
output_model = str((Path.cwd() / output_model))
output_fld = Path(output_model).parent
output_model_name = Path(output_model).name
output_model_stem = Path(output_model).stem
output_model_pbtxt_name = output_model_stem + '.pbtxt'
# Create output directory if it does not exist
# print (Path(output_model).parent)
if not os.path.exists(str(Path(output_model).parent)):
Path(output_model).parent.mkdir(parents=True)
if FLAGS.channels_first:
K.set_image_data_format('channels_first')
else:
K.set_image_data_format('channels_last')
model = load_model(FLAGS.input_model, FLAGS.input_model_json)
input_node_names = [node.op.name for node in model.inputs]
logging.info('Input nodes names are: %s', str(input_node_names))
# TODO(amirabdi): Support networks with multiple inputs
orig_output_node_names = [node.op.name for node in model.outputs]
if FLAGS.output_nodes_prefix: # 给模型节点编号
num_output = len(orig_output_node_names)
pred = [None] * num_output
converted_output_node_names = [None] * num_output
# Create dummy tf nodes to rename output
for i in range(num_output):
converted_output_node_names[i] = '{}{}'.format(
FLAGS.output_nodes_prefix, i)
pred[i] = tf.identity(model.outputs[i],
name=converted_output_node_names[i])
else:
converted_output_node_names = orig_output_node_names
logging.info('Converted output node names are: %s',
str(converted_output_node_names))
sess = K.get_session()
if FLAGS.output_meta_ckpt: # 让转化的模型可以继续被训练
saver = tf.train.Saver()
saver.save(sess, str(output_fld / output_model_stem))
if FLAGS.save_graph_def: # 以ascii形式存储模型
tf.train.write_graph(sess.graph.as_graph_def(), str(output_fld),
output_model_pbtxt_name, as_text=True)
logging.info('Saved the graph definition in ascii format at %s',
str(Path(output_fld) / output_model_pbtxt_name))
if FLAGS.quantize: # 将权重从float转为八位比特
from tensorflow.tools.graph_transforms import TransformGraph
transforms = ["quantize_weights", "quantize_nodes"]
transformed_graph_def = TransformGraph(sess.graph.as_graph_def(), [],
converted_output_node_names,
transforms)
constant_graph = graph_util.convert_variables_to_constants(
sess,
transformed_graph_def,
converted_output_node_names)
else: # float形式存储权重
constant_graph = graph_util.convert_variables_to_constants(
sess,
sess.graph.as_graph_def(),
converted_output_node_names)
graph_io.write_graph(constant_graph, str(output_fld), output_model_name,
as_text=False)
logging.info('Saved the freezed graph at %s',
str(Path(output_fld) / output_model_name))
if __name__ == "__main__":
app.run(main)
pb2saved_1.py
# -*- coding: utf-8 -*-
import os
import tensorflow as tf
from tensorflow.python.saved_model import signature_constants
from tensorflow.python.saved_model import tag_constants
from keras_bert import get_custom_objects
from keras_contrib.layers import CRF
from keras_contrib.losses import crf_loss
from keras_contrib.metrics import crf_accuracy
from keras.models import load_model
custom_objects = get_custom_objects()
for key, value in {'CRF': CRF, 'crf_loss': crf_loss, 'crf_accuracy': crf_accuracy}.items():
custom_objects[key] = value
export_dir = './pb_model/1'
graph_pb = './pb_model/vggmodel_22-0.15-0.95.pb'
model = load_model('./h5_model/vggmodel_22-0.15-0.95.hdf5', custom_objects=custom_objects)
builder = tf.compat.v1.saved_model.builder.SavedModelBuilder(export_dir)
with tf.gfile.GFile(graph_pb, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
sigs = {}
with tf.Session(graph=tf.Graph()) as sess:
tf.import_graph_def(graph_def, name="")
g = tf.get_default_graph()
sigs[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY] = \
tf.saved_model.signature_def_utils.predict_signature_def(
inputs={"input_1": g.get_operation_by_name('input_1').outputs[0], "input_2": g.get_operation_by_name('input_2').outputs[0]},
outputs={"output": g.get_operation_by_name('crf_1/one_hot').outputs[0]}
)
builder.add_meta_graph_and_variables(sess,
[tag_constants.SERVING],
signature_def_map = sigs)
builder.save()
from keras_contrib.layers import CRF报错,明显包不存在
pip安装一个
pip install git+https://www.github.com/keras-team/keras-contrib.git
很慢,而且可能报错timeout,切换github国内镜像
把 github.com 替换为 github.com.cnpmjs.org,其余保持不变,速度直接起飞,安装完成后可能需要重启VsCode,才能去掉波浪线。
2.0版本不兼容1.0版本代码
将tf.saved_model.builder.SavedModelBuilder(export_dir)
修改为builder = tf.compat.v1.saved_model.builder.SavedModelBuilder(export_dir)
参考连接传送门https://tensorflow.google.cn/versions/r1.15/api_docs/python/tf/saved_model/Builder
博文参考:https://blog.csdn.net/jclian91/article/details/112712948