Variable和get_variable的用法以及区别

在tensorflow中,可以使用tf.Variable来创建一个变量,也可以使用tf.get_variable来创建一个变量,但是在一个模型需要使用其他模型的变量时,tf.get_variable就派上大用场了。

先分别介绍两个函数的用法:

 1 import tensorflow as tf
 2 var1 = tf.Variable(1.0,name=‘firstvar‘)
 3 print(‘var1:‘,var1.name)
 4 var1 = tf.Variable(2.0,name=‘firstvar‘)
 5 print(‘var1:‘,var1.name)
 6 var2 = tf.Variable(3.0)
 7 print(‘var2:‘,var2.name)
 8 var2 = tf.Variable(4.0)
 9 print(‘var2:‘,var2.name)
10 get_var1 = tf.get_variable(name=‘firstvar‘,shape=[1],dtype=tf.float32,initializer=tf.constant_initializer(0.3))
11 print(‘get_var1:‘,get_var1.name)
12 get_var1 = tf.get_variable(name=‘firstvar1‘,shape=[1],dtype=tf.float32,initializer=tf.constant_initializer(0.4))
13 print(‘get_var1:‘,get_var1.name)
14
15 with tf.Session() as sess:
16     sess.run(tf.global_variables_initializer())
17     print(‘var1=‘,var1.eval())
18     print(‘var2=‘,var2.eval())
19     print(‘get_var1=‘,get_var1.eval())

结果如下:

我们来分析一下代码,tf.Varibale是以定义的变量名称为唯一标识的,如var1,var2,所以可以重复地创建name=‘firstvar‘的变量,但是tensorflow会给它们按顺序取后缀,如firstvar_1:0,firstval_2:0,...,如果没有制定名字,系统会自动加上一个名字Variable:0。而且由于tf.Varibale是以定义的变量名称为唯一标识的,所以当第二次命名同一个变量名时,第一个变量就会被覆盖,所以var1由1.0变成2.0。

对于tf.get_variable,它是以指定的name属性为唯一标识,而不是定义的变量名称,所以不能同时定义两个变量name是相同的,例如下面这种就会报错:

1 get_var1 = tf.get_variable(name=‘a‘,shape=[1],dtype=tf.float32,initializer=tf.constant_initializer(0.3))
2 print(‘get_var1:‘,get_var1.name)
3 get_var2 = tf.get_variable(name=‘a‘,shape=[1],dtype=tf.float32,initializer=tf.constant_initializer(0.4))
4 print(‘get_var1:‘,get_var1.name)

这样就会报错了。如果我们想声明两次相同name的变量,这时variable_scope就派上用场了,可以使用variable_scope将它们分开:

1 import tensorflow as tf
2 with tf.variable_scope(‘test1‘):
3     get_var1 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
4 with tf.variable_scope(‘test2‘):
5     get_var2 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
6 print(‘get_var1:‘,get_var1.name)
7 print(‘get_var2:‘,get_var2.name)

这样就不会报错了,variable_scope相当于声明了作用域,这样在不同的作用域存在相同的变量就不会冲突了,结果如下:

当然,scope还支持嵌套:

1 import tensorflow as tf
2 with tf.variable_scope(‘test1‘,):
3     get_var1 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
4     with tf.variable_scope(‘test2‘,):
5         get_var2 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
6 print(‘get_var1:‘,get_var1.name)
7 print(‘get_var2:‘,get_var2.name)

输出结果为:

怎么样?可以对照上面的结果体会一下不同。那么如何通过get_variable来实现变量共享呢?这就要用到variable_scope里的一个属性:reuse,顾名思义嘛,当把reuse设置成True时就可以了,它表示使用已经定义过的变量,这是get_variable就不会再创建新的变量,而是去找与name相同的变量:

import tensorflow as tf
with tf.variable_scope(‘test1‘,):
    get_var1 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
    with tf.variable_scope(‘test2‘,):
        get_var2 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
print(‘get_var1:‘,get_var1.name)
print(‘get_var2:‘,get_var2.name)
with tf.variable_scope(‘test1‘,reuse=True):
    get_var3 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
    with tf.variable_scope(‘test2‘,):
        get_var4 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
print(‘get_var3:‘,get_var3.name)
print(‘get_var4:‘,get_var4.name)

输出结果如下:

当然前面说过,reuse=True是使用前面已经创建过的变量,如果仅仅只有从第八行到最后的代码,也会报错的,如果还是想这么做,就需要把reuse属性设置成tf.AUTO_REUSE

1 import tensorflow as tf
2 with tf.variable_scope(‘test1‘,reuse=tf.AUTO_REUSE):
3     get_var3 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
4     with tf.variable_scope(‘test2‘,):
5         get_var4 = tf.get_variable(name=‘firstvar‘,shape=[2],dtype=tf.float32)
6 print(‘get_var3:‘,get_var3.name)
7 print(‘get_var4:‘,get_var4.name)

此时就不会报错,tf.AUTO_REUSE可以实现第一次调用variable_scope时,传入的reuse值为False,再次调用时,传入reuse的值就会自动变为True。

原文地址:https://www.cnblogs.com/wf-ml/p/9721027.html

时间: 2024-08-27 06:35:57

Variable和get_variable的用法以及区别的相关文章

javascript中window与document对象、setInterval与setTimeout定时器的用法与区别

一.写在前面 本人前端菜鸟一枚,学习前端不久,学习过程中有很多概念.定义在使用时容易混淆,在此给向我一样刚踏入前端之门的童鞋们归纳一下.今天给大家分享一下js中window与document对象.setInterval与setTimeout定时器的用法与区别.讲得不对的地方,烦请大家指正,还望前辈.大牛多多指教! 二.window对象与document对象的用法和区别 window是全局对象,document是window对象的一个属性它也是一个对象.如图: document对象指的页面这个文档

Linux中yum和apt-get用法及区别

Linux中yum和apt-get用法及区别 一般来说著名的linux系统基本上分两大类: 1.RedHat系列:Redhat.Centos.Fedora等 2.Debian系列:Debian.Ubuntu等 RedHat 系列 1 常见的安装包格式 rpm包,安装rpm包的命令是"rpm -参数" 2 包管理工具  yum 3 支持tar包 Debian系列 1 常见的安装包格式 deb包,安装deb包的命令是"dpkg -参数" 2 包管理工具 apt-get

PHP基础温习之echo print printf sprintf print_r var_dump的用法与区别

原文:PHP基础温习之echo print printf sprintf print_r var_dump的用法与区别 一.echoecho() 实际上不是一个函数,是php语句,因此您无需对其使用括号.不过,如果您希望向 echo() 传递一个以上的参数,那么使用括号会发生解析错误.而且echo是返回void的,并不返回值,所以不能使用它来赋值.例子: 复制代码代码如下: <?php $a = echo("55nav"); // 错误!不能用来赋值 echo "55n

jquery.fn.extend与jquery.extend用法与区别

关于jquery.fn.extend与jquery.extend用法与区别. jQuery为开发插件提拱了两个方法,分别是:  代码如下 复制代码 jQuery.fn.extend(object);  和   jQuery.extend(object); jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法. jQuery.fn.extend(object);给jQuery对象添加方法. fn 是什么东西呢.查看jQuery代码,就不难发现.  代码如下 复制

【Java学习笔记之二十九】Java中的&quot;equals&quot;和&quot;==&quot;的用法及区别

Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 System.out.println(str1==str2); 4 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一

WordPress翻译中 __()、_e()、_x、_ex 和 _n 的用法及区别

编译函数 WordPress使用了下面几个函数来方便语言本地化. __() _e() _x() _ex() _n() 以上所列的函数是用来包含所需翻译的字符串的,根据字符串的不同参数和输出类型,需要使用不同的函数.相信有不少朋友还是不太明白这几个函数的区别和用法,下面倡萌就来详细说说. __() 和 _e() __() 和 _e() 都是用来返回对应当前语言的字符串内容.请看下面的例子: 使用 __() <?php if( is_single() ) { //如果这是一篇“文章” echo __

SQL语句中count(1)count(*)count(字段)用法的区别

SQL语句中count(1)count(*)count(字段)用法的区别 在SQL语句中count函数是最常用的函数之一,count函数是用来统计表中记录数的一个函数, 一. count(1)和count(*)的区别 1. count(1)和count(*)的作用: 都是检索表中所有记录行的数目,不论其是否包含null值. 2. 区别:但是count(1)比count(*)效率更高 二 . count(字段)与count(1)和count(*)的区别 count(字段)的作用是检索表中的这个字段

innerHTML,innerText,outHTML的用法及区别详解

innerHTML,innerText,outHTML的用法及区别,今天就详细的解说并且带有实例说明.大家一看就明白,进入正题,接下来我们用下面的这段代码做测试 <div id="tianzi"> <span style="color:red">www.seostudying.com</span> </div> 1.tianzi.innerText 它得到的是<div></div>标签中的文本节

[转载]jQuery中wrap、wrapAll和wrapInner用法以及区别

原文地址:jQuery中wrap.wrapAll和wrapInner用法以及区别作者:伊少君 原文: <ul> <li title='苹果'>苹果</li> <li title='橘子'>橘子</li> <li title='菠萝'>菠萝</li> </ul> 1.$("li").wrap("<div></div>"); 每一个选择器都添加 <