____tz_zs
Protocol Buffer 是谷歌开发的一种语言无关、平台无关、可扩展的序列化结构数据格式,在 tensorflow 中可以理解为处理结构化数据的工具,用于序列化结构化数据。
关于Protocol Buffer的介绍: https://developers.google.com/protocol-buffers/docs/overview
Protocol Buffer的编码方式: https://developers.google.com/protocol-buffers/docs/encoding
Protocol Bufferdf 定义数据格式的文件一般保存在.proto文件中。每一个 message 代表了一类结构化数据,message 里面定义了每一个属性的类型和名字,Protocol Buffer 里属性的类型可以是像布尔型、整数型、实数型、字符型这些基本类型,也可以是另一个 message。可用 required(可选的)、required(必须的)、repeated(可重复的)说明属性是否可选的、必须的或者可重复的。
以json格式导出MetaGraph元图的数据
元图是由 MetaGraphDef Protocol Buffer 定义的一类结构化数据
# -*- coding: utf-8 -*-
"""
@author: tz_zs
以json格式导出MetaGraph元图的数据
"""
import tensorflow as tf
v1 = tf.Variable(tf.constant(1.0, shape=[1]), name="v1")
v2 = tf.Variable(tf.constant(2.0, shape=[1]), name="v2")
result = v1 + v2
saver = tf.train.Saver()
saver.export_meta_graph("/path/to/model.ckpt.json", as_text=True)
meta_info_def {
stripped_op_list {
op {
name: "Add"
input_arg {
name: "x"
type_attr: "T"
}
input_arg {
name: "y"
type_attr: "T"
}
output_arg {
name: "z"
type_attr: "T"
}
attr {
name: "T"
type: "type"
allowed_values {
list {
type: DT_HALF
type: DT_FLOAT
type: DT_DOUBLE
type: DT_UINT8
type: DT_INT8
type: DT_INT16
type: DT_INT32
type: DT_INT64
type: DT_COMPLEX64
type: DT_COMPLEX128
type: DT_STRING
}
}
}
}
op {
name: "Assign"
input_arg {
name: "ref"
type_attr: "T"
is_ref: true
}
input_arg {
name: "value"
type_attr: "T"
}
output_arg {
name: "output_ref"
type_attr: "T"
is_ref: true
}
attr {
name: "T"
type: "type"
}
attr {
name: "validate_shape"
type: "bool"
default_value {
b: true
}
}
attr {
name: "use_locking"
type: "bool"
default_value {
b: true
}
}
allows_uninitialized_input: true
}
op {
name: "Const"
output_arg {
name: "output"
type_attr: "dtype"
}
attr {
name: "value"
type: "tensor"
}
attr {
name: "dtype"
type: "type"
}
}
op {
name: "Identity"
input_arg {
name: "input"
type_attr: "T"
}
output_arg {
name: "output"
type_attr: "T"
}
attr {
name: "T"
type: "type"
}
}
op {
name: "NoOp"
}
op {
name: "RestoreV2"
input_arg {
name: "prefix"
type: DT_STRING
}
input_arg {
name: "tensor_names"
type: DT_STRING
}
input_arg {
name: "shape_and_slices"
type: DT_STRING
}
output_arg {
name: "tensors"
type_list_attr: "dtypes"
}
attr {
name: "dtypes"
type: "list(type)"
has_minimum: true
minimum: 1
}
}
op {
name: "SaveV2"
input_arg {
name: "prefix"
type: DT_STRING
}
input_arg {
name: "tensor_names"
type: DT_STRING
}
input_arg {
name: "shape_and_slices"
type: DT_STRING
}
input_arg {
name: "tensors"
type_list_attr: "dtypes"
}
attr {
name: "dtypes"
type: "list(type)"
has_minimum: true
minimum: 1
}
}
op {
name: "VariableV2"
output_arg {
name: "ref"
type_attr: "dtype"
is_ref: true
}
attr {
name: "shape"
type: "shape"
}
attr {
name: "dtype"
type: "type"
}
attr {
name: "container"
type: "string"
default_value {
s: ""
}
}
attr {
name: "shared_name"
type: "string"
default_value {
s: ""
}
}
is_stateful: true
}
}
tensorflow_version: "1.2.1"
tensorflow_git_version: "b\'unknown\'"
}
graph_def {
node {
name: "Const"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
}
float_val: 1.0
}
}
}
}
node {
name: "v1"
op: "VariableV2"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "container"
value {
s: ""
}
}
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "shape"
value {
shape {
dim {
size: 1
}
}
}
}
attr {
key: "shared_name"
value {
s: ""
}
}
}
node {
name: "v1/Assign"
op: "Assign"
input: "v1"
input: "Const"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_class"
value {
list {
s: "loc:@v1"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "use_locking"
value {
b: true
}
}
attr {
key: "validate_shape"
value {
b: true
}
}
}
node {
name: "v1/read"
op: "Identity"
input: "v1"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_class"
value {
list {
s: "loc:@v1"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
}
node {
name: "Const_1"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
}
float_val: 2.0
}
}
}
}
node {
name: "v2"
op: "VariableV2"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "container"
value {
s: ""
}
}
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "shape"
value {
shape {
dim {
size: 1
}
}
}
}
attr {
key: "shared_name"
value {
s: ""
}
}
}
node {
name: "v2/Assign"
op: "Assign"
input: "v2"
input: "Const_1"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_class"
value {
list {
s: "loc:@v2"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "use_locking"
value {
b: true
}
}
attr {
key: "validate_shape"
value {
b: true
}
}
}
node {
name: "v2/read"
op: "Identity"
input: "v2"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_class"
value {
list {
s: "loc:@v2"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
}
node {
name: "add"
op: "Add"
input: "v1/read"
input: "v2/read"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
}
node {
name: "save/Const"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
}
string_val: "model"
}
}
}
}
node {
name: "save/SaveV2/tensor_names"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 2
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
dim {
size: 2
}
}
string_val: "v1"
string_val: "v2"
}
}
}
}
node {
name: "save/SaveV2/shape_and_slices"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 2
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
dim {
size: 2
}
}
string_val: ""
string_val: ""
}
}
}
}
node {
name: "save/SaveV2"
op: "SaveV2"
input: "save/Const"
input: "save/SaveV2/tensor_names"
input: "save/SaveV2/shape_and_slices"
input: "v1"
input: "v2"
attr {
key: "dtypes"
value {
list {
type: DT_FLOAT
type: DT_FLOAT
}
}
}
}
node {
name: "save/control_dependency"
op: "Identity"
input: "save/Const"
input: "^save/SaveV2"
attr {
key: "T"
value {
type: DT_STRING
}
}
attr {
key: "_class"
value {
list {
s: "loc:@save/Const"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
}
}
}
}
}
node {
name: "save/RestoreV2/tensor_names"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
dim {
size: 1
}
}
string_val: "v1"
}
}
}
}
node {
name: "save/RestoreV2/shape_and_slices"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
dim {
size: 1
}
}
string_val: ""
}
}
}
}
node {
name: "save/RestoreV2"
op: "RestoreV2"
input: "save/Const"
input: "save/RestoreV2/tensor_names"
input: "save/RestoreV2/shape_and_slices"
attr {
key: "_output_shapes"
value {
list {
shape {
unknown_rank: true
}
}
}
}
attr {
key: "dtypes"
value {
list {
type: DT_FLOAT
}
}
}
}
node {
name: "save/Assign"
op: "Assign"
input: "v1"
input: "save/RestoreV2"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_class"
value {
list {
s: "loc:@v1"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "use_locking"
value {
b: true
}
}
attr {
key: "validate_shape"
value {
b: true
}
}
}
node {
name: "save/RestoreV2_1/tensor_names"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
dim {
size: 1
}
}
string_val: "v2"
}
}
}
}
node {
name: "save/RestoreV2_1/shape_and_slices"
op: "Const"
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "value"
value {
tensor {
dtype: DT_STRING
tensor_shape {
dim {
size: 1
}
}
string_val: ""
}
}
}
}
node {
name: "save/RestoreV2_1"
op: "RestoreV2"
input: "save/Const"
input: "save/RestoreV2_1/tensor_names"
input: "save/RestoreV2_1/shape_and_slices"
attr {
key: "_output_shapes"
value {
list {
shape {
unknown_rank: true
}
}
}
}
attr {
key: "dtypes"
value {
list {
type: DT_FLOAT
}
}
}
}
node {
name: "save/Assign_1"
op: "Assign"
input: "v2"
input: "save/RestoreV2_1"
attr {
key: "T"
value {
type: DT_FLOAT
}
}
attr {
key: "_class"
value {
list {
s: "loc:@v2"
}
}
}
attr {
key: "_output_shapes"
value {
list {
shape {
dim {
size: 1
}
}
}
}
}
attr {
key: "use_locking"
value {
b: true
}
}
attr {
key: "validate_shape"
value {
b: true
}
}
}
node {
name: "save/restore_all"
op: "NoOp"
input: "^save/Assign"
input: "^save/Assign_1"
}
versions {
producer: 22
}
}
saver_def {
filename_tensor_name: "save/Const:0"
save_tensor_name: "save/control_dependency:0"
restore_op_name: "save/restore_all"
max_to_keep: 5
keep_checkpoint_every_n_hours: 10000.0
version: V2
}
collection_def {
key: "trainable_variables"
value {
bytes_list {
value: "\n\004v1:0\022\tv1/Assign\032\tv1/read:0"
value: "\n\004v2:0\022\tv2/Assign\032\tv2/read:0"
}
}
}
collection_def {
key: "variables"
value {
bytes_list {
value: "\n\004v1:0\022\tv1/Assign\032\tv1/read:0"
value: "\n\004v2:0\022\tv2/Assign\032\tv2/read:0"
}
}
}
tensorflow 元图的 Protocol Buffer 数据格式的定义文件 meta_graph.proto
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/protobuf/meta_graph.proto
syntax = "proto3";
package tensorflow;
option cc_enable_arenas = true;
option java_outer_classname = "MetaGraphProtos";
option java_multiple_files = true;
option java_package = "org.tensorflow.framework";
import "google/protobuf/any.proto";
import "tensorflow/core/framework/graph.proto";
import "tensorflow/core/framework/op_def.proto";
import "tensorflow/core/framework/tensor_shape.proto";
import "tensorflow/core/framework/types.proto";
import "tensorflow/core/protobuf/saver.proto";
// NOTE: This protocol buffer is evolving, and will go through revisions in the
// coming months.
//
// Protocol buffer containing the following which are necessary to restart
// training, run inference. It can be used to serialize/de-serialize memory
// objects necessary for running computation in a graph when crossing the
// process boundary. It can be used for long term storage of graphs,
// cross-language execution of graphs, etc.
// MetaInfoDef
// GraphDef
// SaverDef
// CollectionDef
// TensorInfo
// SignatureDef
message MetaGraphDef {
// Meta information regarding the graph to be exported. To be used by users
// of this protocol buffer to encode information regarding their meta graph.
message MetaInfoDef {
// User specified Version string. Can be the name of the model and revision,
// steps this model has been trained to, etc.
string meta_graph_version = 1;
// A copy of the OpDefs used by the producer of this graph_def.
// Descriptions and Ops not used in graph_def are stripped out.
OpList stripped_op_list = 2;
// A serialized protobuf. Can be the time this meta graph is created, or
// modified, or name of the model.
google.protobuf.Any any_info = 3;
// User supplied tag(s) on the meta_graph and included graph_def.
//
// MetaGraphDefs should be tagged with their capabilities or use-cases.
// Examples: "train", "serve", "gpu", "tpu", etc.
// These tags enable loaders to access the MetaGraph(s) appropriate for a
// specific use-case or runtime environment.
repeated string tags = 4;
// The __version__ string of the tensorflow build used to write this graph.
// This will be populated by the framework, which will overwrite any user
// supplied value.
string tensorflow_version = 5;
// The __git_version__ string of the tensorflow build used to write this
// graph. This will be populated by the framework, which will overwrite any
// user supplied value.
string tensorflow_git_version = 6;
}
MetaInfoDef meta_info_def = 1;
// GraphDef.
GraphDef graph_def = 2;
// SaverDef.
SaverDef saver_def = 3;
// collection_def: Map from collection name to collections.
// See CollectionDef section for details.
map<string, CollectionDef> collection_def = 4;
// signature_def: Map from user supplied key for a signature to a single
// SignatureDef.
map<string, SignatureDef> signature_def = 5;
// Asset file def to be used with the defined graph.
repeated AssetFileDef asset_file_def = 6;
}
// CollectionDef should cover most collections.
// To add a user-defined collection, do one of the following:
// 1. For simple data types, such as string, int, float:
// tf.add_to_collection("your_collection_name", your_simple_value)
// strings will be stored as bytes_list.
//
// 2. For Protobuf types, there are three ways to add them:
// 1) tf.add_to_collection("your_collection_name",
// your_proto.SerializeToString())
//
// collection_def {
// key: "user_defined_bytes_collection"
// value {
// bytes_list {
// value: "queue_name: \"test_queue\"\n"
// }
// }
// }
//
// or
//
// 2) tf.add_to_collection("your_collection_name", str(your_proto))
//
// collection_def {
// key: "user_defined_string_collection"
// value {
// bytes_list {
// value: "\n\ntest_queue"
// }
// }
// }
//
// or
//
// 3) any_buf = any_pb2.Any()
// tf.add_to_collection("your_collection_name",
// any_buf.Pack(your_proto))
//
// collection_def {
// key: "user_defined_any_collection"
// value {
// any_list {
// value {
// type_url: "type.googleapis.com/tensorflow.QueueRunnerDef"
// value: "\n\ntest_queue"
// }
// }
// }
// }
//
// 3. For Python objects, implement to_proto() and from_proto(), and register
// them in the following manner:
// ops.register_proto_function("your_collection_name",
// proto_type,
// to_proto=YourPythonObject.to_proto,
// from_proto=YourPythonObject.from_proto)
// These functions will be invoked to serialize and de-serialize the
// collection. For example,
// ops.register_proto_function(ops.GraphKeys.GLOBAL_VARIABLES,
// proto_type=variable_pb2.VariableDef,
// to_proto=Variable.to_proto,
// from_proto=Variable.from_proto)
message CollectionDef {
// NodeList is used for collecting nodes in graph. For example
// collection_def {
// key: "summaries"
// value {
// node_list {
// value: "input_producer/ScalarSummary:0"
// value: "shuffle_batch/ScalarSummary:0"
// value: "ImageSummary:0"
// }
// }
message NodeList {
repeated string value = 1;
}
// BytesList is used for collecting strings and serialized protobufs. For
// example:
// collection_def {
// key: "trainable_variables"
// value {
// bytes_list {
// value: "\n\017conv1/weights:0\022\024conv1/weights/Assign
// \032\024conv1/weights/read:0"
// value: "\n\016conv1/biases:0\022\023conv1/biases/Assign\032
// \023conv1/biases/read:0"
// }
// }
// }
message BytesList {
repeated bytes value = 1;
}
// Int64List is used for collecting int, int64 and long values.
message Int64List {
repeated int64 value = 1 [packed = true];
}
// FloatList is used for collecting float values.
message FloatList {
repeated float value = 1 [packed = true];
}
// AnyList is used for collecting Any protos.
message AnyList {
repeated google.protobuf.Any value = 1;
}
oneof kind {
NodeList node_list = 1;
BytesList bytes_list = 2;
Int64List int64_list = 3;
FloatList float_list = 4;
AnyList any_list = 5;
}
}
// Information about a Tensor necessary for feeding or retrieval.
message TensorInfo {
// For sparse tensors, The COO encoding stores a triple of values, indices,
// and shape.
message CooSparse {
// The shape of the values Tensor is [?]. Its dtype must be the dtype of
// the SparseTensor as a whole, given in the enclosing TensorInfo.
string values_tensor_name = 1;
// The indices Tensor must have dtype int64 and shape [?, ?].
string indices_tensor_name = 2;
// The dynamic logical shape represented by the SparseTensor is recorded in
// the Tensor referenced here. It must have dtype int64 and shape [?].
string dense_shape_tensor_name = 3;
}
oneof encoding {
// For dense `Tensor`s, the name of the tensor in the graph.
string name = 1;
// There are many possible encodings of sparse matrices
// (https://en.wikipedia.org/wiki/Sparse_matrix). Currently, TensorFlow
// uses only the COO encoding. This is supported and documented in the
// SparseTensor Python class.
CooSparse coo_sparse = 4;
}
DataType dtype = 2;
// The static shape should be recorded here, to the extent that it can
// be known in advance. In the case of a SparseTensor, this field describes
// the logical shape of the represented tensor (aka dense_shape).
TensorShapeProto tensor_shape = 3;
}
// SignatureDef defines the signature of a computation supported by a TensorFlow
// graph.
//
// For example, a model with two loss computations, sharing a single input,
// might have the following signature_def map.
//
// Note that across the two SignatureDefs "loss_A" and "loss_B", the input key,
// output key, and method_name are identical, and will be used by system(s) that
// implement or rely upon this particular loss method. The output tensor names
// differ, demonstrating how different outputs can exist for the same method.
//
// signature_def {
// key: "loss_A"
// value {
// inputs {
// key: "input"
// value {
// name: "input:0"
// dtype: DT_STRING
// tensor_shape: ...
// }
// }
// outputs {
// key: "loss_output"
// value {
// name: "loss_output_A:0"
// dtype: DT_FLOAT
// tensor_shape: ...
// }
// }
// }
// ...
// method_name: "some/package/compute_loss"
// }
// signature_def {
// key: "loss_B"
// value {
// inputs {
// key: "input"
// value {
// name: "input:0"
// dtype: DT_STRING
// tensor_shape: ...
// }
// }
// outputs {
// key: "loss_output"
// value {
// name: "loss_output_B:0"
// dtype: DT_FLOAT
// tensor_shape: ...
// }
// }
// }
// ...
// method_name: "some/package/compute_loss"
// }
message SignatureDef {
// Named input parameters.
map<string, TensorInfo> inputs = 1;
// Named output parameters.
map<string, TensorInfo> outputs = 2;
// Extensible method_name information enabling third-party users to mark a
// SignatureDef as supporting a particular method. This enables producers and
// consumers of SignatureDefs, e.g. a model definition library and a serving
// library to have a clear hand-off regarding the semantics of a computation.
//
// Note that multiple SignatureDefs in a single MetaGraphDef may have the same
// method_name. This is commonly used to support multi-headed computation,
// where a single graph computation may return multiple results.
string method_name = 3;
}
// An asset file def for a single file or a set of sharded files with the same
// name.
message AssetFileDef {
// The tensor to bind the asset filename to.
TensorInfo tensor_info = 1;
// The filename within an assets directory. Note: does not include the path
// prefix, i.e. directories. For an asset at /tmp/path/vocab.txt, the filename
// would be "vocab.txt".
string filename = 2;
}