[572]tf.get_variable

本文介绍了获取或创建变量时tf.Variable()和tf.get_variable()的使用,包括参数如name、shape、dtype等含义,还列举了多种变量初始化方式。指出不同变量不能同名,除非定义variable_scope。对比了二者区别,如处理命名冲突方式,以及共享变量时的选择。

获取一个已经存在的变量或者创建一个新的变量

get_variable(
    name,
    shape=None,
    dtype=None,
    initializer=None,
    regularizer=None,
    trainable=True,
    collections=None,
    caching_device=None,
    partitioner=None,
    validate_shape=True,
    use_resource=None,
    custom_getter=None,
    constraint=None
)

Args:

  • name:新变量或现有变量的名称。

  • shape:新变量或现有变量的形状。

  • dtype:新变量或现有变量的类型(默认为DT_FLOAT)。

  • ininializer:如果创建了则用它来初始化变量。

    initializer是变量初始化的方式,初始化的方式有以下几种:

    • tf.constant_initializer:常量初始化函数
    • tf.random_normal_initializer:正态分布
    • tf.truncated_normal_initializer:截取的正态分布
    • tf.random_uniform_initializer:均匀分布
    • tf.zeros_initializer:全部是0
    • tf.ones_initializer:全是1
    • tf.uniform_unit_scaling_initializer:满足均匀分布,但不影响输出数量级的随机值
  • regularizer:A(Tensor - > Tensor或None)函数;将它应用于新创建的变量的结果将添加到集合tf.GraphKeys.REGULARIZATION_LOSSES中,并可用于正则化。

  • trainable:如果为True,还将变量添加到图形集合GraphKeys.TRAINABLE_VARIABLES(参见tf.Variable)。

  • collections:要将变量添加到的图表集合列表。默认为[GraphKeys.GLOBAL_VARIABLES](参见tf.Variable)。

  • caching_device:可选的设备字符串或函数,描述变量应被缓存以供读取的位置。默认为Variable的设备。如果不是None,则在另一台设备上缓存。典型用法是在使用变量驻留的Ops的设备上进行缓存,以通过Switch和其他条件语句进行重复数据删除。

  • partitioner:可选callable,接受完全定义的TensorShape和要创建的Variable的dtype,并返回每个轴的分区列表(当前只能对一个轴进行分区)。

  • validate_shape:如果为False,则允许使用未知形状的值初始化变量。如果为True,则默认为initial_value的形状必须已知。

  • use_resource:如果为False,则创建常规变量。如果为true,则使用定义良好的语义创建实验性ResourceVariable。默认为False(稍后将更改为True)。在Eager模式下,此参数始终强制为True。

  • custom_getter:Callable,它将第一个参数作为true getter,并允许覆盖内部get_variable方法。 custom_getter的签名应与此方法的签名相匹配,但最适合未来的版本将允许更改:def custom_getter(getter,* args,** kwargs)。也允许直接访问所有get_variable参数:def custom_getter(getter,name,* args,** kwargs)。一个简单的身份自定义getter只需创建具有修改名称的变量是:python def custom_getter(getter,name,* args,** kwargs):return getter(name +’_suffix’,* args,** kwargs)

如果initializer初始化方法是None(默认值),则会使用variable_scope()中定义的initializer,如果也为None,则默认使用glorot_uniform_initializer,也可以使用其他的tensor来初始化,value,和shape与此tensor相同

正则化方法默认是None,如果不指定,只会使用variable_scope()中的正则化方式,如果也为None,则不使用正则化;

附: tf.truncated_narmal()和tf.truncated_naomal__initializer()的区别

  • tf.truncated_narmal(shape=[],mean=0,stddev=0.5)使用时必须制定shape,返回值是在截断的正态分布随机生成的指定shape的tensor

  • tf.truncated_normal_initializer(mean=0.stddev=0.5)调用返回一个initializer 类的一个实例(就是一个初始化器),不可指定shape,

import tensorflow as tf;  
import numpy as np;  
import matplotlib.pyplot as plt;  
  
a1 = tf.get_variable(name='a1', shape=[2,3], initializer=tf.random_normal_initializer(mean=0, stddev=1))
a2 = tf.get_variable(name='a2', shape=[1], initializer=tf.constant_initializer(1))
a3 = tf.get_variable(name='a3', shape=[2,3], initializer=tf.ones_initializer())
 
with tf.Session() as sess:
	sess.run(tf.initialize_all_variables())
	print(sess.run(a1))
	print(sess.run(a2))
	print(sess.run(a3))

输出:

[[ 0.42299312 -0.25459203 -0.88605702]
 [ 0.22410156  1.34326422 -0.39722782]]
[ 1.]
[[ 1.  1.  1.]
 [ 1.  1.  1.]]

注意:不同的变量之间不能有相同的名字,除非你定义了variable_scope,这样才可以有相同的名字。

tf.Variable() 和tf.get_variable()区别

1、使用tf.Variable时,如果检测到命名冲突,系统会自己处理。使用tf.get_variable()时,系统不会处理冲突,而会报错

import tensorflow as tf
w_1 = tf.Variable(3,name="w_1")
w_2 = tf.Variable(1,name="w_1")
print w_1.name
print w_2.name
#输出
#w_1:0
#w_1_1:0
import tensorflow as tf

w_1 = tf.get_variable(name="w_1",initializer=1)
w_2 = tf.get_variable(name="w_1",initializer=2)
#错误信息
#ValueError: Variable w_1 already exists, disallowed. Did
#you mean to set reuse=True in VarScope?

2、基于这两个函数的特性,当我们需要共享变量的时候,需要使用tf.get_variable()。在其他情况下,这两个的用法是一样的

import tensorflow as tf

with tf.variable_scope("scope1"):
    w1 = tf.get_variable("w1", shape=[])
    w2 = tf.Variable(0.0, name="w2")
with tf.variable_scope("scope1", reuse=True):
    w1_p = tf.get_variable("w1", shape=[])
    w2_p = tf.Variable(1.0, name="w2")

print(w1 is w1_p, w2 is w2_p)
#输出
#True  False

由于tf.Variable() 每次都在创建新对象,所有reuse=True 和它并没有什么关系。对于get_variable(),来说,如果已经创建的变量对象,就把那个对象返回,如果没有创建变量对象的话,就创建一个新的。

参考:https://blog.youkuaiyun.com/MrR1ght/article/details/81228087
https://blog.youkuaiyun.com/UESTC_C2_403/article/details/72327321
https://www.jianshu.com/p/2061b221cd8f
https://www.w3cschool.cn/tensorflow_python/tensorflow_python-st6f2ez1.html
https://blog.youkuaiyun.com/zz2230633069/article/details/81414330

<think>好的,用户问的是能否替换TensorFlow中的tf.get_variable,我需要详细解释一下。首先,得考虑用户使用的TensorFlow版本,因为如果是TF2.x的话,tf.get_variable可能已经被弃用了。不过也有可能用户还在用TF1.x,所以需要分别说明两种情况。 在TF1.x中,tf.get_variable通常与variable_scope一起使用,特别是在需要变量共享时,比如在RNN中。这时候替换的话,可能需要用tf.Variable,但要注意是否涉及变量重用(reuse),因为在TF2.x中移除了这种机制,转而支持更Pythonic的方式,比如对象共享。 对于TF2.x,推荐使用tf.keras.layers.Layer或者tf.Module来管理变量。例如,自定义层中的build方法里使用add_variable,这其实和tf.Variable类似,但集成在Keras的框架里,方便管理。另外,eager execution在TF2.x是默认开启的,所以变量会立即创建,而不需要像TF1.x那样通过session运行。 用户可能需要替换的原因可能是迁移到TF2.x,或者想用更简洁的API。需要指出替换的方法以及注意事项,比如变量共享如何通过Python作用域或者对象实例来实现,而不是通过variable_scope。还要提到兼容性,比如使用tf.compat.v1模块可以继续使用旧的API,但不建议长期使用。 另外,可能用户对变量初始化和命名有特定需求,这时候用tf.Variable配合不同的initializer可能更直接。同时,如果用户在使用Keras,那么层中的变量会自动管理,可能不需要手动创建变量,这也是一个替代方案。 需要总结一下,替换是可行的,但要根据TF版本和具体需求来选择方法。同时提醒用户检查代码中是否有依赖于variable_scope或reuse的地方,这些在TF2.x中需要重构。可能用户的问题背后是想迁移代码到TF2,或者简化现有代码结构,所以给出迁移指南的链接可能会有帮助。</think>在 TensorFlow 中,`tf.get_variable` 是早期版本(如 TF1.x)中用于创建或获取变量的核心函数,通常与 `variable_scope` 配合使用。随着 TensorFlow 2.x 的发布,许多旧 API 被弃用或替换为更简洁的接口。以下是关于替换 `tf.get_variable` 的详细说明: -- ### **1. TensorFlow 1.x 中的 `tf.get_variable`** 在 TF1.x 中,`tf.get_variable` 主要用于: - 在变量共享(variable reuse)时创建/获取变量。 - 通过 `variable_scope` 控制变量的命名空间。 例如: ```python with tf.variable_scope("my_scope"): weights = tf.get_variable("weights", shape=[10, 5], initializer=tf.glorot_uniform_initializer()) ``` --- ### **2. TensorFlow 2.x 中的替代方案** 在 TF2.x 中,`tf.get_variable` 已被弃用,推荐使用以下方法: #### **(1) 直接使用 `tf.Variable`** - 如果不需要变量共享,直接使用 `tf.Variable`: ```python weights = tf.Variable( initial_value=tf.random.normal([10, 5]), name="weights" ) ``` #### **(2) 通过 `tf.keras` 管理变量** - 使用 Keras 层(如 `Dense`, `Conv2D`)会自动创建和管理变量: ```python layer = tf.keras.layers.Dense(units=5, kernel_initializer="glorot_uniform") output = layer(inputs) ``` - 自定义层时,在 `build` 方法中使用 `add_weight`: ```python class MyLayer(tf.keras.layers.Layer): def build(self, input_shape): self.weights = self.add_weight( name="weights", shape=(input_shape[-1], 5), initializer="glorot_uniform" ) def call(self, inputs): return tf.matmul(inputs, self.weights) ``` #### **(3) 通过 `tf.Module` 管理变量** - 使用 `tf.Module` 组织变量: ```python class MyModule(tf.Module): def __init__(self): self.weights = tf.Variable( tf.random.normal([10, 5]), name="weights" ) ``` --- ### **3. 变量共享的替代方案** 在 TF1.x 中,变量共享通过 `variable_scope(reuse=True)` 实现。在 TF2.x 中: - **直接通过对象实例共享变量**(面向对象的方式): ```python # 定义一个共享的层/模块 shared_layer = tf.keras.layers.Dense(5) # 多次调用同一实例会复用变量 output1 = shared_layer(inputs1) output2 = shared_layer(inputs2) ``` - **避免全局变量共享**,改用 Python 对象封装。 --- ### **4. 注意事项** - **命名空间**:TF2.x 中不再需要 `variable_scope`,变量名称会自动包含父对象的名称(如层名)。 - **兼容模式**:如果需在 TF2.x 中运行旧代码,可使用 `tf.compat.v1.get_variable`,但建议逐步迁移到新 API。 - **Eager Execution**:TF2.x 默认启用即时执行,变量会立即创建,无需 `tf.Session`。 -- ### **总结** - **可以替换**:在 TF2.x 中,推荐使用 `tf.Variable`、Keras 层或 `tf.Module` 替代 `tf.get_variable`。 - **迁移工具**:使用 `tf_upgrade_v2` 工具自动迁移旧代码,但需手动检查变量共享逻辑。 - **最佳实践**:以面向对象的方式组织模型(继承 `tf.keras.Model` 或 `tf.Module`)。 如果有具体的代码场景,可以提供更多细节,我可以给出更针对性的建议!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周小董

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值