Tensorflow替换静态图中的OP
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)))
Tensorflow替换静态图中的OP的更多相关文章
- Tensorflow选择性初始化图中的变量
import tensorflow as tf def initialize_uninitialized(sess): global_vars = tf.global_variables() is_n ...
- 如何设计一个高内聚低耦合的模块——MegEngine 中自定义 Op 系统的实践经验
作者:褚超群 | 旷视科技 MegEngine 架构师 背景介绍 在算法研究的过程中,算法同学们可能经常会尝试定义各种新的神经网络层(neural network layer),比如 Layer No ...
- 【UML 建模】UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
发现个好东西思维导图, 最近开始用MindManager整理博客 . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/deta ...
- UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
发现个好东西思维导图, 最近开始用MindManager整理博客 . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/deta ...
- 小白学PyTorch 动态图与静态图的浅显理解
文章来自公众号[机器学习炼丹术],回复"炼丹"即可获得海量学习资料哦! 目录 1 动态图的初步推导 2 动态图的叶子节点 3. grad_fn 4 静态图 本章节缕一缕PyTorc ...
- (第一章第二部分)TensorFlow框架之图与TensorBoard
系列博客链接: (一)TensorFlow框架介绍:https://www.cnblogs.com/kongweisi/p/11038395.html 本文概述: 说明图的基本使用 应用tf.Grap ...
- tensorflow 升级到1.9-rc0,生成静态图frozen graph.pb本地测试正常, 在其他版本(eg1.4版本)或者android下运行出错NodeDef mentions attr 'dilations' not in Op<name=Conv2D; signature=input:T, filter:T -> output:T; attr=T:type,allowed=[DT_
这时节点定义找不到NodeDef attr 'dilations' not in,说明执行版本的NodeDef不在节点定义上,两个不一致,分别是执行inference的代码和生成静态图节点不一致(当然 ...
- AI学习---TensorFlow框架介绍[图+会话+张量+变量OP+API]
TensorFlow的数据流图 TensorFlow的结构分析: 图 + 会话 TensorFlow = 构图阶段(数据与操作的执行步骤被描绘出一个图) + 执行图阶段(使用回话执行构建好的图中操作) ...
- Dive into TensorFlow系列(1)-静态图运行原理
接触过TensorFlow v1的朋友都知道,训练一个TF模型有三个步骤:定义输入和模型结构,创建tf.Session实例sess,执行sess.run()启动训练.不管是因为历史遗留代码或是团队保守 ...
随机推荐
- exception: TypeError: Cannot read property '_modulesNamespaceMap' of undefined at getModuleByNamespac
用 Vue.extend 创造的组件构造器和组件,默认是不集成 store 和 router 的. 比如 main.js 中的这个,其实是挂载在根组件 vm 中.并不是注入到全局 Vue 中.所以你用 ...
- python 一般处理
#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:afei# QQ:97259460# date = 2019/8/29 s_code1=''s_ ...
- 登陆服务器提示“You need to run "nvm install N/A" to install it before using it.”
一.登陆服务器提示“You need to run "nvm install N/A" to install it before using it.” 二.执行命令: nvm ls ...
- 使用 Laravel-Swagger 编写接口文档(php)
使用 Laravel-Swagger 编写接口文档 Table of Contents Swagger 文档管理 官方网站:https://swagger.io/ 快速编写你的 RESTFUL API ...
- Cisco ASA 5505配置详解(v8.3之前版本)
在配ASA 5505时用到的命令 2009-11-22 22:49 nat-control命令 在6.3的时候只要是穿越防火墙都需要创建转换项,比如:nat:static等等,没有转换项是不能穿越防火 ...
- 最新sublime3配C++11编译环境
sublime text 3. version 3.2.1 build 3207 Package control: install package : C++11 (v0.0.9; github.co ...
- DLL注入实践
Windows系统大量使用dll作为组件复用,应用程序也会通过dll实现功能模块的拆分.DLL注入技术是向一个正在运行的进程插入自有DLL的过程. Window下的代码注入 常见的Windows代码注 ...
- Docker守护式容器
1.什么是守护式容器 能够长期运行 没有交互式会话 适合运行应用程序和服务 2.以守护形式运行容器 运行交互式容器时以Ctrl+P Ctrl+Q 来退出容器,此时容器还在后台继续运行,我们可以通过do ...
- cmake安装与使用
CMake(cross platform make)是一个开源的跨平台工具系列,旨在构建,测试和打包软件. 使用指定名为CMakeLists.txt的配置文件可以控制软件的构建.测试和打包等流程. 通 ...
- PHP设计模式 - 访问者模式
访问者模式是一种行为型模式,访问者表示一个作用于某对象结构中各元素的操作.它可以在不修改各元素类的前提下定义作用于这些元素的新操作,即动态的增加具体访问者角色. 访问者模式利用了双重分派.先将访问者传 ...