两种从 TensorFlow 的 checkpoint生成 frozenpb 的方法
1. 从 ckpt-.data,ckpt-.index 和 .meta 生成 frozenpb
import os
import tensorflow as tf
from tensorflow.python.framework import graph_util
def freeze_graph(input_checkpoint,output_graph):
'''
:param input_checkpoint:
:param output_graph: PB模型保存路径
:return:
'''
# 指定输出的节点名称,该节点名称必须是原模型中存在的节点
output_node_names = "outputs"
saver = tf.train.import_meta_graph(os.path.join(os.path.split(input_checkpoint)[0], 'graph.meta'), clear_devices=True)
with tf.Session() as sess:
saver.restore(sess, input_checkpoint) #恢复图并得到数据
output_graph_def = graph_util.convert_variables_to_constants(
# 模型持久化,将变量值固定
sess=sess,
input_graph_def=sess.graph_def,# 等于:sess.graph_def
output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
with tf.gfile.GFile(output_graph, "wb") as f: #保存模型
f.write(output_graph_def.SerializeToString()) #序列化输出
print("%d ops in the final graph." % len(output_graph_def.node))
#得到当前图有几个操作节点
if __name__ == "__main__":
# 输入ckpt模型路径
input_checkpoint='ckpt_path/ckpt-10000'
# 输出pb模型的路径
out_pb_path="some_path/frozen_model.pb"
# 调用freeze_graph将ckpt转为pb
freeze_graph(input_checkpoint,out_pb_path)
2. 从网络代码和 ckpt-.data 文件生成 frozenpb
import tensorflow as tf
import os
from tensorflow.python.tools import freeze_graph
import network # 导入网络结构
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 设置GPU
model_path = "ckpt_path/ckpt-10000"
def main():
tf.reset_default_graph()
input_node = tf.placeholder(
tf.float32, shape=(None,112, 96, 3)
)
input_node = tf.identity(input_node,name="inputs") # 设置输入节点的名字,这里可以自定义名称
flow = network(input_node)
flow = tf.identity(flow, name="outs") # 设置输出类型以及输出的接口名字,为了之后的调用pb的时候使用
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, model_path)
# 保存图
tf.train.write_graph(sess.graph_def, "logdir/", "graph.pb")
# 把图和参数结构一起
freeze_graph.freeze_graph(
"logdir/graph.pb", # 上面保存的图结构 graph.pb
"",
False,
model_path,
"outs",
"save/restore_all", # 默认恢复所有
"save/Const:0", # 默认常量
"some_path/frozen.pb", # 保存frozen.pb
False,
"",
)
print("done")
if __name__ == "__main__":
main()
3. 打印 网络中节点的名字
import tensorflow as tf
if __name__ == "__main__":
checkpoint_path = '../model_fintune/ckpt-1400'
reader = tf.train.NewCheckpointReader(checkpoint_path)
var_to_shape_map = reader.get_variable_to_shape_map()
for key in var_to_shape_map:
print("tensor name: ", key)
# print(reader.get_tensor(key))
或者通过
import tensorflow as tf
def printTensors(pb_file):
# read pb into graph_def
with tf.gfile.GFile(pb_file, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
# import graph_def
with tf.Graph().as_default() as graph:
tf.import_graph_def(graph_def)
# print operations
for op in graph.get_operations():
print(op.name)
printTensors("path-to-my-pbfile.pb")
4. 两种方法对比
如果是自己的代码训练的模型,有网络结构,有 ckpt 文件,最好是使用第二种方法,使用起来很灵活,可以进行各种自定义,比如修改输入输出的节点名字,网络有多个路径的时候可以自定义输出路径。第一种方法,应该也能达到第二种方法的效果,因为它们本来就是等价的,可能会有些麻烦。第一种方法的好处就是快,不要去翻那些杂糅在一起的网络结构。
两种从 TensorFlow 的 checkpoint生成 frozenpb 的方法的更多相关文章
- linux两种增加交换分区(swap)的方法
在安装Oracle后,为使Oracle流畅运行,需要手动增加linux的交换分区(相当于Windows下的虚拟内存)的大小,本文介绍两种增加交换分区(swap)的方法. 第一种方法:新建分区 1.fd ...
- JAVA 中两种判断输入的是否是数字的方法__正则化_
JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengz ...
- 两种常用的jquery事件加载的方法 的区别
两种常用的jquery事件加载的方法 $(function(){}); window.onload=function(){} 第一个呢,是在DOM结构渲染完成以后调用的,这时候网页中一些资源还 ...
- Android中两种设置全屏或者无标题的方法
在开发中我们经常需要把我们的应用设置为全屏或者不想要title, 这里是有两种方法的,一种是在代码中设置,另一种方法是在配置文件里改: 一.在代码中设置: package jason.tutor; i ...
- JSONP和CORS两种跨域方式的优缺点及使用方法原理介绍
随着软件开发分工趋于精细,前后端开发分离成为趋势,前端同事负责前端页面的展示及页面逻辑处理,服务端同事负责业务逻辑处理同时通过API为前端提供数据也为前端提供数据的持久化能力,考虑到前后端同事开发工具 ...
- 两种解决IE6不支持固定定位的方法
有两种让IE6支持position:fixed1.用CSS执行表达式 *{margin:0;padding:0;} * html,* html body{ background-image:url(a ...
- 【DevCloud · 敏捷智库】两种你必须了解的常见敏捷估算方法
背景 在某开发团队辅导的回顾会议上,团队成员对于优化估计具体方法上达成了一致意见.询问是否有什么具体的估计方法来做估算. 问题分析 回顾意见上大家对本次Sprint的效果做回顾,其中80%的成员对于本 ...
- Django—Form两种解决表单数据无法动态刷新的方法
一.无法动态更新数据的实例 1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多” from django.db import models class Classes(models. ...
- 【Django】Django—Form两种解决表单数据无法动态刷新的方法
一.无法动态更新数据的实例 1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多” from django.db import models class Classes(models. ...
随机推荐
- sublime3 docblocker 注释插件的配置
sublime3 docblocker插件定制自己的注释,配置步骤 DocBlockr很好用,不仅仅可以自动生成注释,还可以手动编辑注释的格式. 安装方法: Cmd+Shift+P -> In ...
- java正则使用全记录!
一 开坑! 场景: 将动态uri中{} 替换成 至少出现一次的任意字符进行匹配, 比如 loclahost:8080/{name}/{9527} -> localhost:8080/.{1,} ...
- pycharm版本下载地址
https://www.runoob.com/w3cnote/pycharm-windows-install.html 下载社区版本,因为免费 其余按照默认安装即可
- logback 发送邮件和自定义发送邮件;java类发送邮件
使用logback发送邮件 需求: 1.报错发邮件,定位错误位置以尽快解决:(报错发送邮件) 2.某一项重要操作完成之后发送邮件:(自定义发送邮件) 没有接触过logback,怎么办? 没办法,硬着头 ...
- 使用visual studio 2013读取.mat文件
现在有一个T.mat 文件需要在c++中处理然后以.mat 或是.txt形式返回 T.mat中存储了十个cell,每个cell中会有一个不等长的数组 1.以下是相关配置过程: 参考:http://we ...
- ThreadLocal源码分析-黄金分割数的使用
前提 最近接触到的一个项目要兼容新老系统,最终采用了ThreadLocal(实际上用的是InheritableThreadLocal)用于在子线程获取父线程中共享的变量.问题是解决了,但是后来发现对T ...
- 《 Java 编程思想》CH06 访问权限控制
访问控制(或隐藏具体实现)与"最初的实现并不恰当"有关. 重构即重写代码,以使得它更可读,更容易理解,并因此而更具维护性. 在面向对象设计中需要考虑一个基本问题:"如何把 ...
- python函数中的参数类型
python函数中的参数 动态获取函数的参数 python的函数类型详解
- 曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- DNS 查询 - Domain Name Server
DNS 查询 - Domain Name Server socket.getaddrinfo("www.baidu.com",None) 返回时一个 tuple list - (f ...