6_1 持久化模型与再次加载_探讨(1)_三种持久化模型加载方式以及import_meta_graph方式加载持久化模型会存在的变量管理命名混淆的问题
笔者提交到gitHub上的问题描述地址是:https://github.com/tensorflow/tensorflow/issues/20140
三种持久化模型加载方式的一个小结论
加载持久化模型的三种方式:
第一,saver.restore:属于当前代码计算图已经定义,我需要将持久化模型中变量的值加载到当前代码计算图中的变量中去。所以,两者只能是持久化模型中的变量是当前代码计算图中变量集合的一个子集,必须是一种严格包含的关系。(当然,可以在初始化Saver的时候指定加载哪些变量)
第二,import_meta_graph则完全不允许当前代码计算图已经定义的变量节点和要加载的持久化模型中的节点存在冲突,因为它价值的是整个图。不是单纯将变量的值进行加载。
第三,使用pb文件的方式,即使持久化模型中的变量节点和当前代码计算图中定义的变量节点发生冲突,也是毛事没有,没有任何关系。因为pb文件的方式加载进来的计算图,
会全部加上import/前缀。也就是说,从命名空间上就隔开了这种冲突。
上述三点是很重要的结论,自己调试和观察的。
所以,使用别人的模型,最好的方式就是用pb文件。因为不会有冲突的可能!但是,有一个弊端就是,import命名空间下的变量不能参与到当前的训练!!!记住,不能参与训练!
问题描述(英文版):
write the code below, and save it to a ,ckpt as a model
import tensorflow as tf`
v1 = tf.Variable(tf.constant(1.0, shape=[]), name = "v1")
v2 = tf.Variable(tf.constant(2.0, shape=[]), name = "v2")
v3 = tf.Variable(tf.constant(3.0, shape=[]), name = "v3")
result=v1+v2
result2= result + v3 init_op = tf.global_variables_initializer()
saver = tf.train.Saver() with tf.Session() as sess:
sess.run(init_op)
writer = tf.summary.FileWriter('./graphs/const_add', sess.graph)
saver.save(sess, "Saved_model/model.ckpt")`
then in another .py, we restore the model from the model.ckpt file
import tensorflow as tf
saver = tf.train.import_meta_graph("Saved_model/model.ckpt.meta")
with tf.Session() as sess:
saver.restore(sess, "Saved_model/model.ckpt")
print (sess.run(tf.get_default_graph().get_tensor_by_name("add:0")))
#sess.run(tf.assign(v1,[10])) #直接这样使用v1,会提示v1没有定义 #with tf.variable_scope("",reuse=tf.AUTO_REUSE):
with tf.variable_scope("",reuse=False):
v1=tf.get_variable(name="v1",shape=[1])
print(v1.name)
sess.run(tf.assign(v1,[10]))
"""④输出所有可训练的变量名称,也就是神经网络的参数"""
trainable_variables=tf.trainable_variables()
variable_list_name = [c.name for c in tf.trainable_variables()]
variable_list = sess.run(variable_list_name)
for k,v in zip(variable_list_name,variable_list):
print("variable name:",k)
print("shape:",v.shape)
#print(v)
"""④输出所有可训练的变量名称,也就是神经网络的参数"""
print (sess.run(tf.get_default_graph().get_tensor_by_name("v1:0")))
print (sess.run(tf.get_default_graph().get_tensor_by_name("add:0")))
print (sess.run(tf.get_default_graph().get_tensor_by_name("add_1:0")))
print (sess.run(tf.get_default_graph().get_tensor_by_name("v1_1:0")))
the results will be as below:
we will find that:
if we restore some variables from the already existed model file ""Saved_model/model.ckpt.meta")",
such as v1,v2,v3 in this example.
it will influence the process of calling get_variable. Because of these two causes as below:
- the variables restored from the model file such as v1,v2 and v3 will not exist in the scope of get_variable, it means you can only use
with tf.variable_scope("",reuse=False):
v1=tf.get_variable(name="v1",shape=[1])
and create a new variable. you can not reuse the restored variable v1 from the model file unless you define a v1 , before you restore from the model file. like below
v1=tf.get_variable(name="v1",shape=[1])
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, "Saved_model/model.ckpt")
print (sess.run(result))
that is , you can not reuse the restored variable v1 which is from restoring the model file unless you define it befor you restore.
2. although tensorflow doesnot allow reusing the restored variable v1 which is from restoring the model file if you don't define v1 before you restore the model file.
But if you call get_varialbe after you restore the model file, it will create a variable whose name is "v1_1" but not as name='v1' which you specify.
in my opinion, it should be corrected because it is so confusing. how to correct it?
i think get_variable should also reuse the variables which is loaded by restoring some model file.
the last sentence is what i finally want to say.
My english is to bad, you can run the code i offer and will find what i want to convey.
Thanks.
总结
假定一个持久化模型中存在一个V1命名的变量,此时如果使用import_meta_graph方式加载持久化模型。
- 首先,使用import_meta_graph要加载的持久化模型中的变量命名不能与当前代码默认计算图中的变量命名发生冲突
- 其次,如果此时希望通过利用tf.get_variable的方式,来建立python变量与计算图变量节点之间的关系,即:
with tf.variable_scope("",reuse=False):
v1=tf.get_variable(name="v1",shape=[1])
print(v1.name)
是不可能做到的。而且你只能用reuse=False,就好像:加载持久化模型以后,计算图中没有V1变量节点一样。
同时,你使用v1=tf.get_variable(name="v1",shape=[1])方式,会在当前代码的计算图中生成一个新的变量节点V1_1,并非加载的持久化模型中的变量节点V1。此时,就会出现函数功能失效。也就是,你希望调用get_variable函数使得:python的变量v1和计算图中的变量节点v1是绑定的,但是情况并非如此,绑定的是变量节点v1_1。
所以访问计算图中的V1节点,就只能使用tf.get_default_graph().get_tensor_by_name("v1:0")的方式。
很多人可能并不理解这个:0,这是一个operation的输出。也就是说变量节点的输出只有一个,所以用0表示引用计算图中这个变量节点的输出tensor。
事实上,可以自定义tensorflow中的operation,也就是我可以输出多个tensor。那个时候:0,:1就可以用起来了。
总的来说,笔者将此问题提交到gitHub,目前仍然处于欢迎讨论状态。即tensorflow的开发人员需要更多tensorflow使用者的意见,来回答:有没有必要对这个问题进行修复。
6_1 持久化模型与再次加载_探讨(1)_三种持久化模型加载方式以及import_meta_graph方式加载持久化模型会存在的变量管理命名混淆的问题的更多相关文章
- android加载大量图片内存溢出的三种方法
android加载大量图片内存溢出的三种解决办法 方法一: 在从网络或本地加载图片的时候,只加载缩略图. /** * 按照路径加载图片 * @param path 图片资源的存放路径 * @para ...
- VC中加载LIB库文件的三种方法
VC中加载LIB库文件的三种方法 在VC中加载LIB文件的三种方法如下: 方法1:LIB文件直接加入到工程文件列表中 在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中&quo ...
- 加载gif动态图的三种方式
准备:本地图片资源,GifView
- Javascript事件模型系列(一)事件及事件的三种模型
一.开篇 在学习javascript之初,就在网上看过不少介绍javascript事件的文章,毕竟是js基础中的基础,文章零零散散有不少,但遗憾的是没有看到比较全面的系列文章.犹记得去年这个时候,参加 ...
- 【转】android加载大量图片内存溢出的三种解决办法
方法一: 在从网络或本地加载图片的时候,只加载缩略图. /** * 按照路径加载图片 * @param path 图片资源的存放路径 * @param scalSize 缩小的倍数 * @return ...
- 页面加载即执行JQuery的三种方法
[1]$(function( ){ }): $(function(){ $("#name").click(function(){ //adding your code here } ...
- linux c++ 加载动态库常用的三种方法
链接库时的搜索路径顺序:LD_LIBRARY_PATH --> /etc/ld.so.conf --> /lib,/usr/lib 方法1. vi .bash_profile 设置环 ...
- 谈IO中的阻塞和非阻塞,同步和异步及三种IO模型
什么是同步和异步? 烧水,我们都是通过热水壶来烧水的.在很久之前,科技还没有这么发达的时候,如果我们要烧水,需要把水壶放到火炉上,我们通过观察水壶内的水的沸腾程度来判断水有没有烧开.随着科技的发展,现 ...
- java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现
注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...
随机推荐
- CS231n学习笔记-图像分类笔记(下篇)
原文地址:智能单元 K-Nearest Neighbor分类器 大家可能注意到了,为什么只用最相似的一张图片的标签来作为测试图像的标签呢?这不是很奇怪吗!是的,使用K-Nearest Neighbor ...
- 前端的CRUD增删改查的小例子
前端的CRUD增删改查的小例子 1.效果演示 2.相关代码: <!DOCTYPE html> <html lang="en"> <head> & ...
- mysql数据库修改字符编码问题
遇到这种情况,现有项目的数据库已经建好,数据表也已经创建完成. 问题来的,数据库不能插入中文,调试时候发现中文数据从发送请求到最后请求处理完成这些步骤,中文还没有发生乱码. 只有在存储到数据库后查询数 ...
- Struts文件上传(FormFile)
Struts中FormFile用于文件进行上传 1.在jsp文件中进行定义 <form action="/StrutsFileUpAndDown/register.do" m ...
- 使用fastjson进行转换
package junit.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; imp ...
- java序列化测试
0.前言 本文主要对几种常见Java序列化方式进行实现.包括Java原生以流的方法进行的序列化.Json序列化.FastJson序列化.Protobuff序列化. 1.Java原生序列化 Java原生 ...
- rpm使用方法
查看rpm信息:rpm -q [软件的rpm名字]rpm -q下还有很多选项,具体功能如下:rpm -qa 列出所有已安装的RPM文件rpm -qa | grep [rp ...
- 使用 Selenium 实现基于 Web 的自动化测试
(转自http://www.ibm.com/developerworks/cn/web/1209_caimin_seleniumweb/index.html) Selenium 是一个用于 Web 应 ...
- 基于Ionic的移动框架搭建
- Angular的表单组件
创建表单元素 在上一节中,我们学习了如何创建一个组件login,现在将login改造一下, 在template中添加html表单元素,#usernameRef表示input元素id,如果想传递inpu ...