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 的方法的更多相关文章

  1. linux两种增加交换分区(swap)的方法

    在安装Oracle后,为使Oracle流畅运行,需要手动增加linux的交换分区(相当于Windows下的虚拟内存)的大小,本文介绍两种增加交换分区(swap)的方法. 第一种方法:新建分区 1.fd ...

  2. JAVA 中两种判断输入的是否是数字的方法__正则化_

    JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengz ...

  3. 两种常用的jquery事件加载的方法 的区别

    两种常用的jquery事件加载的方法   $(function(){});  window.onload=function(){}  第一个呢,是在DOM结构渲染完成以后调用的,这时候网页中一些资源还 ...

  4. Android中两种设置全屏或者无标题的方法

    在开发中我们经常需要把我们的应用设置为全屏或者不想要title, 这里是有两种方法的,一种是在代码中设置,另一种方法是在配置文件里改: 一.在代码中设置: package jason.tutor; i ...

  5. JSONP和CORS两种跨域方式的优缺点及使用方法原理介绍

    随着软件开发分工趋于精细,前后端开发分离成为趋势,前端同事负责前端页面的展示及页面逻辑处理,服务端同事负责业务逻辑处理同时通过API为前端提供数据也为前端提供数据的持久化能力,考虑到前后端同事开发工具 ...

  6. 两种解决IE6不支持固定定位的方法

    有两种让IE6支持position:fixed1.用CSS执行表达式 *{margin:0;padding:0;} * html,* html body{ background-image:url(a ...

  7. 【DevCloud · 敏捷智库】两种你必须了解的常见敏捷估算方法

    背景 在某开发团队辅导的回顾会议上,团队成员对于优化估计具体方法上达成了一致意见.询问是否有什么具体的估计方法来做估算. 问题分析 回顾意见上大家对本次Sprint的效果做回顾,其中80%的成员对于本 ...

  8. Django—Form两种解决表单数据无法动态刷新的方法

    一.无法动态更新数据的实例 1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多” from django.db import models class Classes(models. ...

  9. 【Django】Django—Form两种解决表单数据无法动态刷新的方法

    一.无法动态更新数据的实例 1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多” from django.db import models class Classes(models. ...

随机推荐

  1. AcWing 787.归并排序

    AcWing 787.归并排序 题目描述 给定你一个长度为n的整数数列. 请你使用归并排序对这个数列按照从小到大进行排序. 并将排好序的数列按顺序输出. 输入格式 输入共两行,第一行包含整数 n. 第 ...

  2. vuex之state(一)

    我的理解 个人认为,不用说得太过深奥,vuex其实就是把一个应用的某些数据统一管理起来,以便其他的组件更方便的操作该数据. 为什么使用vuex 当项目结构越来越复杂,组件的多层嵌套使得数据传递非常繁琐 ...

  3. Dubbo Cluster集群那点你不知道的事。

    这是why技术的第33篇原创文章 本周是在家办公的一周,上面的图就是我在家的工位. 工欲善其事,必先利其器.在家办公,我是认真的. 在家里开发的时候有需求是这样的:一个如果接口调用失败,需要自动进行重 ...

  4. 严重 [RMI TCP Connection(3)-127.0.0.1]

    学习Servlet时碰到的一个bug. Connected to server [2017-01-08 04:40:33,100] Artifact jspRun:war exploded: Arti ...

  5. ATL窗口

    标准的Windows应用程序框架: /*------------------------------------------------------------ HELLOWIN.C -- Displ ...

  6. JAVA环境配置(Windows10)

    Java开发环境配置 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:https://www.oracle.com/technetwork/java/javase/downloads/ ...

  7. Go语言实现:【剑指offer】二进制中1的个数

    该题目来源于牛客网<剑指offer>专题. 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析: 如果一个整数不为0,那么这个整数至少有一位是1.如果我们把这个整数减1 ...

  8. SpringBoot+Mybatis+MybatisPlus整合实现基本的CRUD操作

    SpringBoot+Mybatis+MybatisPlus整合实现基本的CRUD操作 1> 数据准备 -- 创建测试表 CREATE TABLE `tb_user` ( `id` ) NOT ...

  9. Apache-Tomcat-Ajp漏洞(CVE-2020-1938)漏洞复现

    前言 Apache Tomcat会开启AJP连接器,方便与其他Web服务器通过AJP协议进行交互.由于Tomcat本身也内含了HTTP服务器,因此也可以视作单独的Web服务器.此漏洞为文件包含漏洞,攻 ...

  10. The Divide and Conquer Approach - 归并排序

    The divide and conquer approach - 归并排序 归并排序所应用的理论思想叫做分治法. 分治法的思想是: 将问题分解为若干个规模较小,并且类似于原问题的子问题, 然后递归( ...