在训练深度网络时,为了减少需要训练参数的个数(比如具有simase结构的LSTM模型)、或是多机多卡并行化训练大数据大模型(比如数据并行化)等情况时,往往需要共享变量。另外一方面是当一个深度学习模型变得非常复杂的时候,往往存在大量的变量和操作,如何避免这些变量名和操作名的唯一不重复,同时维护一个条理清晰的graph非常重要。

因此,tensorflow中用tf.Variable(),tf.get_variable(),tf.Variable_scope(),tf.name_scope()几个函数来实现:


一、tf.Variable(<variable_name>),tf.get_variable(<variable_name>)的作用与区别:

tf.Variable(<variable_name>)和tf.get_variable(<variable_name>)都是用于在一个name_scope下面获取或创建一个变量的两种方式,区别在于:

  1. tf.Variable(<variable_name>)会自动检测命名冲突并自行处理,但tf.get_variable(<variable_name>)则遇到重名的变量创建且变量名没有设置为共享变量时,则会报错。
  2. tf.Variable(<variable_name>)用于创建一个新变量,在同一个name_scope下面,可以创建相同名字的变量,底层实现会自动引入别名机制,两次调用产生了其实是两个不同的变量。

    tf.get_variable(<variable_name>)用于获取一个变量,并且不受name_scope的约束。当这个变量已经存在时,则自动获取;如果不存在,则自动创建一个变量。
二、tf.name_scope(<scope_name>)与tf.variable_scope(<scope_name>)的作用与区别:

tf.name_scope(<scope_name>):主要用于管理一个图里面的各种op,返回的是一个以scope_name命名的context manager。一个graph会维护一个name_space的

堆,每一个namespace下面可以定义各种op或者子namespace,实现一种层次化有条理的管理,避免各个op之间命名冲突。

tf.variable_scope(<scope_name>):一般与tf.name_scope()配合使用,用于管理一个graph中变量的名字,避免变量之间的命名冲突,tf.variable_scope(<scope_name>)允许在一个variable_scope下面共享变量。

代码示例:

在 tf.name_scope下时,tf.get_variable()创建的变量名不受 name_scope 的影响,而且在未指定共享变量时,如果重名会报错,tf.Variable()会自动检测有没有变量重名,如果有则会自行处理。

import tensorflow as tf

with tf.name_scope('name_scope_x'):
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
var3 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
var4 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32) with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var3.name, sess.run(var3))
print(var4.name, sess.run(var4))
# 输出结果:
# var1:0 [-0.30036557] 可以看到前面不含有指定的'name_scope_x'
# name_scope_x/var2:0 [ 2.]
# name_scope_x/var2_1:0 [ 2.] 可以看到变量名自行变成了'var2_1',避免了和'var2'冲突

如果使用tf.get_variable()创建变量,且没有设置共享变量,重名时会报错

import tensorflow as tf

with tf.name_scope('name_scope_1'):
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var2.name, sess.run(var2)) # ValueError: Variable var1 already exists, disallowed. Did you mean
# to set reuse=True in VarScope? Originally defined at:
# var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)

所以要共享变量,需要使用tf.variable_scope()

import tensorflow as tf

with tf.variable_scope('variable_scope_y') as scope:
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
scope.reuse_variables() # 设置共享变量
var1_reuse = tf.get_variable(name='var1')
var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
var2_reuse = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32) with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var1_reuse.name, sess.run(var1_reuse))
print(var2.name, sess.run(var2))
print(var2_reuse.name, sess.run(var2_reuse))
# 输出结果:
# variable_scope_y/var1:0 [-1.59682846]
# variable_scope_y/var1:0 [-1.59682846] 可以看到变量var1_reuse重复使用了var1
# variable_scope_y/var2:0 [ 2.]
# variable_scope_y/var2_1:0 [ 2.]

tf.variable和tf.get_Variable以及tf.name_scope和tf.variable_scope的区别的更多相关文章

  1. 理解 tf.Variable、tf.get_variable以及范围命名方法tf.variable_scope、tf.name_scope

    tensorflow提供了通过变量名称来创建或者获取一个变量的机制.通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递. 1. tf.Variable( ...

  2. tf.Variable

    tf.Variable __init__( initial_value=None, trainable=True, collections=None, validate_shape=True, cac ...

  3. TF.VARIABLE、TF.GET_VARIABLE、TF.VARIABLE_SCOPE以及TF.NAME_SCOPE关系

    1. tf.Variable与tf.get_variable tensorflow提供了通过变量名称来创建或者获取一个变量的机制.通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要 ...

  4. 彻底弄懂tf.Variable、tf.get_variable、tf.variable_scope以及tf.name_scope异同

    https://blog.csdn.net/qq_22522663/article/details/78729029 1. tf.Variable与tf.get_variabletensorflow提 ...

  5. tensorflow共享变量 the difference between tf.Variable() and get_variable()

    一般这样用tf.get_variable(): v = tf.get_variable(name, shape, dtype, initializer) 下面内容来源于 http://blog.csd ...

  6. tf.Variable() 与tf.get_variable()的区别

    每次调用 tf.Variable() 都会产生一个新的变量,变量名称是一个可选参数,运行命名相同,如果命名冲突会根据命名先后对名字进行处理, tf.get_variable()的变量名称是必填参数,t ...

  7. TensorFlow函数(二)tf.get_variable() 和 tf.Variable()

    tf.Variable(<initial - value>,name=<optional - name>) 此函数用于定义图变量.生成一个初始值为initial - value ...

  8. tf.Variable()、tf.get_variable()和tf.placeholder()

    1.tf.Variable() tf.Variable(initializer,name) 功能:tf.Variable()创建变量时,name属性值允许重复,检查到相同名字的变量时,由自动别名机制创 ...

  9. tf.name_scope()和tf.variable_scope() (转)

    网络层中变量存在两个问题: 随着层数的增多,导致变量名的增多: 在调用函数的时候,会重复生成变量,但他们存储的都是一样的变量.   tf.variable不能解决这个问题. 变量作用域使用tf.var ...

随机推荐

  1. python下划线作用初识

    单下划线(例:_textchar) 以单下划线做前缀的名称指定了这个名称是"私有的".在 有些 导入import * 的场景中,下一个使用你代码的人(或者你本人)会明白这个名称仅内 ...

  2. Linux make nginx 的时候报错

    报错如下: `conf/koi-win' and `/usr/local/nginx/conf/koi-win' are the same file   原因: 可能在编译 nginx 的时候步骤不对 ...

  3. MySql按日期进行统计

    1 数据库字段pk_time(Varchar) 当天的数据 SELECT * FROM 表 WHERE date(fk_time) = curdate(); 当月的数据 SELECT *FROM 表 ...

  4. android 页面的切换

    startActivity后加:IntentHelper.jump(mContext, MyBalanceActivity.class);activity.overridePendingTransit ...

  5. c# 基础任务1

    1.winform系统全局异常布局处理. Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);   ...

  6. MySQL数据库学习笔记----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  7. LAMP_yum安装

    前言,人总是会越来越懒,说真的,我是摸着良心说话的 开始总是喜欢源码安装,因为可以定制,而且能显得有格调(逼格),但是一安装就要半天,还有各种依赖包的安装,各种报错,不忍直视 下面是我摘自晚上的一篇l ...

  8. javascript:将URL的参数列表解析为一个对象

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. Prime - 程序员的修养

    求质数算法的N种境界 求质数算法的N种境界[1] - 试除法和初级筛法 过程 尽管题目并没有要我们写一个最优的算法,但是身为一个程序员,优化应该是一种习惯,在编程的过程中,随着思考进行优化. 如果你只 ...

  10. linux下iptables配置模板

    linux下iptables配置模板 # Flush all policy iptables -F iptables -X iptables -Z iptables -t nat -F iptable ...