【TensorFlow-windows】name_scope与variable_scope

前言

探索一下variable_scopename_scope相关的作用域,为下一章节tensorboard的学习做准备

其实关于variable_scopeget_variable实现变量共享,在最开始的博客有介绍过:

【TensorFlow-windows】学习笔记二——低级API

当然还是国际惯例,参考博客:

tensorflow: name_scope 和 variable_scope区别及理解

tensorflow学习笔记(十七):name&variable scope

tensorflow官方文档name_scope

tensorflow官方文档get_varialbe

tensorflow官方文档variable_scope

variable_scope相关

先引入对应包:

import tensorflow as tf
import numpy as np

Variable定义的变量是否共享

a1 = tf.Variable(1,name='aaa')
a2 = tf.Variable(2,name='aaa')
init=tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    print(a1.eval())#1
    print(a2.eval())#2
print(a1) #<tf.Variable 'aaa:0' shape=() dtype=int32_ref>
print(a2) #<tf.Variable 'aaa_1:0' shape=() dtype=int32_ref>

结论:Variable定义的权重不共享,会自动给变量按照定义顺序加后缀_索引,比如第2此定义的aaa得到的名字是aaa_1,所以他们是完全不同的两个变量,名称也不同。

Variable定义与get_variable定义有什么区别

#variable创建方式
tf.Variable(<initial-value>, name=<optional-name>)
#get_variable创建方式
tf.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
)

结论:Variable定义不实现共享,所以只需要初始值就行了,名字无所谓。get_variable要通过名字实现共享,所以必须给变量一个名字,其余无所谓。

直接定义两个同名的get_variable变量

b1 = tf.get_variable(name='b',initializer=10)
init = tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    print(b1.eval())#10
b2 = tf.get_variable(name='b',initializer=20)
'''
Variable b already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:
'''

结论:不能直接定义两个同名get_variable变量,必须通过特定方法实现共享

第一种共享方法

variable_scope内部使用reuse_variables函数:

with tf.variable_scope('dd') as scope:
    d1=tf.get_variable(name='d',initializer=10.0,dtype=tf.float32)
    scope.reuse_variables()
    d2=tf.get_variable(name='d',initializer=20.0,dtype=tf.float32)

上述在同一个变量空间中,定义两个同名变量,通过reuse_variable实现共享,输出结果如下:

print(d1,d2)
init=tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    print(d1.eval(),d2.eval())
'''
<tf.Variable 'dd/d:0' shape=() dtype=float32_ref> <tf.Variable 'dd/d:0' shape=() dtype=float32_ref>
10.0 10.0
'''

结论:可以通过reuse_variable实现共享,但是第二次初始化的值是无法覆盖第一次初始化的值的

第二种共享方法

在使用variable_scope建立变量空间的时候,如果是复用一个已定义的变量空间中的变量,直接将reuse设置为True

with tf.variable_scope('ff') as scope:
    f1=tf.get_variable(name='f',initializer=10.0,dtype=tf.float32)
with tf.variable_scope('ff',reuse=True) as scope:
    f2=tf.get_variable(name='f',initializer=20.0,dtype=tf.float32)
with tf.variable_scope('gg') as scope:
    g=tf.get_variable(name='f',initializer=20.0,dtype=tf.float32)

输出看看

print(f1,f2,g)
init=tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    print(f1.eval(),f2.eval(),g.eval())
'''
<tf.Variable 'ff/f:0' shape=() dtype=float32_ref> <tf.Variable 'ff/f:0' shape=() dtype=float32_ref> <tf.Variable 'gg/f:0' shape=() dtype=float32_ref>
10.0 10.0 20.0
'''

结论:可以通过函数参数reuse实现变量共享

不同变量空间中的相同名称变量是否共享

结论:无法共享,比如上例中f1g无法共享,虽然名称都是f,但是所在变量空间不同。

第三种共享方法

调用函数的时候,自动检测是否需要reuse

with tf.variable_scope('ee',reuse=tf.AUTO_REUSE) as scope:
    e2=tf.get_variable(name='e',initializer=10.0,dtype=tf.float32)
    e3=tf.get_variable(name='e',initializer=20.0,dtype=tf.float32)
with tf.variable_scope('ee',reuse=tf.AUTO_REUSE) as scope:
    e4=tf.get_variable(name='e',initializer=30.0,dtype=tf.float32)
init = tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    print(e2,e3,e4)
    print(e2.eval(),e3.eval(),e4.eval())
'''
<tf.Variable 'ee/e:0' shape=() dtype=float32_ref> <tf.Variable 'ee/e:0' shape=() dtype=float32_ref> <tf.Variable 'ee/e:0' shape=() dtype=float32_ref>
10.0 10.0 10.0
'''

如果之前没创建过共享变量,不适用自动检测,而直接reuse会报错

with tf.variable_scope('ee',reuse=True) as scope:
    e2=tf.get_variable(name='e',initializer=10.0,dtype=tf.float32)
'''
 Variable ee/e does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?
'''

结论:如果不确定之前是否创建过共享变量,最好是使用AUTO_REUSE自动检测

name_scope相关

直接用namescope是否能隔绝共享变量

with tf.name_scope('f') as nscope:
    f1 = tf.get_variable('f',initializer=10.0,dtype=tf.float32)
with tf.name_scope('g') as nscope:
    g = tf.get_variable('f',initializer=20.0,dtype=tf.float32)
'''
Variable f already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:
'''

结论:无法直接用name_scope隔绝共享变量

在不同namesope中是否可以共享变量

创建两个命名空间,但是两个命名空间包含相同的变量空间,设置共享变量h

with tf.name_scope('test1') as scope:
    with tf.variable_scope('h',reuse=tf.AUTO_REUSE):
        h1 = tf.get_variable('hh',initializer=10.0,dtype=tf.float32)
with tf.name_scope('test2') as scope:
    with tf.variable_scope('h',reuse=tf.AUTO_REUSE):
        h2 = tf.get_variable('hh',initializer=10.0,dtype=tf.float32)

测试是否能实现变量共享

init = tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    print(h1,h2)
    print(h1.eval(),h2.eval())
    op=tf.assign(h1,30.0)
    sess.run(op)
    print(h1.eval(),h2.eval())
'''
<tf.Variable 'h/hh:0' shape=() dtype=float32_ref> <tf.Variable 'h/hh:0' shape=() dtype=float32_ref>
10.0 10.0
30.0 30.0
'''

结论:命名空间不能控制是否共享,但是变量空间可以控制变量共享。

总结

get_variablevariable_scope配合可以实现变量共享。

name_scope无法实现变量共享,但是如果看过之前的博客可以发现,它的一个作用是将一系列操作封装在一起,这样画图的时候网络结构比较清晰。

其它作用以后遇到再补充,主要是为了下一章节学习tensorboard做准备。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风翼冰舟

额~~~CSDN还能打赏了

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

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

打赏作者

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

抵扣说明:

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

余额充值