tensorflow的命名域问题:tf.Variable与tf.get_variable

本文介绍了TensorFlow中tf.Variable和tf.get_variable的使用,特别是变量命名域的问题。通过示例说明了如何创建和共享变量,解释了reuse参数的作用,并提供了两种在函数中实现首次创建、后续获取变量的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

tensorflow的命名问题断断续续接触了又忘记,干脆写一篇博来记录一下好啦。其实极客学院里面也回答的挺清楚的了:极客学院:共享变量, 但它考虑了更多种情况,自己还是想以更简单的方式去记忆。

tf.Variable:创建变量

这个是最简单粗暴的创建变量方式,如果不停地调用它,是会产生不同的变量的。举个更简单的例子:

import tensorflow as tf
#tf.Variable创建变量
def geta():
    a = tf.Variable([1],name='a')
    return a
a = geta() # 得到<tf.Variable 'a:0' shape=(1,) dtype=int32_ref>
a1 = geta() # 得到与a不同的变量:<tf.Variable 'a_1:0' shape=(1,) dtype=int32_ref>

调用geta(),会得到 <tf.Variable ‘a:0’ shape=(1,) dtype=int32_ref>,再调用geta(),则得到<tf.Variable ‘a_1:0’ shape=(1,) dtype=int32_ref>。可以看到此时两次调用得到两个不同的变量。

但在实际中,我们很可能需要多次调用而使用同一个变量,比如极客学院中提到的,我们可能需要定义一个图片的滤波器函数,然后对不同图片使用同一个滤波器,这时候就需要所谓的共享变量,可以用到下面的tf.get_variable大招啦。

tf.get_variable: 创建或获取变量

一般与tf.variable_scope搭配使用。

reuse=True?False?

首先先说说reuse,每次跑别人tensorflow代码debug时总是会弹出来令我头疼的:
ValueError: Variable xxx already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?

其实reuse说简单也很简单,一句话就是:如果你想用get_variable创建变量,你就用reuse=False;如果想用get_variable获取变量,就用reuse=True。 反过来会有问题,比如如果该变量还没有创建就用reuse=True,get_variable会告诉你它找不到这个变量;如果该变量已经创建过了还用reuse=False,get_variable就会弹出上面那一串ValueError,告诉你变量已经存在了。没错,它就是这么挑剔,所以一定要选对它的值。

示例1:

def geta():
    with tf.variable_scope('A',reuse=False):
        a = tf.get_variable('a',[1])
    return a
a = geta() # <tf.Variable 'A/a:0' shape=(1,) dtype=float32_ref>
a1 = geta() # 会报错

此时a为<tf.Variable ‘A/a:0’ shape=(1,) dtype=float32_ref>,创建成功。但再次调用geta()的时候就会报出上面的ValueError错误,因为不能重用。

示例2:

def geta():
    with tf.variable_scope('AA',reuse=True):
        a = tf.get_variable('a',[1])
    return a
a = geta() # 会报错

此时调用geta()会报错(注意此时scope的域我改为了AA,而不是A了,所以属于一个新的域,我们还没往这个域里面定义变量):Variable AA/a does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope? 因为我们还没有创建过这个变量。

想先创建,后获取?

于是问题来了:如果我想定义一个函数,第一次调用的时候创建,第二次调用的时候获取,怎么办?

方法一极客学院:共享变量中提到的,用scope.reuse_variables()解决。即在另一个域里面先调用一次函数,然后用scope.reuse_variables()设置为重用,再调用一次函数:

def getb():
    with tf.variable_scope('B'):
        b = tf.get_variable('b',[1])
    return b

with tf.variable_scope('main_scope') as scope:
    b1 = getb()
    scope.reuse_variables()
    b2 = getb()
assert b1==b2 #不会报错,两个都是<tf.Variable 'main_scope/B/b:0' shape=(1,) dtype=float32_ref>

此时b1和b2都是<tf.Variable ‘main_scope/B/b:0’ shape=(1,) dtype=float32_ref>。

方法二:但其实我自己更喜欢这种方法,因为无需再多定义一个scope。即只需要在函数中多加一个reuse的标志,第一次调用的时候设置reuse为None或False,第二次调用的时候设置为True即可。

def getc(reuse=None):
    with tf.variable_scope('C',reuse=reuse):
        c = tf.get_variable('c',[1])
    return c
c1=getc()
c2=getc(True)
assert c1==c2 # 不会报错,两者都是<tf.Variable 'C/c:0' shape=(1,) dtype=float32_ref>

此时c1和c2都是<tf.Variable ‘C/c:0’ shape=(1,) dtype=float32_ref>。

END

目前关于变量域的先学习到这么多,如果在之后的使用中还有遇到什么经验,再来更新~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值