IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> tensorflow 变量及命名空间 tf.Variable() vs tf.get_variable() & tf.name_scope() vs tf.variable_scope() -> 正文阅读

[游戏开发]tensorflow 变量及命名空间 tf.Variable() vs tf.get_variable() & tf.name_scope() vs tf.variable_scope()

tf.Variable() vs tf.get_variable()
tf.name_scope() vs tf.variable_scope()

1. 基础功能

1.1 tf.Variable()

是一个类,tensorflow.python.ops.variables.Variable,其构造函数原型为

def __init__(
    self,
    initial_value: Any = None,
    trainable: bool = True,
    collections: Any = None,
    validate_shape: bool = True,
    caching_device: Any = None,
    name: Any = None,
    variable_def: Any = None,
    dtype: Any = None,
    expected_shape: Any = None,
    import_scope: Any = None,
    constraint: Any = None
) -> Any

创建一个初始值为 initial_value 的变量。
Params:(仅关注几个常用的)

  • initial_value – 变量初始值,是一个 Tensor 或者 可转换为 Tensor 的 python 对象;
  • trainable – 可否训练;
  • collections – 一个 List[graph collections keys],变量将会加入这些 collections,列表默认为 [GraphKeys.GLOBAL_VARIABLES]
  • nameOptional(可选) 变量的名字,默认为 'Variable',如果已有同名变量,则新变量 name 为 'Variable_num',其中 num 递增;
  • constraint – 一个可选的投影函数,在被 Optimizer(例如,用于实现层权重的范数约束或值约束)更新之后应用于该变量。该函数必须将代表变量值的未投影张量作为输入,并返回投影值的张量(它必须具有相同的形状)。进行异步分布式训练时,约束条件不安全。

例子:

a = tf.Variable(
    initial_value=[1.0, 2.0],
    trainable=True,
    name='va',
    dtype=tf.float32
)
print(a)  # <tf.Variable 'va:0' shape=(2,) dtype=float32_ref>

1.2 tf.get_variable()

函数,原型为:

def get_variable(
    name: Any,
    shape: Any = None,
    dtype: Any = None,
    initializer: Any = None,
    regularizer: Any = None,
    trainable: Any = None,
    collections: Any = None,
    caching_device: Any = None,
    partitioner: Any = None,
    validate_shape: bool = True,
    use_resource: Any = None,
    custom_getter: Any = None,
    constraint: Any = None,
    synchronization: VariableSynchronization = VariableSynchronization.AUTO,
    aggregation: VariableAggregation = VariableAggregation.NONE
) -> Any

通过变量名来获取或创建一个变量。
Params:(仅关注几个常用的)

  • name必填 变量的名字,如果已有同名变量,则报错(variable_scope(reuse=True) 除外);
  • shape – 变量形状;
  • dtype – 数据类型;本来猜测 initializer 中的 dtype 可能只决定随机值,最终类型由此参数决定,initializer 中的 dtype 似乎并不起作用
  • initializer – 初始化器,如 tf.tf.random_uniform_initializer(minval=1, maxval=10)
  • regularizer – 可能是传入一个正则化器,如 `tf.contrib.layers.l2_regularizer(0.1)';
  • synchronization – 以后再说(应该挺有用的);

例子:

a = tf.get_variable(
	name='v',
	shape=[1, 2],
	dtype=tf.float64,
	initializer=tf.random_uniform_initializer(
        minval=1,
        maxval=10,
        dtype=tf.int32
    )  # initializer 里的 dtype 没什么卵用
)
print(a)  # `<tf.Variable 'v:0' shape=(1, 2) dtype=float64_ref>`
with tf.Session() as sess:
	sess.run(tf.global_variables_initializer())
	print(sess.run(a))  # [[3.98646081 3.30710938]]

1.3 tf.name_scope()

def __init__(
    self,
    name: Any,
    default_name: Any = None,
    values: Any = None
) -> None

初始化上下文管理器。
Params:

  • name – 传递给 OP 函数的 name 参数;
  • default_name – 如果 name 参数为 None 则使用默认的名称;
  • values – 要传递给 op 函数的张量参数列表(不清楚);

这篇博文 讲得不错。

例子:

with tf.name_scope(name='ns'):
	a = tf.Variable(0.0)
	b = tf.Variable(0.0)
	c = a + b
print(a)  # <tf.Variable 'ns/Variable:0' shape=() dtype=float32_ref>  
print(b)  # <tf.Variable 'ns/Variable_1:0' shape=() dtype=float32_ref>
print(c)  # Tensor("ns/add:0", shape=(), dtype=float32)

1.4 tf.variable_scope()

def __init__(
    self,
    name_or_scope: Any,
    default_name: Any = None,
    values: Any = None,
    initializer: Any = None,
    regularizer: Any = None,
    caching_device: Any = None,
    partitioner: Any = None,
    custom_getter: Any = None,
    reuse: Any = None,
    dtype: Any = None,
    use_resource: Any = None,
    constraint: Any = None,
    auxiliary_name_scope: bool = True
) -> Any

初始化上下文管理器。
Params:

  • name_or_scopestring or VariableScope: 要打开的 scope;
  • default_name – 如果参数 name_or_scopeNone, 则启用默认名;
  • values – 要传递给 op 函数的张量参数列表(不清楚);
  • reuseTrue, None, or tf.AUTO_REUSE
    • 如果为 True,该 scope 及其 sub-scope(reuse=None)开启 reuse 模式,get_variable(name='v') 将获取已有的 name == v 的变量;
    • 如果为 tf.AUTO_REUSEget_variable(name='v') 创建新变量 if v 不存在 esle 获取已有变量 v
    • 如果为 None,则继承其 parent-scope 的 reuse flag;

Returns:
A scope that can be captured and reused. 可以作为参数传递给 tf.variable_scope()

例子

with tf.variable_scope('vs') as scope:
	a = tf.get_variable(name='a', shape=[2, 3], initializer=tf.random_uniform_initializer(0.0, 1.0))
print(a)  # <tf.Variable 'vs/a:0' shape=(2, 3) dtype=float32_ref>
with tf.variable_scope(scope, reuse=True):  # 需要指明 reuse
	b = tf.get_variable(name='a')
print(a is b)  # True

2. 四者之间的关系

2.1 tf.Variable() 和 tf.get_variable()

# 两个定义是等价的
v = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
print(v)  # <tf.Variable 'v:0' shape=(1,) dtype=float32_ref>
  • 最大的区别在于tf.Variable()name 是可选的;而 tf.get_variable()name 是必填的;
  • 当已存在同名变量时:tf.Variable() 会在变量名后加 _n 其中 n 递增;而 tf.get_variable() 会报错(最后一个例子特殊,如果已存在 tf.Variable() 创建的同名变量,则遵循 +1 规则);

例子

a = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
b = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
print(a)  # <tf.Variable 'v:0' shape=(1,) dtype=float32_ref>
print(b)  # <tf.Variable 'v_1:0' shape=(1,) dtype=float32_ref>
a = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
b = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
# ValueError: Variable v already exists, disallowed.
a = tf.Variable(1.0, name='v')
b = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
c = tf.Variable(1.0, name='v1')
d = tf.get_variable(name='v1', shape=[1], initializer=tf.constant_initializer(1.0))
print(a)  # <tf.Variable 'v:0' shape=() dtype=float32_ref>
print(b)  # <tf.Variable 'v_1:0' shape=(1,) dtype=float32_ref>
print(c)  # <tf.Variable 'v1:0' shape=() dtype=float32_ref>
print(d)  # <tf.Variable 'v1_1:0' shape=(1,) dtype=float32_ref>

只有在 tf.get_variable() & tf.get_variable() 的情况下重名才报错,其他情况遵循 +1 规则。

2.2 tf.Variable() 和 tf.name_scope()

with tf.name_scope('ns'):
	a = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
b = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
print(a)  # <tf.Variable 'ns/v:0' shape=(1,) dtype=float32_ref>
print(b)  # <tf.Variable 'v:0' shape=(1,) dtype=float32_ref>

2.3 tf.Variable() 和 tf.variable_scope()

with tf.variable_scope('vs'):
	a = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
b = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
print(a)  # <tf.Variable 'vs/v:0' shape=(1,) dtype=float32_ref>
print(b)  # <tf.Variable 'v:0' shape=(1,) dtype=float32_ref>

此时,tf.variable_scope() == tf.name_scope()

2.4 tf.get_variable() 和 tf.name_scope()

with tf.name_scope('ns'):
	a = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
# b = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
print(a)  # <tf.Variable 'v:0' shape=(1,) dtype=float32_ref>
# print(b)  # Err

tf.name_scope()tf.get_variable() 不起作用。

2.5 tf.get_variable() 和 tf.variable_scope()

with tf.variable_scope(
		'vs',
		initializer=tf.constant_initializer(1.0),
		regularizer=tf.contrib.layers.l2_regularizer(0.01)
):
	a = tf.Variable(0.0, name='v')
	b = tf.get_variable(name='v', shape=[1])

print(a)  # <tf.Variable 'vs/v:0' shape=() dtype=float32_ref>
print(b)  # <tf.Variable 'vs/v_1:0' shape=(1,) dtype=float32_ref>

with tf.Session() as sess:
	sess.run(tf.global_variables_initializer())
	print(sess.run(a))  # 0.0
	print(sess.run(b))  # [1.]
  • tf.get_variable()tf.variable_scope() 是更强大的结合,可以设置 scope 下变量的默认属性。但对 tf.Variable() 来说,没有这些功能。
    图1
图 1 正则化器 regularizer 的输入只有 v_1

图 1 说明 a 的初始化是自己的 initial_value,regularizer 也未作用到 a 上。而 b 得到了这两个默认属性。

  • reuse 功能给了编程更大的灵活性
def forward(input_tensor):
	with tf.variable_scope('vs', reuse=tf.AUTO_REUSE, initializer=tf.constant_initializer(3.0)):
		w = tf.get_variable(name='w', shape=[1])
	return input_tensor * w


a = tf.get_variable(name='input', shape=[1], initializer=tf.constant_initializer(2.0))
b = forward(a)
c = forward(b)

with tf.Session() as sess:
	sess.run(tf.global_variables_initializer())
	print(sess.run(a))  # [2.]
	print(sess.run(b))  # [6.]
	print(sess.run(c))  # [18.]
在这里插入图片描述在这里插入图片描述
get_variavble()Variavble()
图2 tf.variable_scope() reuse 的作用

可以看到,wtf.get_variable() 时得到了 reuse,非常方便。而 wtf.Variable() 则不 reuse。

结论

tf.get_variable()tf.variable_scope() 一起可以发挥强大灵活的作用。而 tf.Variable() 只把 tf.variable_scope() 当作简化的 tf.name_scope() 使用。

2.6 tf.name_scope() 和 tf.variable_scope()

  • 2.22.3 可以看到,tf.name_scope()tf.variable_scope() 下,tf.Variable() 的名字都会加上前缀 scope
    2.4 说明tf.name_scope()tf.get_variable() 不起作用;
  • tf.name_scope() 更像是 tf.variable_scope() 的阉割版,从形参上看,前者较为简单,被后者完全覆盖;tf.variable_scope() 的形参中存在大量针对变量的参数(几乎是 name_scope + get_variable 参数的合集),如 initializerregularizer 等,可以指定 scope 内创建的变量的默认属性;
  • 重名+1:与 tf.Variable() 一样,空间重名 +1,(tf.variable_scope() 不使用 tf.get_variable() 时)
with tf.name_scope('s'):
	a = tf.Variable(0.0, name='v')
	c = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
with tf.name_scope('s'):
	b = tf.Variable(0.0, name='v')
print(a)  # <tf.Variable 's/v:0' shape=() dtype=float32_ref>
print(b)  # <tf.Variable 's_1/v:0' shape=() dtype=float32_ref>
print(c)  # <tf.Variable 'v:0' shape=(1,) dtype=float32_ref>

with tf.variable_scope('s'):
	a = tf.Variable(0.0, name='v')
	c = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
with tf.variable_scope('s'):
	b = tf.Variable(0.0, name='v')
	# d = tf.get_variable(name='v', shape=[1], initializer=tf.constant_initializer(1.0))
print(a)  # <tf.Variable 's_2/v:0' shape=() dtype=float32_ref>
print(b)  # <tf.Variable 's_3/v:0' shape=() dtype=float32_ref>
print(c)  # <tf.Variable 's/v_1:0' shape=(1,) dtype=float32_ref>,变量重名 +1
# print(d)  # Err,对于 b = Variable() 而言,s+1,对于 d = tf.get_variable() 而言,s 内变量重名报错

Note1 可以看到,当用于 tf.Variable() 时,tf.variable_scope()tf.name_scope() 没什么区别,重名的话都会使空间名自动 +1,即使混用,也一样;

Note2 发现一个很有意思的现象:

在第三个 scope 中,a 和 c 竟然不是同一个 scope,{a:s_2, c:s},可见,当 tf.variable_scope() 用于 tf.get_variable(),空间会另起炉灶(这个新炉灶不会+1)。
且新炉灶的第一个 tf.get_variable() 前有 tf.Variable() 创建的重名变量的话,则命名重复 +1。
所以,tf.variable_scope() 下, tf.get_variable()tf.Variable() 混用时,实际上是各自独立的

总结

当使用 tf.Variable() 时,tf.name_scope()tf.variable_scope() 没什么区别;
当使用 tf.get_variable() 时,tf.name_scope() 不起作用。
tf.variable_scope() 下, tf.get_variable()tf.Variable() 混用时,实际上是各自独立的

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:49:29  更:2022-04-09 18:50:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 20:46:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码