关于Tensorflow 模型持久化详解
作者:Yigit_dev 发布时间:2021-02-26 14:27:33
当我们使用 tensorflow 训练神经网络的时候,模型持久化对于我们的训练有很重要的作用。
如果我们的神经网络比较复杂,训练数据比较多,那么我们的模型训练就会耗时很长,如果在训练过程中出现某些不可预计的错误,导致我们的训练意外终止,那么我们将会前功尽弃。为了避免这个问题,我们就可以通过模型持久化(保存为CKPT格式)来暂存我们训练过程中的临时数据。
如果我们训练的模型需要提供给用户做离线的预测,那么我们只需要前向传播的过程,只需得到预测值就可以了,这个时候我们就可以通过模型持久化(保存为PB格式)只保存前向传播中需要的变量并将变量的值固定下来,这个时候只需用户提供一个输入,我们就可以通过模型得到一个输出给用户。
保存为 CKPT 格式的模型
定义运算过程
声明并得到一个 Saver
通过 Saver.save 保存模型
# coding=UTF-8 支持中文编码格式
import tensorflow as tf
import shutil
import os.path
MODEL_DIR = "model/ckpt"
MODEL_NAME = "model.ckpt"
# if os.path.exists(MODEL_DIR): 删除目录
# shutil.rmtree(MODEL_DIR)
if not tf.gfile.Exists(MODEL_DIR): #创建目录
tf.gfile.MakeDirs(MODEL_DIR)
#下面的过程你可以替换成CNN、RNN等你想做的训练过程,这里只是简单的一个计算公式
input_holder = tf.placeholder(tf.float32, shape=[1], name="input_holder") #输入占位符,并指定名字,后续模型读取可能会用的
W1 = tf.Variable(tf.constant(5.0, shape=[1]), name="W1")
B1 = tf.Variable(tf.constant(1.0, shape=[1]), name="B1")
_y = (input_holder * W1) + B1
predictions = tf.greater(_y, 50, name="predictions") #输出节点名字,后续模型读取会用到,比50大返回true,否则返回false
init = tf.global_variables_initializer()
saver = tf.train.Saver() #声明saver用于保存模型
with tf.Session() as sess:
sess.run(init)
print "predictions : ", sess.run(predictions, feed_dict={input_holder: [10.0]}) #输入一个数据测试一下
saver.save(sess, os.path.join(MODEL_DIR, MODEL_NAME)) #模型保存
print("%d ops in the final graph." % len(tf.get_default_graph().as_graph_def().node)) #得到当前图有几个操作节点
for op in tf.get_default_graph().get_operations(): #打印模型节点信息
print (op.name, op.values())
运行后生成的文件如下:
checkpoint : 记录目录下所有模型文件列表
ckpt.data : 保存模型中每个变量的取值
ckpt.meta : 保存整个计算图的结构
保存为 PB 格式模型
定义运算过程
通过 get_default_graph().as_graph_def() 得到当前图的计算节点信息
通过 graph_util.convert_variables_to_constants 将相关节点的values固定
通过 tf.gfile.GFile 进行模型持久化
# coding=UTF-8
import tensorflow as tf
import shutil
import os.path
from tensorflow.python.framework import graph_util
# MODEL_DIR = "model/pb"
# MODEL_NAME = "addmodel.pb"
# if os.path.exists(MODEL_DIR): 删除目录
# shutil.rmtree(MODEL_DIR)
#
# if not tf.gfile.Exists(MODEL_DIR): #创建目录
# tf.gfile.MakeDirs(MODEL_DIR)
output_graph = "model/pb/add_model.pb"
#下面的过程你可以替换成CNN、RNN等你想做的训练过程,这里只是简单的一个计算公式
input_holder = tf.placeholder(tf.float32, shape=[1], name="input_holder")
W1 = tf.Variable(tf.constant(5.0, shape=[1]), name="W1")
B1 = tf.Variable(tf.constant(1.0, shape=[1]), name="B1")
_y = (input_holder * W1) + B1
# predictions = tf.greater(_y, 50, name="predictions") #比50大返回true,否则返回false
predictions = tf.add(_y, 10,name="predictions") #做一个加法运算
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print "predictions : ", sess.run(predictions, feed_dict={input_holder: [10.0]})
graph_def = tf.get_default_graph().as_graph_def() #得到当前的图的 GraphDef 部分,通过这个部分就可以完成重输入层到输出层的计算过程
output_graph_def = graph_util.convert_variables_to_constants( # 模型持久化,将变量值固定
sess,
graph_def,
["predictions"] #需要保存节点的名字
)
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))
print (predictions)
# for op in tf.get_default_graph().get_operations(): 打印模型节点信息
# print (op.name)
*GraphDef:这个属性记录了tensorflow计算图上节点的信息。
add_model.pb : 里面保存了重输入层到输出层这个计算过程的计算图和相关变量的值,我们得到这个模型后传入一个输入,既可以得到一个预估的输出值
CKPT 转换成 PB格式
通过传入 CKPT 模型的路径得到模型的图和变量数据
通过 import_meta_graph 导入模型中的图
通过 saver.restore 从模型中恢复图中各个变量的数据
通过 graph_util.convert_variables_to_constants 将模型持久化
# coding=UTF-8
import tensorflow as tf
import os.path
import argparse
from tensorflow.python.framework import graph_util
MODEL_DIR = "model/pb"
MODEL_NAME = "frozen_model.pb"
if not tf.gfile.Exists(MODEL_DIR): #创建目录
tf.gfile.MakeDirs(MODEL_DIR)
def freeze_graph(model_folder):
checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
output_graph = os.path.join(MODEL_DIR, MODEL_NAME) #PB模型保存路径
output_node_names = "predictions" #原模型输出操作节点的名字
saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True) #得到图、clear_devices :Whether or not to clear the device field for an `Operation` or `Tensor` during import.
graph = tf.get_default_graph() #获得默认的图
input_graph_def = graph.as_graph_def() #返回一个序列化的图代表当前的图
with tf.Session() as sess:
saver.restore(sess, input_checkpoint) #恢复图并得到数据
print "predictions : ", sess.run("predictions:0", feed_dict={"input_holder:0": [10.0]}) # 测试读出来的模型是否正确,注意这里传入的是输出 和输入 节点的 tensor的名字,不是操作节点的名字
output_graph_def = graph_util.convert_variables_to_constants( #模型持久化,将变量值固定
sess,
input_graph_def,
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)) #得到当前图有几个操作节点
for op in graph.get_operations():
print(op.name, op.values())
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("model_folder", type=str, help="input ckpt model dir") #命令行解析,help是提示符,type是输入的类型,
# 这里运行程序时需要带上模型ckpt的路径,不然会报 error: too few arguments
aggs = parser.parse_args()
freeze_graph(aggs.model_folder)
# freeze_graph("model/ckpt") #模型目录
来源:https://blog.csdn.net/michael_yt/article/details/74737489
猜你喜欢
- 阅读目录什么是设计模式单体模式:工厂模式:单例模式观察者模式(发布订阅模式)策略模式模板模式代理模式外观模式设计模式太多了,貌似有23种,其
- 继上一篇计算checksum校验和,本章通过socket套接字,struct字节打包成二进制,select返回套接字的文件描述符的结合,实现
- python的多进程性能要明显优于多线程,因为cpython的GIL对性能做了约束。Python是运行在解释器中的语言,查找资料知道,pyt
- 汉字转为拼音的asp函数,原理:利用多维数组 1.添加索引 2.遍历数组Author: Unknowasp之家测试截图,呵呵不错:<%
- 这篇论坛文章主要介绍了Oracle数据库到SQL Server数据库主键的迁移过程,具体内容请参考下文。由于项目需要要将以前Oracle的数
- 在JavaScript中,我们应该尽可能的用局部变量来代替全局变量,这句话所有人都知道,可是这句话是谁先说的?为什么要这么做?有什么根据么?
- 一、什么是sql子查询? 子查询是一个嵌套在Select 、Insert 、Update 或Dele
- 随着网站访问量的加大,每次从数据库读取都是以效率作为代价的,很多用ACCESS作数据库的更会深有体会,静态页加在搜索时,也会被优先考虑。互联
- 新闻、文章系统中经常会用到的一个功能,添加上一篇,下一篇或相关文章的功能可以增加访客停留的时间。也许新人在做这上一篇、下一篇功能时使用的是I
- 它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, Adi
- 本文实例讲述了Python3.6基于正则实现的计算器。分享给大家供大家参考,具体如下:# -*- coding:utf-8 -*-#!pyt
- 当使用pytorch写网络结构的时候,本人发现在卷积层与第一个全连接层的全连接层的input_features不知道该写多少?一开始本人的做
- 学习目的 接触验证控件 昨天介绍了SQL SERVER插入数据,但是我们省略了验证输入这一步。以前的做法是用语句逐个判断输入的正确性,如是否
- 1、背景介绍在采用通常的socket抓包方式下,操作系统会自动将收到包的VLAN信息剥离,导致上层应用收到的包不会含有VLAN标签信息。而l
- 如果是windows安装完成后,需要将'\Python27\Scripts\'加入系统环境变量# coding=utf-8i
- 这篇论坛文章(赛迪网技术社区)主要介绍了数据仓库基本报表制作过程中的SQL写法,详细内容请参考下文:在数据仓库的基本报表制作过程中,通常会使
- 使用指令:pyinstaller -F -w main.py生成的.exe文件执行报错看报错信息,初步怀疑是生成的.exe不能执行.ini配
- 本文介绍了使用Application来统计访问网站的在线人数的方法,并介绍了使用Application时应该注意的事项。首先讲明白,用ASP
- 一、输入input("提示内容")(1)当程序执行到input,等待用户输入,输入完成后才继续往下执行(2)input接
- 本文实例借鉴mvc模式,核心数据为model,维护1个矩阵,0表无雷,1表雷,-1表已经检测过。本例使用python的tkinter做gui