import tensorflow as tf
import collections
from tensorflow.core.framework import tensor_shape_pb2
# 讀取模型
graph_def = tf.GraphDef()
with tf.gfile.FastGFile('./pb/model.pb', 'rb') as f:
graph_def.ParseFromString(f.read())
# 統計圖中的node,保存為map.其中 key : value = op.name : op
input_node_map = {}
for node in graph_def.node:
if node.name not in input_node_map.keys():
input_node_map[node.name] = node
else:
raise ValueError("Duplicate node names detected for ", node.name)
# 統計每一個op被使用的次數
node_reference_count = collections.defaultdict(int)
output_node_names = ['xnet/Softmax']
for node in graph_def.node:
for input_name in node.input:
stripped_name = input_name
node_reference_count[stripped_name] += 1
for output_name in output_node_names:
node_reference_count[output_name] += 1
# 刪除old_op
old_op = input_node_map['xnet/Layer_Conv_1/Conv2D']
node_reference_count['xnet/Layer_Conv_1/Conv2D'] -= 1
# 創建新的op
new_node = tf.NodeDef()
new_node.op = 'Conv2D'
new_node.name = 'new_Conv_1'
for input_name in old_op.input:
new_node.input.extend([input_name])
new_node.attr["T"].CopyFrom(tf.AttrValue(type=tf.float32.as_datatype_enum)) # (old_op.attr["T"])
new_node.attr["use_cudnn_on_gpu"].CopyFrom(tf.AttrValue(b=1)) # (old_op.attr["use_cudnn_on_gpu"])
stride_list = [1, 2, 2, 1]
new_node.attr["strides"].CopyFrom(tf.AttrValue(list=tf.AttrValue.ListValue(i=stride_list))) # (old_op.attr["strides"])
new_node.attr["padding"].CopyFrom(tf.AttrValue(s=b'VALID')) # (old_op.attr["padding"])
# 創建const類型的op,僅作為測試,本實驗中不添加入graph
new_const = tf.NodeDef()
new_const.op = 'Const'
new_const.name = 'new_Const'
new_const.attr['dtype'].CopyFrom(tf.AttrValue(type=tf.float32.as_datatype_enum))
new_const.attr['value'].CopyFrom(
tf.AttrValue(tensor=tf.make_tensor_proto([4, 5, 0, 0, 8, 0, 7, 0], tf.float32, [4, 2])))
new_const.attr['_output_shapes'].CopyFrom(
tf.AttrValue(list=tf.AttrValue.ListValue(shape=[tensor_shape_pb2.TensorShapeProto(
dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=4), tensor_shape_pb2.TensorShapeProto.Dim(size=2)])])))
# 將new_node作為輸入賦值給圖中節點
for node in graph_def.node:
if old_op.name in node.input:
for i, name in enumerate(node.input):
if name == old_op.name:
node.input[i] = new_node.name
print('success_1')
# 定義一個新圖
graph_def_new = tf.GraphDef()
for node in graph_def.node:
if node_reference_count[node.name] < 1:
continue
new = tf.NodeDef()
new.CopyFrom(node)
graph_def_new.node.extend([new])
graph_def_new.node.extend([new_node])
# graph_def_new.node.extend([new_const])
# 將新圖注入到默認的Graph中
tf.import_graph_def(graph_def_new, name='') # Imports `graph_def` into the current default `Graph`
# 測試案例
with tf.Session() as sess:
tf.train.write_graph(sess.graph_def, logdir='./pb', name='graph_def_new.pb')
OP的信息:
name: "xnet/Layer_FC_32/xw_plus_b"
op: "BiasAdd"
input: "xnet/Layer_FC_32/xw_plus_b/MatMul"
input: "xnet/Layer_FC_32/biases/read"
attr
{
key: "T"
value {type: DT_FLOAT}
}
attr
{
key: "data_format"
value {s: "NHWC"}
}
在tensorflow中,OP主要包括以下信息:name, op , input, attr
name--類型string。 在模型定義的時候由工程師定義,如果工程師沒有定義的話會自動的利用op作為其值
op--類型string。表示這是一個什么op,比如加減乘除,當在運行的時候,編譯器會更具op調用相應的算子來做計算
input--類型list.。列表中包含了該節點輸入,是有序的,不可以被assign
attr--類型map。map中的key和value一般是指該OP的配置信息
OP的操作:
1、op信息獲取
1. 通過Graph獲取op
op = tf.get_default_graph().get_Operations()
print(op[0])
print(op[0].name)
# 如果想獲得屬性或者input信息需要如下寫法
print(op[0].node_def.attr)
2.通過Graph_def獲取op
op = graph_def.node
print(op[0].name)
print(op[0].input)
2、op的創建無錫好的男科醫院 http://www.zzchnk.com/
在構建新的op的時候需要對op的屬性比較清楚,對於沒有default的屬性一定要做好初始化
1.根據已有的op創建新的op
new_node = tf.NodeDef() # 構建一個op對象,所有屬性都為空
new_node.op = 'Conv2D'
new_node.name = 'new_Conv_1'
for input_name in old_op.input: # 原始op的input導入進來
new_node.input.extend([input_name])
new_node.attr["T"].CopyFrom(old_op.attr["T"])
new_node.attr["use_cudnn_on_gpu"].CopyFrom(old_op.attr["use_cudnn_on_gpu"])
new_node.attr["strides"].CopyFrom(old_op.attr["strides"])
new_node.attr["padding"].CopyFrom(old_op.attr["padding"])
2.創建一個自定義的op
new_op = tf.NodeDef()
new_op.op = "Const"
new_op.name = conv_op.name
new_op.attr["dtype"].CopyFrom(tf.AttrValue( type=tf.int32.as_datatype_enum))
new_op.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto([0, 0, 0, 0, 0, 0, 0, 0], tf.int32, [4, 2])))
OP中attr為map,每一個map中key為字符串,value為的類型由下面9種,每種對應的原型如下表所示:
repeated bytes s = 2; // "list(string)"
repeated int64 i = 3 [packed = true]; // "list(int)"
repeated float f = 4 [packed = true]; // "list(float)"
repeated bool b = 5 [packed = true]; // "list(bool)"
repeated DataType type = 6 [packed = true]; // "list(type)"
repeated TensorShapeProto shape = 7; // "list(shape)"
repeated TensorProto tensor = 8; // "list(tensor)"
repeated NameAttrList func = 9; // "list(attr)"
list 也為value的一種類型
每一種類型初始化方式:
CopyFrom(tf.AttrValue( s=b'hello,world'))
CopyFrom(tf.AttrValue( i=88 ))
CopyFrom(tf.AttrValue( f=88.0 ))
CopyFrom(tf.AttrValue( b=1/0 ))
new_op.attr["dtype"].CopyFrom(tf.AttrValue( type=tf.int32.as_datatype_enum))
from tensorflow.core.framework import tensor_shape_pb2
tensor_shape_pb2.TensorShapeProto(dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=-1 if d.value is None else d.value) for d in dims])
new_op.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto([0, 0, 0, 0, 0, 0, 0, 0], tf.int32, [4, 2])))
func目前沒有沒有遇到過
stride_list = [1, 2, 2, 1]
new_node.attr["strides"].CopyFrom(tf.AttrValue(list=tf.AttrValue.ListValue(i=stride_list)))
import tensorflow as tf
import collections
from tensorflow.core.framework import tensor_shape_pb2
# 讀取模型
graph_def = tf.GraphDef()
with tf.gfile.FastGFile('./pb/model.pb', 'rb') as f:
graph_def.ParseFromString(f.read())
# 統計圖中的node,保存為map.其中 key : value = op.name : op
input_node_map = {}
for node in graph_def.node:
if node.name not in input_node_map.keys():
input_node_map[node.name] = node
else:
raise ValueError("Duplicate node names detected for ", node.name)
# 統計每一個op被使用的次數
node_reference_count = collections.defaultdict(int)
output_node_names = ['xnet/Softmax']
for node in graph_def.node:
for input_name in node.input:
stripped_name = input_name
node_reference_count[stripped_name] += 1
for output_name in output_node_names:
node_reference_count[output_name] += 1
# 刪除old_op
old_op = input_node_map['xnet/Layer_Conv_1/Conv2D']
node_reference_count['xnet/Layer_Conv_1/Conv2D'] -= 1
# 創建新的op
new_node = tf.NodeDef()
new_node.op = 'Conv2D'
new_node.name = 'new_Conv_1'
for input_name in old_op.input:
new_node.input.extend([input_name])
new_node.attr["T"].CopyFrom(tf.AttrValue(type=tf.float32.as_datatype_enum)) # (old_op.attr["T"])
new_node.attr["use_cudnn_on_gpu"].CopyFrom(tf.AttrValue(b=1)) # (old_op.attr["use_cudnn_on_gpu"])
stride_list = [1, 2, 2, 1]
new_node.attr["strides"].CopyFrom(tf.AttrValue(list=tf.AttrValue.ListValue(i=stride_list))) # (old_op.attr["strides"])
new_node.attr["padding"].CopyFrom(tf.AttrValue(s=b'VALID')) # (old_op.attr["padding"])
# 創建const類型的op,僅作為測試,本實驗中不添加入graph
new_const = tf.NodeDef()
new_const.op = 'Const'
new_const.name = 'new_Const'
new_const.attr['dtype'].CopyFrom(tf.AttrValue(type=tf.float32.as_datatype_enum))
new_const.attr['value'].CopyFrom(
tf.AttrValue(tensor=tf.make_tensor_proto([4, 5, 0, 0, 8, 0, 7, 0], tf.float32, [4, 2])))
new_const.attr['_output_shapes'].CopyFrom(
tf.AttrValue(list=tf.AttrValue.ListValue(shape=[tensor_shape_pb2.TensorShapeProto(
dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=4), tensor_shape_pb2.TensorShapeProto.Dim(size=2)])])))
# 將new_node作為輸入賦值給圖中節點
for node in graph_def.node:
if old_op.name in node.input:
for i, name in enumerate(node.input):
if name == old_op.name:
node.input[i] = new_node.name
print('success_1')
# 定義一個新圖
graph_def_new = tf.GraphDef()
for node in graph_def.node:
if node_reference_count[node.name] < 1:
continue
new = tf.NodeDef()
new.CopyFrom(node)
graph_def_new.node.extend([new])
graph_def_new.node.extend([new_node])
# graph_def_new.node.extend([new_const])
# 將新圖注入到默認的Graph中
tf.import_graph_def(graph_def_new, name='') # Imports `graph_def` into the current default `Graph`
# 測試案例
with tf.Session() as sess:
tf.train.write_graph(sess.graph_def, logdir='./pb', name='graph_def_new.pb')
OP的信息:
name: "xnet/Layer_FC_32/xw_plus_b"
op: "BiasAdd"
input: "xnet/Layer_FC_32/xw_plus_b/MatMul"
input: "xnet/Layer_FC_32/biases/read"
attr
{
key: "T"
value {type: DT_FLOAT}
}
attr
{
key: "data_format"
value {s: "NHWC"}
}
在tensorflow中,OP主要包括以下信息:name, op , input, attr
name--類型string。 在模型定義的時候由工程師定義,如果工程師沒有定義的話會自動的利用op作為其值
op--類型string。表示這是一個什么op,比如加減乘除,當在運行的時候,編譯器會更具op調用相應的算子來做計算
input--類型list.。列表中包含了該節點輸入,是有序的,不可以被assign
attr--類型map。map中的key和value一般是指該OP的配置信息
OP的操作:
1、op信息獲取
1. 通過Graph獲取op
op = tf.get_default_graph().get_Operations()
print(op[0])
print(op[0].name)
# 如果想獲得屬性或者input信息需要如下寫法
print(op[0].node_def.attr)
2.通過Graph_def獲取op
op = graph_def.node
print(op[0].name)
print(op[0].input)
2、op的創建
在構建新的op的時候需要對op的屬性比較清楚,對於沒有default的屬性一定要做好初始化
1.根據已有的op創建新的op
new_node = tf.NodeDef() # 構建一個op對象,所有屬性都為空
new_node.op = 'Conv2D'
new_node.name = 'new_Conv_1'
for input_name in old_op.input: # 原始op的input導入進來
new_node.input.extend([input_name])
new_node.attr["T"].CopyFrom(old_op.attr["T"])
new_node.attr["use_cudnn_on_gpu"].CopyFrom(old_op.attr["use_cudnn_on_gpu"])
new_node.attr["strides"].CopyFrom(old_op.attr["strides"])
new_node.attr["padding"].CopyFrom(old_op.attr["padding"])
2.創建一個自定義的op
new_op = tf.NodeDef()
new_op.op = "Const"
new_op.name = conv_op.name
new_op.attr["dtype"].CopyFrom(tf.AttrValue( type=tf.int32.as_datatype_enum))
new_op.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto([0, 0, 0, 0, 0, 0, 0, 0], tf.int32, [4, 2])))
OP中attr為map,每一個map中key為字符串,value為的類型由下面9種,每種對應的原型如下表所示:
repeated bytes s = 2; // "list(string)"
repeated int64 i = 3 [packed = true]; // "list(int)"
repeated float f = 4 [packed = true]; // "list(float)"
repeated bool b = 5 [packed = true]; // "list(bool)"
repeated DataType type = 6 [packed = true]; // "list(type)"
repeated TensorShapeProto shape = 7; // "list(shape)"
repeated TensorProto tensor = 8; // "list(tensor)"
repeated NameAttrList func = 9; // "list(attr)"
list 也為value的一種類型
每一種類型初始化方式:
CopyFrom(tf.AttrValue( s=b'hello,world'))
CopyFrom(tf.AttrValue( i=88 ))
CopyFrom(tf.AttrValue( f=88.0 ))
CopyFrom(tf.AttrValue( b=1/0 ))
new_op.attr["dtype"].CopyFrom(tf.AttrValue( type=tf.int32.as_datatype_enum))
from tensorflow.core.framework import tensor_shape_pb2
tensor_shape_pb2.TensorShapeProto(dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=-1 if d.value is None else d.value) for d in dims])
new_op.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto([0, 0, 0, 0, 0, 0, 0, 0], tf.int32, [4, 2])))
func目前沒有沒有遇到過
stride_list = [1, 2, 2, 1]
new_node.attr["strides"].CopyFrom(tf.AttrValue(list=tf.AttrValue.ListValue(i=stride_list)))