def regression_signature_def(examples, predictions): """Creates regression signature from given examples and predictions. Args: examples: `Tensor`. predictions: `Tensor`. Returns: A regression-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('Regression examples cannot be None.') if not isinstance(examples, ops.Tensor): raise ValueError('Regression examples must be a string Tensor.') if predictions is None: raise ValueError('Regression predictions cannot be None.') input_tensor_info = utils.build_tensor_info(examples) if input_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Regression examples must be a string Tensor.') signature_inputs = {signature_constants.REGRESS_INPUTS: input_tensor_info} output_tensor_info = utils.build_tensor_info(predictions) if output_tensor_info.dtype != types_pb2.DT_FLOAT: raise ValueError('Regression output must be a float Tensor.') signature_outputs = {signature_constants.REGRESS_OUTPUTS: output_tensor_info} signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.REGRESS_METHOD_NAME) return signature_def
def predict_signature_def(inputs, outputs): """Creates prediction signature from given inputs and outputs. This function produces signatures intended for use with the TensorFlow Serving Predict API (tensorflow_serving/apis/prediction_service.proto). This API imposes no constraints on the input and output types. Args: inputs: dict of string to `Tensor`. outputs: dict of string to `Tensor`. Returns: A prediction-flavored signature_def. Raises: ValueError: If inputs or outputs is `None`. """ if inputs is None or not inputs: raise ValueError('Prediction inputs cannot be None or empty.') if outputs is None or not outputs: raise ValueError('Prediction outputs cannot be None or empty.') signature_inputs = {key: utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {key: utils.build_tensor_info(tensor) for key, tensor in outputs.items()} signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.PREDICT_METHOD_NAME) return signature_def
def build_inputs_and_outputs(self): if self.frame_features: serialized_examples = tf.placeholder(tf.string, shape=(None,)) fn = lambda x: self.build_prediction_graph(x) video_id_output, top_indices_output, top_predictions_output = ( tf.map_fn(fn, serialized_examples, dtype=(tf.string, tf.int32, tf.float32))) else: serialized_examples = tf.placeholder(tf.string, shape=(None,)) video_id_output, top_indices_output, top_predictions_output = ( self.build_prediction_graph(serialized_examples)) inputs = {"example_bytes": saved_model_utils.build_tensor_info(serialized_examples)} outputs = { "video_id": saved_model_utils.build_tensor_info(video_id_output), "class_indexes": saved_model_utils.build_tensor_info(top_indices_output), "predictions": saved_model_utils.build_tensor_info(top_predictions_output)} return inputs, outputs
def testBuildSignatureDef(self): x = tf.placeholder(tf.float32, 1, name="x") x_tensor_info = utils.build_tensor_info(x) inputs = dict() inputs["foo-input"] = x_tensor_info y = tf.placeholder(tf.float32, name="y") y_tensor_info = utils.build_tensor_info(y) outputs = dict() outputs["foo-output"] = y_tensor_info signature_def = utils.build_signature_def(inputs, outputs, "foo-method-name") self.assertEqual("foo-method-name", signature_def.method_name) # Check inputs in signature def. self.assertEqual(1, len(signature_def.inputs)) x_tensor_info_actual = signature_def.inputs["foo-input"] self.assertEqual("x:0", x_tensor_info_actual.name) self.assertEqual(types_pb2.DT_FLOAT, x_tensor_info_actual.dtype) self.assertEqual(1, len(x_tensor_info_actual.tensor_shape.dim)) self.assertEqual(1, x_tensor_info_actual.tensor_shape.dim[0].size) # Check outputs in signature def. self.assertEqual(1, len(signature_def.outputs)) y_tensor_info_actual = signature_def.outputs["foo-output"] self.assertEqual("y:0", y_tensor_info_actual.name) self.assertEqual(types_pb2.DT_FLOAT, y_tensor_info_actual.dtype) self.assertEqual(0, len(y_tensor_info_actual.tensor_shape.dim))
def regression_signature_def(examples, predictions): """Creates regression signature from given examples and predictions. Args: examples: `Tensor`. predictions: `Tensor`. Returns: A regression-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('examples cannot be None for regression.') if predictions is None: raise ValueError('predictions cannot be None for regression.') input_tensor_info = utils.build_tensor_info(examples) signature_inputs = {signature_constants.REGRESS_INPUTS: input_tensor_info} output_tensor_info = utils.build_tensor_info(predictions) signature_outputs = {signature_constants.REGRESS_OUTPUTS: output_tensor_info} signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.REGRESS_METHOD_NAME) return signature_def
def predict_signature_def(inputs, outputs): """Creates prediction signature from given inputs and outputs. Args: inputs: dict of string to `Tensor`. outputs: dict of string to `Tensor`. Returns: A prediction-flavored signature_def. Raises: ValueError: If inputs or outputs is `None`. """ if inputs is None or not inputs: raise ValueError('Prediction inputs cannot be None or empty.') if outputs is None or not outputs: raise ValueError('Prediction outputs cannot be None or empty.') signature_inputs = {key: utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {key: utils.build_tensor_info(tensor) for key, tensor in outputs.items()} signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.PREDICT_METHOD_NAME) return signature_def
def setUp(self): """Write test SavedModels to a temp directory.""" with session.Session(graph=ops.Graph()) as sess: x = variables.VariableV1(5, name="x") y = variables.VariableV1(11, name="y") z = x + y self.evaluate(variables.global_variables_initializer()) foo_sig_def = signature_def_utils.build_signature_def( {"foo_input": utils.build_tensor_info(x)}, {"foo_output": utils.build_tensor_info(z)}) bar_sig_def = signature_def_utils.build_signature_def( {"bar_x": utils.build_tensor_info(x), "bar_y": utils.build_tensor_info(y)}, {"bar_z": utils.build_tensor_info(z)}) builder = saved_model_builder.SavedModelBuilder(SIMPLE_ADD_SAVED_MODEL) builder.add_meta_graph_and_variables( sess, ["foo_graph"], {"foo": foo_sig_def, "bar": bar_sig_def}) builder.save() # Write SavedModel with a main_op assign_op = control_flow_ops.group(state_ops.assign(y, 7)) builder = saved_model_builder.SavedModelBuilder(SAVED_MODEL_WITH_MAIN_OP) builder.add_meta_graph_and_variables( sess, ["foo_graph"], {"foo": foo_sig_def, "bar": bar_sig_def}, main_op=assign_op) builder.save()
def export(model_version, model_dir, sess, x, y_op): """导出tensorflow_serving可用的模型 SavedModel(tensorflow.python.saved_model)提供了一种跨语言格式来保存和恢复训练后的TensorFlow模型。它使用方法签名来定义Graph的输入和输出,使上层系统能够更方便地生成、调用或转换TensorFlow模型。 SavedModelBuilder类提供保存Graphs、Variables及Assets的方法。所保存的Graphs必须标注用途标签。在这个实例中我们打算将模型用于服务而非训练,因此我们用SavedModel预定义好的tag_constant.Serving标签。 为了方便地构建签名,SavedModel提供了signature_def_utils API。我们通过signature_def_utils.build_signature_def()来构建predict_signature。一个predict_signature至少包含以下参数: * inputs = {'x': tensor_info_x} 指定输入的tensor信息 * outputs = {'y': tensor_info_y} 指定输出的tensor信息 * method_name = signature_constants.PREDICT_METHOD_NAME method_name定义方法名,它的值应该是tensorflow/serving/predict、tensorflow/serving/classify和tensorflow/serving/regress三者之一。Builder标签用来明确Meta Graph被加载的方式,只接受serve和train两种类型。 """ if model_version <= 0: logging.warning('Please specify a positive value for version number.') sys.exit() path = os.path.dirname(os.path.abspath(model_dir)) if os.path.isdir(path) == False: logging.warning('Path (%s) not exists, making directories...', path) os.makedirs(path) export_path = os.path.join( compat.as_bytes(model_dir), compat.as_bytes(str(model_version))) if os.path.isdir(export_path) == True: logging.warning('Path (%s) exists, removing directories...', export_path) shutil.rmtree(export_path) builder = saved_model_builder.SavedModelBuilder(export_path) tensor_info_x = utils.build_tensor_info(x) tensor_info_y = utils.build_tensor_info(y_op) prediction_signature = signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'y': tensor_info_y}, # signature_constants.CLASSIFY_METHOD_NAME = "tensorflow/serving/classify" # signature_constants.PREDICT_METHOD_NAME = "tensorflow/serving/predict" # signature_constants.REGRESS_METHOD_NAME = "tensorflow/serving/regress" # 如果缺失method_name会报错: # grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.INTERNAL, details="Expected prediction signature method_name to be one of {tensorflow/serving/predict, tensorflow/serving/classify, tensorflow/serving/regress}. Was: ") method_name=signature_constants.PREDICT_METHOD_NAME) builder.add_meta_graph_and_variables( sess, # tag_constants.SERVING = "serve" # tag_constants.TRAINING = "train" # 如果只有train标签,TensorFlow Serving加载时会报错: # E tensorflow_serving/core/aspired_versions_manager.cc:351] Servable {name: default version: 2} cannot be loaded: Not found: Could not find meta graph def matching supplied tags. [tag_constants.SERVING], signature_def_map={ 'predict_text': prediction_signature, # 如果缺失会报错: # grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.FAILED_PRECONDITION, details="Default serving signature key not found.") signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature }) builder.save()
def _make_signature(inputs, outputs, name=None): input_info = { input_name: utils.build_tensor_info(tensor) for input_name, tensor in inputs.items() } output_info = { output_name: utils.build_tensor_info(tensor) for output_name, tensor in outputs.items() } return signature_def_utils_impl.build_signature_def(input_info, output_info, name)
def testGetSignatureDefByKey(self): x = array_ops.placeholder(dtypes.float32, 1, name="x") x_tensor_info = utils.build_tensor_info(x) y = array_ops.placeholder(dtypes.float32, name="y") y_tensor_info = utils.build_tensor_info(y) foo_signature_def = signature_def_utils.build_signature_def({ "foo-input": x_tensor_info }, {"foo-output": y_tensor_info}, "foo-method-name") bar_signature_def = signature_def_utils.build_signature_def({ "bar-input": x_tensor_info }, {"bar-output": y_tensor_info}, "bar-method-name") meta_graph_def = meta_graph_pb2.MetaGraphDef() self._add_to_signature_def_map( meta_graph_def, {"foo": foo_signature_def, "bar": bar_signature_def}) # Look up a key that does not exist in the SignatureDefMap. missing_key = "missing-key" with self.assertRaisesRegexp( ValueError, "No SignatureDef with key '%s' found in MetaGraphDef" % missing_key): signature_def_contrib_utils.get_signature_def_by_key( meta_graph_def, missing_key) # Look up the key, `foo` which exists in the SignatureDefMap. foo_signature_def = signature_def_contrib_utils.get_signature_def_by_key( meta_graph_def, "foo") self.assertTrue("foo-method-name", foo_signature_def.method_name) # Check inputs in signature def. self.assertEqual(1, len(foo_signature_def.inputs)) self._check_tensor_info(foo_signature_def.inputs, "foo-input", "x:0") # Check outputs in signature def. self.assertEqual(1, len(foo_signature_def.outputs)) self._check_tensor_info(foo_signature_def.outputs, "foo-output", "y:0") # Look up the key, `bar` which exists in the SignatureDefMap. bar_signature_def = signature_def_contrib_utils.get_signature_def_by_key( meta_graph_def, "bar") self.assertTrue("bar-method-name", bar_signature_def.method_name) # Check inputs in signature def. self.assertEqual(1, len(bar_signature_def.inputs)) self._check_tensor_info(bar_signature_def.inputs, "bar-input", "x:0") # Check outputs in signature def. self.assertEqual(1, len(bar_signature_def.outputs)) self._check_tensor_info(bar_signature_def.outputs, "bar-output", "y:0")
def _WriteInputSavedModel(self, input_saved_model_dir): """Write the saved model as an input for testing.""" g, var, inp, out = self._GetGraph() signature_def = signature_def_utils.build_signature_def( inputs={"myinput": utils.build_tensor_info(inp)}, outputs={"myoutput": utils.build_tensor_info(out)}, method_name=signature_constants.PREDICT_METHOD_NAME) saved_model_builder = builder.SavedModelBuilder(input_saved_model_dir) with self.session(graph=g, config=self._GetConfigProto()) as sess: sess.run(var.initializer) saved_model_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={"mypredict": signature_def}) saved_model_builder.save()
def classification_signature_def(examples, classes, scores): """Creates classification signature from given examples and predictions. This function produces signatures intended for use with the TensorFlow Serving Classify API (tensorflow_serving/apis/prediction_service.proto), and so constrains the input and output types to those allowed by TensorFlow Serving. Args: examples: A string `Tensor`, expected to accept serialized tf.Examples. classes: A string `Tensor`. Note that the ClassificationResponse message requires that class labels are strings, not integers or anything else. scores: a float `Tensor`. Returns: A classification-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('Classification examples cannot be None.') if not isinstance(examples, ops.Tensor): raise ValueError('Classification examples must be a string Tensor.') if classes is None and scores is None: raise ValueError('Classification classes and scores cannot both be None.') input_tensor_info = utils.build_tensor_info(examples) if input_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Classification examples must be a string Tensor.') signature_inputs = {signature_constants.CLASSIFY_INPUTS: input_tensor_info} signature_outputs = {} if classes is not None: classes_tensor_info = utils.build_tensor_info(classes) if classes_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Classification classes must be a string Tensor.') signature_outputs[signature_constants.CLASSIFY_OUTPUT_CLASSES] = ( classes_tensor_info) if scores is not None: scores_tensor_info = utils.build_tensor_info(scores) if scores_tensor_info.dtype != types_pb2.DT_FLOAT: raise ValueError('Classification scores must be a float Tensor.') signature_outputs[signature_constants.CLASSIFY_OUTPUT_SCORES] = ( scores_tensor_info) signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.CLASSIFY_METHOD_NAME) return signature_def
def build_graph_helper(): g = ops.Graph() with g.as_default(): x = variables.VariableV1(5, name="x") y = variables.VariableV1(11, name="y") z = x + y foo_sig_def = signature_def_utils.build_signature_def({ "foo_input": utils.build_tensor_info(x) }, {"foo_output": utils.build_tensor_info(z)}) bar_sig_def = signature_def_utils.build_signature_def({ "bar_x": utils.build_tensor_info(x), "bar_y": utils.build_tensor_info(y) }, {"bar_z": utils.build_tensor_info(z)}) return g, {"foo": foo_sig_def, "bar": bar_sig_def}, y
def testBuildTensorInfoDense(self): x = array_ops.placeholder(dtypes.float32, 1, name="x") x_tensor_info = utils.build_tensor_info(x) self.assertEqual("x:0", x_tensor_info.name) self.assertEqual(types_pb2.DT_FLOAT, x_tensor_info.dtype) self.assertEqual(1, len(x_tensor_info.tensor_shape.dim)) self.assertEqual(1, x_tensor_info.tensor_shape.dim[0].size)
def testGetTensorFromInfoSparse(self): expected = array_ops.sparse_placeholder(dtypes.float32, name="x") tensor_info = utils.build_tensor_info(expected) actual = utils.get_tensor_from_tensor_info(tensor_info) self.assertIsInstance(actual, sparse_tensor.SparseTensor) self.assertEqual(expected.values.name, actual.values.name) self.assertEqual(expected.indices.name, actual.indices.name) self.assertEqual(expected.dense_shape.name, actual.dense_shape.name)
def GenerateModelV1(tf_saved_model_dir, tftrt_saved_model_dir): """Generate and convert a model using TFv1 API.""" def SimpleModel(): """Define model with a TF graph.""" def GraphFn(): input1 = array_ops.placeholder(dtype=dtypes.float32, shape=[None, 1, 1], name="input1") input2 = array_ops.placeholder(dtype=dtypes.float32, shape=[None, 1, 1], name="input2") var = variables.Variable([[[1.0]]], dtype=dtypes.float32, name="v1") out = GetGraph(input1, input2, var) return g, var, input1, input2, out g = ops.Graph() with g.as_default(): return GraphFn() g, var, input1, input2, out = SimpleModel() signature_def = signature_def_utils.build_signature_def( inputs={ "input1": utils.build_tensor_info(input1), "input2": utils.build_tensor_info(input2) }, outputs={"output": utils.build_tensor_info(out)}, method_name=signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY) saved_model_builder = builder.SavedModelBuilder(tf_saved_model_dir) with Session(graph=g) as sess: sess.run(var.initializer) saved_model_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def }) saved_model_builder.save() # Convert TF model to TensorRT converter = trt_convert.TrtGraphConverter( input_saved_model_dir=tf_saved_model_dir, is_dynamic_op=True) converter.convert() converter.save(tftrt_saved_model_dir)
def save_model(saved_model_dir, sess, input_tensors=None, output_tensors=None, output_node_names=None): input_tensors = input_tensors or [] output_tensors = output_tensors or [] output_node_names = output_node_names or [] inputs = {t.name: tf_utils.build_tensor_info(t) for t in input_tensors} outputs = { t.name: tf_utils.build_tensor_info(t) for t in output_tensors } model_signature = signature_def_utils.build_signature_def( inputs=inputs, outputs=outputs, method_name=signature_constants.PREDICT_METHOD_NAME) builder = saved_model_builder.SavedModelBuilder(saved_model_dir) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], clear_devices=True, signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: model_signature, }) builder.save() # Add the output node names to the collection def fname = os.path.join(saved_model_dir, tf_constants.SAVED_MODEL_FILENAME_PB) saved_model = saved_model_pb2.SavedModel() with open(fname, "rb") as f: saved_model.ParseFromString(f.read()) saved_model.meta_graphs[0].collection_def[ tf_saved_model_base_importer.ImportTFSavedModelBase. OUTPUT_NODES_COLLECTION_DEF_KEY].node_list.value.extend( output_node_names) with open(fname, "wb") as f: f.write(saved_model.SerializeToString())
def classification_signature_def(examples, classes, scores): """Creates classification signature from given examples and predictions. Args: examples: `Tensor`. classes: `Tensor`. scores: `Tensor`. Returns: A classification-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('Classification examples cannot be None.') if not isinstance(examples, ops.Tensor): raise ValueError('Classification examples must be a string Tensor.') if classes is None and scores is None: raise ValueError('Classification classes and scores cannot both be None.') input_tensor_info = utils.build_tensor_info(examples) if input_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Classification examples must be a string Tensor.') signature_inputs = {signature_constants.CLASSIFY_INPUTS: input_tensor_info} signature_outputs = {} if classes is not None: classes_tensor_info = utils.build_tensor_info(classes) if classes_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Classification classes must be a string Tensor.') signature_outputs[signature_constants.CLASSIFY_OUTPUT_CLASSES] = ( classes_tensor_info) if scores is not None: scores_tensor_info = utils.build_tensor_info(scores) if scores_tensor_info.dtype != types_pb2.DT_FLOAT: raise ValueError('Classification scores must be a float Tensor.') signature_outputs[signature_constants.CLASSIFY_OUTPUT_SCORES] = ( scores_tensor_info) signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.CLASSIFY_METHOD_NAME) return signature_def
def testGetTensorFromInfoRaisesErrors(self): expected = array_ops.placeholder(dtypes.float32, 1, name="x") tensor_info = utils.build_tensor_info(expected) tensor_info.name = "blah:0" # Nonexistent name. with self.assertRaises(KeyError): utils.get_tensor_from_tensor_info(tensor_info) tensor_info.ClearField("name") # Malformed (missing encoding). with self.assertRaises(ValueError): utils.get_tensor_from_tensor_info(tensor_info)
def testGetTensorFromInfoRaisesErrors(self): expected = array_ops.placeholder(dtypes.float32, 1, name="x") tensor_info = utils.build_tensor_info(expected) tensor_info.name = "blah:0" # Nonexistant name. with self.assertRaises(KeyError): utils.get_tensor_from_tensor_info(tensor_info) tensor_info.ClearField("name") # Malformed (missing encoding). with self.assertRaises(ValueError): utils.get_tensor_from_tensor_info(tensor_info)
def build_inputs_and_outputs(self): serialized_examples = tf.placeholder(tf.string, shape=(None, )) index_output, predictions_output = ( self.build_prediction_graph(serialized_examples)) inputs = { "example_bytes": saved_model_utils.build_tensor_info(serialized_examples) } outputs = { "class_indexes": saved_model_utils.build_tensor_info(index_output), "predictions": saved_model_utils.build_tensor_info(predictions_output) } return inputs, outputs
def export(model_version, model_dir, sess, x, y_op): """ 导出tensorflow_serving可用的模型 :param model_version: :param model_dir: :param sess: :param x: :param y_op: :return: """ if model_version <= 0: logging.warning('Please specify a positive value of version') sys.exit() path = os.path.dirname(os.path.abspath(model_dir)) if os.path.isdir(path) == False: logging.warning('(%s) not exists, making directories...', path) os.makedirs(path) export_path = os.path.join(compat.as_bytes(model_dir), compat.as_bytes(str(model_version))) if os.path.isdir(export_path) == True: logging.warning('(%s) exists, removing dirs...', export_path) shutil.rmtree(export_path) builder = saved_model_builder.SavedModelBuilder(export_path) tensor_info_x = utils.build_tensor_info(x) tensor_info_y = utils.build_tensor_info(y_op) prediction_signature = signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'y': tensor_info_y}, method_name=signature_constants.PREDICT_METHOD_NAME) builder.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], signature_def_map={ 'predict_text': prediction_signature, signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature }) builder.save()
def main(argv): if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') shutil.rmtree(FLAGS.saved_model_path) # Create the graph # 'x' is a read-only Reference Variable in this test case, which will be # converted to Resource Variable in the MLIR lowering pass. x = variable_scope.get_variable(name='x', initializer=[[1], [2], [3]]) r = math_ops.add(x, 1) x1 = array_ops.placeholder(dtype=dtypes.int32, shape=(1, 3), name='input1') r1 = math_ops.add(x1, 1) sess = session.Session() sess.run(variables.global_variables_initializer()) sm_builder = builder.SavedModelBuilder(FLAGS.saved_model_path) tensor_info_x = utils.build_tensor_info(x) tensor_info_r = utils.build_tensor_info(r) tensor_info_x1 = utils.build_tensor_info(x1) tensor_info_r1 = utils.build_tensor_info(r1) ref_signature = (signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'r': tensor_info_r}, method_name=signature_constants.PREDICT_METHOD_NAME)) non_ref_signature = (signature_def_utils.build_signature_def( inputs={'x1': tensor_info_x1}, outputs={'r1': tensor_info_r1}, method_name=signature_constants.PREDICT_METHOD_NAME)) sm_builder.add_meta_graph_and_variables(sess, [tag_constants.SERVING], signature_def_map={ 'ref': ref_signature, 'non_ref': non_ref_signature, }, strip_default_attrs=True) sm_builder.save()
def build_inputs_and_outputs(self): split_num = self.reader.present_split top_indices_output, top_predictions_output = ( self.build_prediction_graph(split_num)) inputs = { "example_bytes": saved_model_utils.build_tensor_info(tf.constant(split_num)) } outputs = { "class_indexes": saved_model_utils.build_tensor_info(top_indices_output), "predictions": saved_model_utils.build_tensor_info(top_predictions_output) } return inputs, outputs
def main(argv): if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') shutil.rmtree(FLAGS.saved_model_path) # Create the graph x = array_ops.sparse_placeholder(dtype=dtypes.int32, shape=None, name='input') r = sparse_ops.sparse_reduce_sum(x) x1 = array_ops.placeholder(dtype=dtypes.int32, shape=(1, 3), name='input1') r1 = math_ops.add(x1, 1) sess = session.Session() sm_builder = builder.SavedModelBuilder(FLAGS.saved_model_path) tensor_info_x = utils.build_tensor_info(x) tensor_info_r = utils.build_tensor_info(r) tensor_info_x1 = utils.build_tensor_info(x1) tensor_info_r1 = utils.build_tensor_info(r1) sparse_signature = ( signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'r': tensor_info_r}, method_name=signature_constants.PREDICT_METHOD_NAME)) dense_signature = ( signature_def_utils.build_signature_def( inputs={'x1': tensor_info_x1}, outputs={'r1': tensor_info_r1}, method_name=signature_constants.PREDICT_METHOD_NAME)) sm_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ 'sparse': sparse_signature, 'dense': dense_signature, }, strip_default_attrs=True) sm_builder.save()
def _prepare_signature_inputs(layers: dict, dtype_layer, model_keys): signature = {} for key, value in model_keys.items(): if value in layers.keys(): x = gen_array_ops.placeholder(dtype=dtype_layer, shape=layers[value], name=value) x_tensor_info = build_tensor_info(x) signature[key] = x_tensor_info return signature
def test_load_saved_model_with_no_variables(self, builder_cls): """Test that SavedModel runs saver when there appear to be no variables. When no variables are detected, this may mean that the variables were saved to different collections, or the collections weren't saved to the SavedModel. If the SavedModel MetaGraphDef contains a saver, it should still run in either of these cases. Args: builder_cls: SavedModelBuilder or _SavedModelBuilder class """ path = _get_export_dir("no_variable_saved_model") with session.Session(graph=ops.Graph()) as sess: x = variables.VariableV1(5, name="x", collections=["not_global_variable"]) y = variables.VariableV1(11, name="y", collections=["not_global_variable"]) self.assertFalse(variables._all_saveable_objects()) z = x + y self.evaluate(variables.variables_initializer([x, y])) foo_sig_def = signature_def_utils.build_signature_def( {"foo_input": utils.build_tensor_info(x)}, {"foo_output": utils.build_tensor_info(z)}) builder = saved_model_builder.SavedModelBuilder(path) builder.add_meta_graph_and_variables(sess, ["foo_graph"], {"foo": foo_sig_def}, saver=tf_saver.Saver([x, y])) builder.save() loader = loader_impl.SavedModelLoader(path) with self.session(graph=ops.Graph()) as sess: saver, _ = loader.load_graph(sess.graph, ["foo_graph"]) self.assertFalse(variables._all_saveable_objects()) self.assertIsNotNone(saver) with self.session(graph=ops.Graph()) as sess: loader.load(sess, ["foo_graph"]) self.assertEqual(5, sess.graph.get_tensor_by_name("x:0").eval()) self.assertEqual(11, sess.graph.get_tensor_by_name("y:0").eval())
def serving(self): with self.detection_graph.as_default(): with tf.Session(graph=self.detection_graph) as sess: export_path = 'tf_serving_export_{}_{}'.format('mobilenet', 'pascal') print('Exporting trained model to', export_path) if os.path.exists(export_path): shutil.rmtree(export_path) builder = saved_model_builder.SavedModelBuilder(export_path) image_tensor = self.detection_graph.get_tensor_by_name('image_tensor:0') boxes = self.detection_graph.get_tensor_by_name('detection_boxes:0') scores = self.detection_graph.get_tensor_by_name('detection_scores:0') classes = self.detection_graph.get_tensor_by_name('detection_classes:0') num_detections = self.detection_graph.get_tensor_by_name('num_detections:0') image_tensor_info = utils.build_tensor_info(image_tensor) boxes_tensor_info = utils.build_tensor_info(boxes) scores_tensor_info = utils.build_tensor_info(scores) classes_tensor_info = utils.build_tensor_info(classes) num_detections_tensor_info = utils.build_tensor_info(num_detections) prediction_signature = signature_def_utils.build_signature_def( inputs={'image_tensor': image_tensor_info}, outputs={'boxes': boxes_tensor_info, 'scores': scores_tensor_info, 'classes': classes_tensor_info, 'num_detections': num_detections_tensor_info, }, method_name=signature_constants.PREDICT_METHOD_NAME) legacy_init_op = tf.group(tf.initialize_all_tables(), name='legacy_init_op') builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ 'predict_bbox': prediction_signature, }, legacy_init_op=legacy_init_op) builder.save() print('Done exporting!')
def _MakeSavedModel(self, run_params): """Write the saved model as an input for testing.""" params = self._GetParamsCached() g = ops.Graph() with g.as_default(): inputs = [] for spec in params.input_specs: inp = array_ops.placeholder(dtype=spec.dtype, shape=spec.shape, name=spec.name) inputs.append(inp) outputs = params.graph_fn(*inputs) if not isinstance(outputs, list) and not isinstance( outputs, tuple): outputs = [outputs] for spec, output in zip(params.output_specs, outputs): assert spec.name == output.name.split(":")[0] signature_def = signature_def_utils.build_signature_def( inputs={ inp.op.name: utils.build_tensor_info(inp) for inp in inputs }, outputs={ out.op.name: utils.build_tensor_info(out) for out in outputs }, method_name=signature_constants.PREDICT_METHOD_NAME) saved_model_dir = tempfile.mkdtemp(dir=self.get_temp_dir()) saved_model_builder = builder.SavedModelBuilder(saved_model_dir) with self.session(graph=g, config=self._GetConfigProto( run_params, GraphState.ORIGINAL)) as sess: saved_model_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def }) saved_model_builder.save() return saved_model_dir
def main(argv): if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') shutil.rmtree(FLAGS.saved_model_path) variable_scope.enable_resource_variables() # Create the graph table_initializer = lookup_ops.TextFileInitializer( write_vocabulary_file(['cat', 'is', 'on', 'the', 'mat']), dtypes.string, lookup_ops.TextFileIndex.WHOLE_LINE, dtypes.int64, lookup_ops.TextFileIndex.LINE_NUMBER) table = lookup_ops.StaticVocabularyTable(table_initializer, num_oov_buckets=10) key = array_ops.placeholder(dtypes.string, shape=(), name='input') result = table.lookup(key) sess = session.Session() sess.run(variables.global_variables_initializer()) sm_builder = builder.SavedModelBuilder(FLAGS.saved_model_path) tensor_info_x = utils.build_tensor_info(key) tensor_info_r = utils.build_tensor_info(result) toy_signature = (signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'r': tensor_info_r}, method_name=signature_constants.PREDICT_METHOD_NAME)) sm_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: toy_signature, }, main_op=lookup_ops.tables_initializer(), assets_collection=ops.get_collection(ops.GraphKeys.ASSET_FILEPATHS), strip_default_attrs=True) sm_builder.save()
def build_signature(inputs, outputs): """Build the signature. Not using predic_signature_def in saved_model because it is replacing the tensor name, b/35900497. Args: inputs: a dictionary of tensor name to tensor outputs: a dictionary of tensor name to tensor Returns: The signature, a SignatureDef proto. """ signature_inputs = {key: saved_model_utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {key: saved_model_utils.build_tensor_info(tensor) for key, tensor in outputs.items()} signature_def = signature_def_utils.build_signature_def( signature_inputs, signature_outputs, signature_constants.PREDICT_METHOD_NAME) return signature_def
def testGetTensorFromInfoInOtherGraph(self): with ops.Graph().as_default() as expected_graph: expected = array_ops.placeholder(dtypes.float32, 1, name="right") tensor_info = utils.build_tensor_info(expected) with ops.Graph().as_default(): # Some other graph. array_ops.placeholder(dtypes.float32, 1, name="other") actual = utils.get_tensor_from_tensor_info(tensor_info, graph=expected_graph) self.assertIsInstance(actual, ops.Tensor) self.assertIs(actual.graph, expected_graph) self.assertEqual(expected.name, actual.name)
def _prepare_signature(layers: dict, model_keys): signature = {} for key, value in model_keys.items(): if value in layers.keys(): x = gen_array_ops.placeholder( dtype=type_mapping[layers[value].precision], shape=layers[value].shape, name=value) x_tensor_info = build_tensor_info(x) signature[key] = x_tensor_info return signature
def testGetTensorFromInfoInOtherGraph(self): with ops.Graph().as_default() as expected_graph: expected = array_ops.placeholder(dtypes.float32, 1, name="right") tensor_info = utils.build_tensor_info(expected) with ops.Graph().as_default(): # Some other graph. array_ops.placeholder(dtypes.float32, 1, name="other") actual = utils.get_tensor_from_tensor_info(tensor_info, graph=expected_graph) self.assertIsInstance(actual, ops.Tensor) self.assertIs(actual.graph, expected_graph) self.assertEqual(expected.name, actual.name)
def regression_signature_def(examples, predictions): """Creates regression signature from given examples and predictions. This function produces signatures intended for use with the TensorFlow Serving Regress API (tensorflow_serving/apis/prediction_service.proto), and so constrains the input and output types to those allowed by TensorFlow Serving. Args: examples: A string `Tensor`, expected to accept serialized tf.Examples. predictions: A float `Tensor`. Returns: A regression-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('Regression examples cannot be None.') if not isinstance(examples, ops.Tensor): raise ValueError('Regression examples must be a string Tensor.') if predictions is None: raise ValueError('Regression predictions cannot be None.') input_tensor_info = utils.build_tensor_info(examples) if input_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Regression examples must be a string Tensor.') signature_inputs = {signature_constants.REGRESS_INPUTS: input_tensor_info} output_tensor_info = utils.build_tensor_info(predictions) if output_tensor_info.dtype != types_pb2.DT_FLOAT: raise ValueError('Regression output must be a float Tensor.') signature_outputs = { signature_constants.REGRESS_OUTPUTS: output_tensor_info } signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.REGRESS_METHOD_NAME) return signature_def
def test_load_saved_model_with_no_variables(self, builder_cls): """Test that SavedModel runs saver when there appear to be no variables. When no variables are detected, this may mean that the variables were saved to different collections, or the collections weren't saved to the SavedModel. If the SavedModel MetaGraphDef contains a saver, it should still run in either of these cases. Args: builder_cls: SavedModelBuilder or _SavedModelBuilder class """ path = _get_export_dir("no_variable_saved_model") with session.Session(graph=ops.Graph()) as sess: x = variables.VariableV1( 5, name="x", collections=["not_global_variable"]) y = variables.VariableV1( 11, name="y", collections=["not_global_variable"]) self.assertFalse(variables._all_saveable_objects()) z = x + y self.evaluate(variables.variables_initializer([x, y])) foo_sig_def = signature_def_utils.build_signature_def( {"foo_input": utils.build_tensor_info(x)}, {"foo_output": utils.build_tensor_info(z)}) builder = saved_model_builder.SavedModelBuilder(path) builder.add_meta_graph_and_variables( sess, ["foo_graph"], {"foo": foo_sig_def}, saver=tf_saver.Saver([x, y])) builder.save() loader = loader_impl.SavedModelLoader(path) with self.session(graph=ops.Graph()) as sess: saver, _ = loader.load_graph(sess.graph, ["foo_graph"]) self.assertFalse(variables._all_saveable_objects()) self.assertIsNotNone(saver) with self.session(graph=ops.Graph()) as sess: loader.load(sess, ["foo_graph"]) self.assertEqual(5, sess.graph.get_tensor_by_name("x:0").eval()) self.assertEqual(11, sess.graph.get_tensor_by_name("y:0").eval())
def save_model(sess, model, save_path, model_version): #模型签名,模型输入和输出的签名 model_signature = signature_def_utils.build_signature_def( inputs={ "inputs": utils.build_tensor_info(model.x), "mask": utils.build_tensor_info(model.mask) }, outputs={"outputs": utils.build_tensor_info(model.y)}, method_name=signature_constants.PREDICT_METHOD_NAME) export_path = os.path.join(compat.as_bytes(save_path), compat.as_bytes(str(model_version))) legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op') builder = saved_model_builder.SavedModelBuilder(export_path) builder.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], clear_devices=True, signature_def_map={'bilstm_crf': model_signature}, legacy_init_op=legacy_init_op) builder.save()
def save_signature(self, directory): signature = signature_def_utils.build_signature_def( inputs={ "input": saved_model_utils.build_tensor_info(self.input), "dropout_rate": saved_model_utils.build_tensor_info(self.dropout_rate), }, outputs={"output": saved_model_utils.build_tensor_info(self.output)}, method_name=signature_constants.PREDICT_METHOD_NAME, ) signature_map = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature } model_builder = saved_model_builder.SavedModelBuilder(directory) model_builder.add_meta_graph_and_variables( self.sess, tags=[tag_constants.SERVING], signature_def_map=signature_map, clear_devices=True, ) model_builder.save(as_text=False)
def _supervised_signature_def( method_name, inputs, loss=None, predictions=None, metrics=None): """Creates a signature for training and eval data. This function produces signatures that describe the inputs and outputs of a supervised process, such as training or evaluation, that results in loss, metrics, and the like. Note that this function only requires inputs to be not None. Args: method_name: Method name of the SignatureDef as a string. inputs: dict of string to `Tensor`. loss: dict of string to `Tensor` representing computed loss. predictions: dict of string to `Tensor` representing the output predictions. metrics: dict of string to `Tensor` representing metric ops. Returns: A train- or eval-flavored signature_def. Raises: ValueError: If inputs or outputs is `None`. """ if inputs is None or not inputs: raise ValueError('{} inputs cannot be None or empty.'.format(method_name)) signature_inputs = {key: utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {} for output_set in (loss, predictions, metrics): if output_set is not None: sig_out = {key: utils.build_tensor_info(tensor) for key, tensor in output_set.items()} signature_outputs.update(sig_out) signature_def = build_signature_def( signature_inputs, signature_outputs, method_name) return signature_def
def predict_signature_def(inputs, outputs): """Creates prediction signature from given inputs and outputs. Args: inputs: dict of string to `Tensor`. outputs: dict of string to `Tensor`. Returns: A prediction-flavored signature_def. Raises: ValueError: If inputs or outputs is `None`. """ if inputs is None or not inputs: raise ValueError('inputs cannot be None or empty for prediction.') if outputs is None: raise ValueError('outputs cannot be None or empty for prediction.') # If there's only one input or output, we can standardize keys if len(inputs) == 1: (_, value), = inputs.items() inputs = {signature_constants.PREDICT_INPUTS: value} if len(outputs) == 1: (_, value), = outputs.items() outputs = {signature_constants.PREDICT_OUTPUTS: value} signature_inputs = { key: utils.build_tensor_info(tensor) for key, tensor in inputs.items() } signature_outputs = { key: utils.build_tensor_info(tensor) for key, tensor in outputs.items() } signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.PREDICT_METHOD_NAME) return signature_def
def _supervised_signature_def( method_name, inputs, loss=None, predictions=None, metrics=None): """Creates a signature for training and eval data. This function produces signatures that describe the inputs and outputs of a supervised process, such as training or evaluation, that results in loss, metrics, and the like. Note that this function only requires inputs to be not None. Args: method_name: Method name of the SignatureDef as a string. inputs: dict of string to `Tensor`. loss: dict of string to `Tensor` representing computed loss. predictions: dict of string to `Tensor` representing the output predictions. metrics: dict of string to `Tensor` representing metric ops. Returns: A train- or eval-flavored signature_def. Raises: ValueError: If inputs or outputs is `None`. """ if inputs is None or not inputs: raise ValueError('{} inputs cannot be None or empty.'.format(method_name)) signature_inputs = {key: utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {} for output_set in (loss, predictions, metrics): if output_set is not None: sig_out = {key: utils.build_tensor_info(tensor) for key, tensor in output_set.items()} signature_outputs.update(sig_out) signature_def = build_signature_def( signature_inputs, signature_outputs, method_name) return signature_def
def main(): # test_preprocess() # test_postprocess() preprocess_function_string = marshal.dumps(preprocess.func_code) tf.add_to_collection("preprocess_function", preprocess_function_string) postprocess_function_string = marshal.dumps(postprocess.func_code) tf.add_to_collection("postprocess_function", postprocess_function_string) model_path = "preprocess_model" model_version = 1 keys_placeholder = tf.placeholder(tf.int32, shape=[None], name="keys") keys_identity = tf.identity(keys_placeholder, name="inference_keys") sess = tf.Session() sess.run(tf.global_variables_initializer()) model_signature = signature_def_utils.build_signature_def( inputs={ "keys": utils.build_tensor_info(keys_placeholder), }, outputs={ "keys": utils.build_tensor_info(keys_identity), }, method_name=signature_constants.PREDICT_METHOD_NAME) export_path = os.path.join(compat.as_bytes(model_path), compat.as_bytes(str(model_version))) builder = saved_model_builder.SavedModelBuilder(export_path) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], clear_devices=True, signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: model_signature, }) builder.save()
def main(): # test_preprocess() # test_postprocess() preprocess_function_string = marshal.dumps(preprocess.func_code) tf.add_to_collection("preprocess_function", preprocess_function_string) postprocess_function_string = marshal.dumps(postprocess.func_code) tf.add_to_collection("postprocess_function", postprocess_function_string) model_path = "preprocess_model" model_version = 1 keys_placeholder = tf.placeholder(tf.int32, shape=[None], name="keys") keys_identity = tf.identity(keys_placeholder, name="inference_keys") sess = tf.Session() sess.run(tf.global_variables_initializer()) model_signature = signature_def_utils.build_signature_def( inputs={ "keys": utils.build_tensor_info(keys_placeholder), }, outputs={ "keys": utils.build_tensor_info(keys_identity), }, method_name=signature_constants.PREDICT_METHOD_NAME) export_path = os.path.join( compat.as_bytes(model_path), compat.as_bytes(str(model_version))) builder = saved_model_builder.SavedModelBuilder(export_path) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], clear_devices=True, signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: model_signature, }) builder.save()
def build_signature(inputs, outputs): """Build the signature. Not using predic_signature_def in saved_model because it is replacing the tensor name, b/35900497. Args: inputs: a dictionary of tensor name to tensor outputs: a dictionary of tensor name to tensor Returns: The signature, a SignatureDef proto. """ signature_inputs = {key: saved_model_utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {key: saved_model_utils.build_tensor_info(tensor) for key, tensor in outputs.items()} signature_def = signature_def_utils.build_signature_def( signature_inputs, signature_outputs, signature_constants.PREDICT_METHOD_NAME) return signature_def
def export_saved_model(sess, export_path, input_tensor, output_tensor): from tensorflow.python.saved_model import builder as saved_model_builder from tensorflow.python.saved_model import signature_constants from tensorflow.python.saved_model import signature_def_utils from tensorflow.python.saved_model import tag_constants from tensorflow.python.saved_model import utils builder = saved_model_builder.SavedModelBuilder(export_path) prediction_signature = signature_def_utils.build_signature_def( inputs={'images': utils.build_tensor_info(input_tensor)}, outputs={'scores': utils.build_tensor_info(output_tensor)}, method_name=signature_constants.PREDICT_METHOD_NAME) legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op') builder.add_meta_graph_and_variables(sess, [tag_constants.SERVING], signature_def_map={ 'predict_images': prediction_signature, }, legacy_init_op=legacy_init_op) builder.save()
def _prepare_signature(layers: dict, model_keys): if tf_version.split(".")[0] == "2": disable_eager_execution() signature = {} for key, value in model_keys.items(): if value in layers.keys(): x = array_ops.placeholder( dtype=type_mapping[layers[value].precision], shape=layers[value].shape, name=value) x_tensor_info = build_tensor_info(x) signature[key] = x_tensor_info return signature
def testBuildTensorInfoSparse(self): x = array_ops.sparse_placeholder(dtypes.float32, [42, 69], name="x") x_tensor_info = utils.build_tensor_info(x) self.assertEqual(x.values.name, x_tensor_info.coo_sparse.values_tensor_name) self.assertEqual(x.indices.name, x_tensor_info.coo_sparse.indices_tensor_name) self.assertEqual(x.dense_shape.name, x_tensor_info.coo_sparse.dense_shape_tensor_name) self.assertEqual(types_pb2.DT_FLOAT, x_tensor_info.dtype) self.assertEqual(2, len(x_tensor_info.tensor_shape.dim)) self.assertEqual(42, x_tensor_info.tensor_shape.dim[0].size) self.assertEqual(69, x_tensor_info.tensor_shape.dim[1].size)
def build_inputs_and_outputs(self): if not self.slice_features: serialized_examples = tf.placeholder(tf.string, shape=(None, )) fn = lambda x: self.build_prediction_graph(x) decodedPrediction = (tf.map_fn(fn, serialized_examples, dtype=(tf.int32))) else: serialized_examples = tf.placeholder(tf.string, shape=(None, )) decodedPrediction = ( self.build_prediction_graph(serialized_examples)) inputs = { "example_bytes": saved_model_utils.build_tensor_info(serialized_examples) } outputs = { "predictions": saved_model_utils.build_tensor_info(decodedPrediction) } return inputs, outputs
def testBuildTensorInfoSparse(self): x = array_ops.sparse_placeholder(dtypes.float32, [42, 69], name="x") x_tensor_info = utils.build_tensor_info(x) self.assertEqual(x.values.name, x_tensor_info.coo_sparse.values_tensor_name) self.assertEqual(x.indices.name, x_tensor_info.coo_sparse.indices_tensor_name) self.assertEqual(x.dense_shape.name, x_tensor_info.coo_sparse.dense_shape_tensor_name) self.assertEqual(types_pb2.DT_FLOAT, x_tensor_info.dtype) self.assertEqual(2, len(x_tensor_info.tensor_shape.dim)) self.assertEqual(42, x_tensor_info.tensor_shape.dim[0].size) self.assertEqual(69, x_tensor_info.tensor_shape.dim[1].size)
def _SaveModel(self, model_dir, output_dir): saved_model_builder = builder.SavedModelBuilder(output_dir) graph = ops.Graph() with session.Session(graph=graph) as sess: with graph.device('/GPU:0'): x = array_ops.placeholder( shape=(None, 28, 28, 1), dtype=dtypes.float32, name=INPUT_NODE_NAME) self._BuildGraph(x) self._LoadWeights(model_dir, sess) input_tensor = graph.get_tensor_by_name(INPUT_NODE_NAME + ':0') output = graph.get_tensor_by_name(OUTPUT_NODE_NAME + ':0') signature_def = signature_def_utils.build_signature_def( inputs={'input': saved_model_utils.build_tensor_info(input_tensor)}, outputs={'output': saved_model_utils.build_tensor_info(output)}, method_name=signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY) saved_model_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def }) saved_model_builder.save()
def export(model_version, model_dir, sess, inputs, y_op): """导出tensorflow_serving可用的模型(Saved Model方式)(推荐) prediction_signature必备的三个参数分别是输入inputs、输出outputs和方法名method_name,如果缺失方法名将会报错:“grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.INTERNAL, details="Expected prediction signature method_name to be one of {tensorflow/serving/predict, tensorflow/serving/classify, tensorflow/serving/regress}. Was: ")”。每一个SavedModel关联着一个独立的checkpoint。每一个图元都绑定一个或多个标签,这些标签用来明确图元被加载的方式。标签只接受两种类型:serve或者train,保存时可以同时包含两个标签。其中tag_constants.SERVING = "serve",tag_constants.TRAINING = "train"。模型用于TensorFlow Serving时,标签必须包含serve类型。如果标签只包含train类型,TensorFlow Serving加载模型时会报错:“E tensorflow_serving/core/aspired_versions_manager.cc:351] Servable {name: default version: 2} cannot be loaded: Not found: Could not find meta graph def matching supplied tags.”。定义signature_def_map时注意定义默认服务签名键,如果缺少则会报错:“grpc.framework.interfaces.face.face.AbortionError: AbortionError(code=StatusCode.FAILED_PRECONDITION, details="Default serving signature key not found.")”。 """ if model_version <= 0: print('Please specify a positive value for version number.') sys.exit() path = os.path.dirname(os.path.abspath(model_dir)) if os.path.isdir(path) == False: logging.warning('Path (%s) not exists, making directories...', path) os.makedirs(path) export_path = os.path.join( compat.as_bytes(model_dir), compat.as_bytes(str(model_version))) if os.path.isdir(export_path) == True: logging.warning('Path (%s) exists, removing directories...', export_path) shutil.rmtree(export_path) builder = saved_model_builder.SavedModelBuilder(export_path) tensor_info_x = utils.build_tensor_info(inputs) tensor_info_y = utils.build_tensor_info(y_op) prediction_signature = signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'y': tensor_info_y}, method_name=signature_constants.PREDICT_METHOD_NAME) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ 'predict_text': prediction_signature, signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature }) builder.save()
def save_tf_model(sess, model_name, model_version, input_tensor_dict, out_tensor_dict, force_write=False): if (type(model_version) is not int): print("Error! input model_version must be a int number! eg. 1") return export_path = os.path.join(compat.as_bytes(model_name), compat.as_bytes(str(model_version))) if (force_write and os.path.exists(export_path)): shutil.rmtree(export_path) print('Exporting trained model to', export_path) builder = saved_model_builder.SavedModelBuilder(export_path) signature_inputs = { key: utils.build_tensor_info(tensor) for key, tensor in input_tensor_dict.items() } signature_outputs = { key: utils.build_tensor_info(tensor) for key, tensor in out_tensor_dict.items() } prediction_signature = signature_def_utils.build_signature_def( inputs=signature_inputs, outputs=signature_outputs, method_name=signature_constants.PREDICT_METHOD_NAME) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={model_name: prediction_signature}, clear_devices=True) builder.save() print('Done exporting!')
def regression_signature_def(examples, predictions): """Creates regression signature from given examples and predictions. This function produces signatures intended for use with the TensorFlow Serving Regress API (tensorflow_serving/apis/prediction_service.proto), and so constrains the input and output types to those allowed by TensorFlow Serving. Args: examples: A string `Tensor`, expected to accept serialized tf.Examples. predictions: A float `Tensor`. Returns: A regression-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('Regression examples cannot be None.') if not isinstance(examples, ops.Tensor): raise ValueError('Regression examples must be a string Tensor.') if predictions is None: raise ValueError('Regression predictions cannot be None.') input_tensor_info = utils.build_tensor_info(examples) if input_tensor_info.dtype != types_pb2.DT_STRING: raise ValueError('Regression examples must be a string Tensor.') signature_inputs = {signature_constants.REGRESS_INPUTS: input_tensor_info} output_tensor_info = utils.build_tensor_info(predictions) if output_tensor_info.dtype != types_pb2.DT_FLOAT: raise ValueError('Regression output must be a float Tensor.') signature_outputs = {signature_constants.REGRESS_OUTPUTS: output_tensor_info} signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.REGRESS_METHOD_NAME) return signature_def
def classification_signature_def(examples, classes, scores): """Creates classification signature from given examples and predictions. Args: examples: `Tensor`. classes: `Tensor`. scores: `Tensor`. Returns: A classification-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('examples cannot be None for classification.') if classes is None and scores is None: raise ValueError('classes and scores cannot both be None for ' 'classification.') input_tensor_info = utils.build_tensor_info(examples) signature_inputs = {signature_constants.CLASSIFY_INPUTS: input_tensor_info} signature_outputs = {} if classes is not None: classes_tensor_info = utils.build_tensor_info(classes) signature_outputs[signature_constants.CLASSIFY_OUTPUT_CLASSES] = ( classes_tensor_info) if scores is not None: scores_tensor_info = utils.build_tensor_info(scores) signature_outputs[signature_constants.CLASSIFY_OUTPUT_SCORES] = ( scores_tensor_info) signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.CLASSIFY_METHOD_NAME) return signature_def
def classification_signature_def(examples, classes, scores): """Creates classification signature from given examples and predictions. Args: examples: `Tensor`. classes: `Tensor`. scores: `Tensor`. Returns: A classification-flavored signature_def. Raises: ValueError: If examples is `None`. """ if examples is None: raise ValueError('examples cannot be None for classification.') if classes is None and scores is None: raise ValueError('classes and scores cannot both be None for ' 'classification.') input_tensor_info = utils.build_tensor_info(examples) signature_inputs = {signature_constants.CLASSIFY_INPUTS: input_tensor_info} signature_outputs = {} if classes is not None: classes_tensor_info = utils.build_tensor_info(classes) signature_outputs[signature_constants.CLASSIFY_OUTPUT_CLASSES] = ( classes_tensor_info) if scores is not None: scores_tensor_info = utils.build_tensor_info(scores) signature_outputs[signature_constants.CLASSIFY_OUTPUT_SCORES] = ( scores_tensor_info) signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.CLASSIFY_METHOD_NAME) return signature_def
def main(argv): if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') shutil.rmtree(FLAGS.saved_model_path) # Create the graph zero = constant_op.constant(0) one = variable_scope.get_variable(name='y', initializer=[1]) neg_one = variable_scope.get_variable(name='z', initializer=[-1]) x = array_ops.placeholder(dtypes.int32, shape=(), name='input') r = control_flow_ops.cond( x < zero, lambda: math_ops.cast(math_ops.greater(x, one), dtypes.int32), lambda: math_ops.cast(math_ops.greater(x, neg_one), dtypes.int32)) sess = session.Session() sess.run(variables.global_variables_initializer()) sm_builder = builder.SavedModelBuilder(FLAGS.saved_model_path) tensor_info_x = utils.build_tensor_info(x) tensor_info_r = utils.build_tensor_info(r) func_signature = (signature_def_utils.build_signature_def( inputs={'x': tensor_info_x}, outputs={'r': tensor_info_r}, method_name=signature_constants.PREDICT_METHOD_NAME)) sm_builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ 'serving_default': func_signature, signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: func_signature, }, strip_default_attrs=True) sm_builder.save()
def testBuildTensorInfoSparse(self): x = sparse_tensor.SparseTensor(indices=[[3, 3], [4, 4], [5, 5]], values=[103.0, 104.0, 105.0], dense_shape=[42, 69]) x_tensor_info = utils.build_tensor_info(x) self.assertEqual(x.values.name, x_tensor_info.coo_sparse.values_tensor_name) self.assertEqual(x.indices.name, x_tensor_info.coo_sparse.indices_tensor_name) self.assertEqual(x.dense_shape.name, x_tensor_info.coo_sparse.dense_shape_tensor_name) self.assertEqual(types_pb2.DT_FLOAT, x_tensor_info.dtype) self.assertEqual(2, len(x_tensor_info.tensor_shape.dim)) self.assertEqual(42, x_tensor_info.tensor_shape.dim[0].size) self.assertEqual(69, x_tensor_info.tensor_shape.dim[1].size)
def predict_signature_def(inputs, outputs): """Creates prediction signature from given inputs and outputs. Args: inputs: dict of string to `Tensor`. outputs: dict of string to `Tensor`. Returns: A prediction-flavored signature_def. Raises: ValueError: If inputs or outputs is `None`. """ if inputs is None or not inputs: raise ValueError('inputs cannot be None or empty for prediction.') if outputs is None: raise ValueError('outputs cannot be None or empty for prediction.') # If there's only one input or output, we can standardize keys if len(inputs) == 1: (_, value), = inputs.items() inputs = {signature_constants.PREDICT_INPUTS: value} if len(outputs) == 1: (_, value), = outputs.items() outputs = {signature_constants.PREDICT_OUTPUTS: value} signature_inputs = {key: utils.build_tensor_info(tensor) for key, tensor in inputs.items()} signature_outputs = {key: utils.build_tensor_info(tensor) for key, tensor in outputs.items()} signature_def = build_signature_def( signature_inputs, signature_outputs, signature_constants.PREDICT_METHOD_NAME) return signature_def
def testGetTensorFromInfoInScope(self): # Build a TensorInfo with name "bar/x:0". with ops.Graph().as_default(): with ops.name_scope("bar"): unscoped = array_ops.placeholder(dtypes.float32, 1, name="x") tensor_info = utils.build_tensor_info(unscoped) self.assertEqual("bar/x:0", tensor_info.name) # Build a graph with node "foo/bar/x:0", akin to importing into scope foo. with ops.Graph().as_default(): with ops.name_scope("foo"): with ops.name_scope("bar"): expected = array_ops.placeholder(dtypes.float32, 1, name="x") self.assertEqual("foo/bar/x:0", expected.name) # Test that tensor is found by prepending the import scope. actual = utils.get_tensor_from_tensor_info(tensor_info, import_scope="foo") self.assertEqual(expected.name, actual.name)
def main(): if os.path.exists(FLAGS.checkpoint_path) == False: os.makedirs(FLAGS.checkpoint_path) checkpoint_file_path = FLAGS.checkpoint_path + "/checkpoint.ckpt" latest_checkpoint_file_path = tf.train.latest_checkpoint( FLAGS.checkpoint_path) if os.path.exists(FLAGS.output_path) == False: os.makedirs(FLAGS.output_path) # Step 1: Construct the dataset op epoch_number = FLAGS.epoch_number if epoch_number <= 0: epoch_number = -1 train_buffer_size = FLAGS.train_batch_size * 3 validation_buffer_size = FLAGS.train_batch_size * 3 train_filename_list = [filename for filename in FLAGS.train_files.split(",")] train_filename_placeholder = tf.placeholder(tf.string, shape=[None]) train_dataset = tf.data.TFRecordDataset(train_filename_placeholder) train_dataset = train_dataset.map(parse_tfrecords_function).repeat( epoch_number).batch(FLAGS.train_batch_size).shuffle( buffer_size=train_buffer_size) train_dataset_iterator = train_dataset.make_initializable_iterator() batch_labels, batch_ids, batch_values = train_dataset_iterator.get_next() validation_filename_list = [ filename for filename in FLAGS.validation_files.split(",") ] validation_filename_placeholder = tf.placeholder(tf.string, shape=[None]) validation_dataset = tf.data.TFRecordDataset(validation_filename_placeholder) validation_dataset = validation_dataset.map(parse_tfrecords_function).repeat( ).batch(FLAGS.validation_batch_size).shuffle( buffer_size=validation_buffer_size) validation_dataset_iterator = validation_dataset.make_initializable_iterator( ) validation_labels, validation_ids, validation_values = validation_dataset_iterator.get_next( ) # Define the model logits = inference(batch_ids, batch_values, True) batch_labels = tf.to_int64(batch_labels) cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits( logits=logits, labels=batch_labels) loss = tf.reduce_mean(cross_entropy, name="loss") global_step = tf.Variable(0, name="global_step", trainable=False) if FLAGS.enable_lr_decay: logging.info( "Enable learning rate decay rate: {}".format(FLAGS.lr_decay_rate)) starter_learning_rate = FLAGS.learning_rate learning_rate = tf.train.exponential_decay( starter_learning_rate, global_step, 100000, FLAGS.lr_decay_rate, staircase=True) else: learning_rate = FLAGS.learning_rate optimizer = util.get_optimizer_by_name(FLAGS.optimizer, learning_rate) train_op = optimizer.minimize(loss, global_step=global_step) tf.get_variable_scope().reuse_variables() # Define accuracy op for train data train_accuracy_logits = inference(batch_ids, batch_values, False) train_softmax = tf.nn.softmax(train_accuracy_logits) train_correct_prediction = tf.equal( tf.argmax(train_softmax, 1), batch_labels) train_accuracy = tf.reduce_mean( tf.cast(train_correct_prediction, tf.float32)) # Define auc op for train data batch_labels = tf.cast(batch_labels, tf.int32) sparse_labels = tf.reshape(batch_labels, [-1, 1]) derived_size = tf.shape(batch_labels)[0] indices = tf.reshape(tf.range(0, derived_size, 1), [-1, 1]) concated = tf.concat(axis=1, values=[indices, sparse_labels]) outshape = tf.stack([derived_size, FLAGS.label_size]) new_train_batch_labels = tf.sparse_to_dense(concated, outshape, 1.0, 0.0) _, train_auc = tf.contrib.metrics.streaming_auc(train_softmax, new_train_batch_labels) # Define accuracy op for validate data validate_accuracy_logits = inference(validation_ids, validation_values, False) validate_softmax = tf.nn.softmax(validate_accuracy_logits) validate_batch_labels = tf.to_int64(validation_labels) validate_correct_prediction = tf.equal( tf.argmax(validate_softmax, 1), validate_batch_labels) validate_accuracy = tf.reduce_mean( tf.cast(validate_correct_prediction, tf.float32)) # Define auc op for validate data validate_batch_labels = tf.cast(validate_batch_labels, tf.int32) sparse_labels = tf.reshape(validate_batch_labels, [-1, 1]) derived_size = tf.shape(validate_batch_labels)[0] indices = tf.reshape(tf.range(0, derived_size, 1), [-1, 1]) concated = tf.concat(axis=1, values=[indices, sparse_labels]) outshape = tf.stack([derived_size, FLAGS.label_size]) new_validate_batch_labels = tf.sparse_to_dense(concated, outshape, 1.0, 0.0) _, validate_auc = tf.contrib.metrics.streaming_auc(validate_softmax, new_validate_batch_labels) # Define inference op sparse_index = tf.placeholder(tf.int64, [None, 2]) sparse_ids = tf.placeholder(tf.int64, [None]) sparse_values = tf.placeholder(tf.float32, [None]) sparse_shape = tf.placeholder(tf.int64, [2]) inference_ids = tf.SparseTensor(sparse_index, sparse_ids, sparse_shape) inference_values = tf.SparseTensor(sparse_index, sparse_values, sparse_shape) inference_logits = inference(inference_ids, inference_values, False) inference_softmax = tf.nn.softmax(inference_logits) inference_op = tf.argmax(inference_softmax, 1) keys_placeholder = tf.placeholder(tf.int32, shape=[None, 1]) keys = tf.identity(keys_placeholder) signature_def_map = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def_utils.build_signature_def( inputs={ "keys": utils.build_tensor_info(keys_placeholder), "indexs": utils.build_tensor_info(sparse_index), "ids": utils.build_tensor_info(sparse_ids), "values": utils.build_tensor_info(sparse_values), "shape": utils.build_tensor_info(sparse_shape) }, outputs={ "keys": utils.build_tensor_info(keys), "softmax": utils.build_tensor_info(inference_softmax), "prediction": utils.build_tensor_info(inference_op) }, method_name=signature_constants.PREDICT_METHOD_NAME) } # Initialize saver and summary saver = tf.train.Saver() tf.summary.scalar("loss", loss) tf.summary.scalar("train_accuracy", train_accuracy) tf.summary.scalar("train_auc", train_auc) tf.summary.scalar("validate_accuracy", validate_accuracy) tf.summary.scalar("validate_auc", validate_auc) summary_op = tf.summary.merge_all() init_op = [ tf.global_variables_initializer(), tf.local_variables_initializer() ] # Create session to run with tf.Session() as sess: writer = tf.summary.FileWriter(FLAGS.output_path, sess.graph) sess.run(init_op) sess.run( train_dataset_iterator.initializer, feed_dict={train_filename_placeholder: train_filename_list}) sess.run( validation_dataset_iterator.initializer, feed_dict={validation_filename_placeholder: validation_filename_list}) if FLAGS.mode == "train": # Restore session and start queue runner util.restore_from_checkpoint(sess, saver, latest_checkpoint_file_path) coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord, sess=sess) start_time = datetime.datetime.now() try: while not coord.should_stop(): if FLAGS.benchmark_mode: sess.run(train_op) else: _, step = sess.run([train_op, global_step]) # Print state while training if step % FLAGS.steps_to_validate == 0: loss_value, train_accuracy_value, train_auc_value, validate_accuracy_value, auc_value, summary_value = sess.run( [ loss, train_accuracy, train_auc, validate_accuracy, validate_auc, summary_op ]) end_time = datetime.datetime.now() logging.info( "[{}] Step: {}, loss: {}, train_acc: {}, train_auc: {}, valid_acc: {}, valid_auc: {}". format(end_time - start_time, step, loss_value, train_accuracy_value, train_auc_value, validate_accuracy_value, auc_value)) writer.add_summary(summary_value, step) saver.save(sess, checkpoint_file_path, global_step=step) start_time = end_time except tf.errors.OutOfRangeError: if FLAGS.benchmark_mode: print("Finish training for benchmark") exit(0) else: # Export the model after training util.save_model( FLAGS.model_path, FLAGS.model_version, sess, signature_def_map, is_save_graph=False) finally: coord.request_stop() coord.join(threads) elif FLAGS.mode == "save_model": if not util.restore_from_checkpoint(sess, saver, latest_checkpoint_file_path): logging.error("No checkpoint found, exit now") exit(1) util.save_model( FLAGS.model_path, FLAGS.model_version, sess, signature_def_map, is_save_graph=False) elif FLAGS.mode == "inference": if not util.restore_from_checkpoint(sess, saver, latest_checkpoint_file_path): logging.error("No checkpoint found, exit now") exit(1) # Load inference test data inference_result_file_name = "./inference_result.txt" inference_test_file_name = "./data/a8a_test.libsvm" labels = [] feature_ids = [] feature_values = [] feature_index = [] ins_num = 0 for line in open(inference_test_file_name, "r"): tokens = line.split(" ") labels.append(int(tokens[0])) feature_num = 0 for feature in tokens[1:]: feature_id, feature_value = feature.split(":") feature_ids.append(int(feature_id)) feature_values.append(float(feature_value)) feature_index.append([ins_num, feature_num]) feature_num += 1 ins_num += 1 # Run inference start_time = datetime.datetime.now() prediction, prediction_softmax = sess.run( [inference_op, inference_softmax], feed_dict={ sparse_index: feature_index, sparse_ids: feature_ids, sparse_values: feature_values, sparse_shape: [ins_num, FLAGS.feature_size] }) end_time = datetime.datetime.now() # Compute accuracy label_number = len(labels) correct_label_number = 0 for i in range(label_number): if labels[i] == prediction[i]: correct_label_number += 1 accuracy = float(correct_label_number) / label_number # Compute auc expected_labels = np.array(labels) predict_labels = prediction_softmax[:, 0] fpr, tpr, thresholds = metrics.roc_curve( expected_labels, predict_labels, pos_label=0) auc = metrics.auc(fpr, tpr) logging.info("[{}] Inference accuracy: {}, auc: {}".format( end_time - start_time, accuracy, auc)) # Save result into the file np.savetxt(inference_result_file_name, prediction_softmax, delimiter=",") logging.info( "Save result to file: {}".format(inference_result_file_name)) elif FLAGS.mode == "inference_with_tfrecords": if not util.restore_from_checkpoint(sess, saver, latest_checkpoint_file_path): logging.error("No checkpoint found, exit now") exit(1) # Load inference test data inference_result_file_name = "./inference_result.txt" inference_test_file_name = "./data/a8a/a8a_test.libsvm.tfrecords" batch_feature_index = [] batch_labels = [] batch_ids = [] batch_values = [] ins_num = 0 # Read from TFRecords files for serialized_example in tf.python_io.tf_record_iterator( inference_test_file_name): # Get serialized example from file example = tf.train.Example() example.ParseFromString(serialized_example) label = example.features.feature["label"].float_list.value ids = example.features.feature["ids"].int64_list.value values = example.features.feature["values"].float_list.value #print("label: {}, features: {}".format(label, " ".join([str(id) + ":" + str(value) for id, value in zip(ids, values)]))) batch_labels.append(label) # Notice that using extend() instead of append() to flatten the values batch_ids.extend(ids) batch_values.extend(values) for i in xrange(len(ids)): batch_feature_index.append([ins_num, i]) ins_num += 1 # Run inference start_time = datetime.datetime.now() prediction, prediction_softmax = sess.run( [inference_op, inference_softmax], feed_dict={ sparse_index: batch_feature_index, sparse_ids: batch_ids, sparse_values: batch_values, sparse_shape: [ins_num, FLAGS.feature_size] }) end_time = datetime.datetime.now() # Compute accuracy label_number = len(batch_labels) correct_label_number = 0 for i in range(label_number): if batch_labels[i] == prediction[i]: correct_label_number += 1 accuracy = float(correct_label_number) / label_number # Compute auc expected_labels = np.array(batch_labels) predict_labels = prediction_softmax[:, 0] fpr, tpr, thresholds = metrics.roc_curve( expected_labels, predict_labels, pos_label=0) auc = metrics.auc(fpr, tpr) logging.info("[{}] Inference accuracy: {}, auc: {}".format( end_time - start_time, accuracy, auc)) # Save result into the file np.savetxt(inference_result_file_name, prediction_softmax, delimiter=",") logging.info( "Save result to file: {}".format(inference_result_file_name))