tensorflow之变量共享

来源:互联网 发布:克伦威尔 知乎 编辑:程序博客网 时间:2024/06/05 05:16

对于tensorflow中的很多内容理解起来都不太容易,因为很多概念和普通编程的概念有很大的区别,比如对于变量而言,tensorflow创建变量有两种方式,分别是tf.Variable()和tf.get_variable(),而这两种方式又有所区别,下面通过实例进行介绍。

实例1:

wang = tf.Variable(tf.random_normal([3,3], stddev = 0.2), name = 'wang')
shuo = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[2,2],[3,3]]))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(wang.name)
    print(shuo.name)
    w = sess.run(wang)
    s = sess.run(shuo)
    print(w)
    print(s)

输出:

wang:0
shuo:0
[[-0.25720707  0.2131146  -0.25735125]
 [-0.20366143  0.25907189  0.10277599]
 [-0.25012487  0.28146097  0.23319903]]
[[ 2.  2.]
 [ 3.  3.]]

上面创建了两个变量分别是wang和shuo,可以看到两种方式都能创建变量,但是创建的形式不一样,Variable是先给初始值,在给名字参数,而get_variable是先给名字,在给shape,最后可以给出初始化值。目前还看不出两者间更大的区别,我们继续。

实例2:

wang = tf.Variable(tf.random_normal([3,3], stddev = 0.2), name = 'wang')
wang1 = tf.Variable(tf.zeros([1,1]), name='wang')
shuo = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[2,2],[3,3]]))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(wang.name)
    print(wang1.name)
    w = sess.run(wang)
    w1 = sess.run(wang1)
    print(w)
    print(w1)
assert wang1 != wang

输出:

wang:0
wang_1:0
[[-0.08472265 -0.18214481 -0.06385913]
 [-0.09954283 -0.00514754  0.20840017]
 [ 0.13883589 -0.19441269  0.05483754]]
[[ 0.]]

可以看到使用tf.Variable可以使用相同的name参数来创建变量,而此时创建的变量的名字是不一样的,分别是wang和wang_1,也就是说tensorflow会自动为通过Variable以相同名字创建的变量自动为名字添加数字编号,以用于区分,即创建了两个变量。那么如果使用相同的名字,用get_variable()创建是否会得到相同的效果?看下面实例。

实例3:

wang = tf.Variable(tf.random_normal([3,3], stddev = 0.2), name = 'wang')
#wang1 = tf.Variable(tf.zeros([1,1]), name='wang')
shuo = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[2,2],[3,3]]))
shuo1 = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[2,2],[3,3]]))
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

执行是会报错,内容是ValueError: Variable shuo already exists, disallowed. Did you mean to set reuse=True in VarScope? 是说名字为shuo的这个变量已经存在了,是否想要将reuse设置为True。也就是这个变量已经存在了,你不能再创建了。所以可以得出结论,tensorflow中每个创建的变量的内部名字都不一样,通过Variable创建变量时,即使你提供了同样的名字,tensorflow会自动在名字后添加数字以区分之前创建的变量,而get_variable的方式不会自动添加,如果之前有同样的名字,而你的scope的reuse属性不是True就会报错,告诉你已经存在这个变量了,不能再创建了。


那么,如果要获取之前存在的那个变量如何做到?答案是通过get_variable,不过tensorflow需要编程者明确指出是要获取以前的变量,使用的方法就是设置这个变量区域的reuse为True。对于什么是变量区域这里先只做简单介绍,tensorflow中任何区域都是有名字的,比如说你什么都没指定就是一个全局的scope,这个scope的名字为空,当你设置一个变量区域时,下面的那部分区域就是设置的这个变量区域,而区域的名字就是你设置的名字,可以看下面的实例:

实例4:

scope = tf.get_variable_scope()
print(scope.name)
with tf.variable_scope("wangshuo"):
    scope1 = tf.get_variable_scope()
    print(scope1.name)

输出:


wangshuo

这里只输出了一个,因为全局的是空。那么接下来看如何将一个变量区域的reuse设置为True,之后来根据名称获取变量。

实例5:

with tf.variable_scope("new") as scope:
    wang = tf.Variable(tf.random_normal([3,3], stddev = 0.2), name = 'wang')
    shuo = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[2,2],[3,3]]))
with tf.variable_scope(scope, reuse = True):
    wang1 = tf.Variable(tf.zeros([1,1]), name='wang')
    shuo1 = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[1,1],[1,1]]))
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(shuo.name)
    print(shuo1.name)
    s = sess.run(shuo)
    s1 = sess.run(shuo1)
    print(s)
    print(s1)
    print(wang.name)
    print(wang1.name)
    w = sess.run(wang)
    w1 = sess.run(wang1)
    print(w)
    print(w1)

输出:

new/shuo:0
new/shuo:0
[[ 2.  2.]
 [ 3.  3.]]
[[ 2.  2.]
 [ 3.  3.]]
new/wang:0
new_1/wang:0
[[ 0.13501269  0.14948565  0.04193816]
 [-0.10178894  0.10689952 -0.26848468]
 [ 0.19011642 -0.26536456  0.11259288]]
[[ 0.]]

可以看到同样的实现方式,使用Variable和get_variable得到不同的效果,使用Variable是创建了两个不同的变量,而是使用get_variable是创建一个变量,随后又获取了该变量。


这里最后还涉及到变量的保存,变量保存使用tf.train.Saver()来实现,在构造函数是可以对指定var_list参数,即需要保存的变量,使用字典形式给出。

实例:

with tf.variable_scope("new") as scope:
    wang = tf.Variable(tf.zeros([3,3]), name = 'wang')
    shuo = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[0,0],[0,0]]))
with tf.variable_scope(scope, reuse = True):
    wang1 = tf.Variable(tf.zeros([1,1]), name='wang')
    shuo1 = tf.get_variable('shuo', shape=[2,2], initializer = tf.constant_initializer([[1,1],[1,1]]))
saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    saver.restore(sess, "./model.ckpt")

    #saver.save(sess, "./model.ckpt")
    
    print(shuo.name)
    print(shuo1.name)
    s = sess.run(shuo)
    s1 = sess.run(shuo1)
    print(s)
    print(s1)
    print(wang.name)
    print(wang1.name)
    w = sess.run(wang)
    w1 = sess.run(wang1)
    print(w)
    print(w1)


可以先保存,之后改变变量初始值的大小,之后再restore来验证。

原创粉丝点击