a.只会初始化之前定义了的变量,从实验3中注释了initialize之后无法运行可以看出
b.这里有个疑问是实验中z w两个变量的创建似乎没有进入到函数中,sess.run()时也没有进入其中?参看实验 4
c.关于b,在随后检查输出后发现,在最上方有print(1)和print(var1)的输出,粘贴的时候省略tf建立计算图的一堆提示,没有注意最上方的输出。
d.只有在建立计算图时会进入函数,sess.run()时只用计算图,不会调用函数
a.参看实验6,其作用正如官方文档中的解释
Given an arbitrary function, wrap it so that it does variable sharing.
给定一个任意函数,将其包装,以便它进行变量共享.
b.重用时注意函数的名称需要完全一致,参看实验4 5
c.变量重用还可以在name_scope.reuse_variables()的方法下实现,参看实验8
1.初始代码:
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var1 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(var1)
return x * var1
with tf.compat.v1.variable_scope('scope') as vs:
scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y',scalar=3)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
w = scale_by_y(tf.constant(5.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
with tf.compat.v1.variable_scope('c', reuse=False):
scale_by_y2 = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='x', scalar=4)
z2 = scale_by_y2(tf.constant(3.))
w2 = scale_by_y2(tf.constant(4.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z2))
print(sess.run(w2))
代码输出:
6.0
15.0
12.0
16.0
可见scale_by_y函数并没有打印变量var1,猜测是没有initialize的原因,而在scale_by_y2函数调用时打印了其中的var1
真正的输出:
#此处省略一堆tf的提示
6.0
15.0
#此处省略两行tf的提示
12.0
16.0
因此只有在最初建立计算图时会进入函数,sess.run()时只会使用计算图,而不会再次调用函数。
另外之后的所有输出都不再修改,阅读请注意这点。
2.添加一行之后
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var1 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(var1)
return x * var1
with tf.compat.v1.variable_scope('scope') as vs:
scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y',scalar=3)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
w = scale_by_y(tf.constant(5.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# z = scale_by_y(tf.constant(2,dtype=tf.float32))
# w = scale_by_y(tf.constant(5.))
print(sess.run(z))
print(sess.run(w))
with tf.compat.v1.variable_scope('c', reuse=False):
scale_by_y2 = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='x', scalar=4)
# 此处为添加代码
z = scale_by_y(tf.constant(2,dtype=tf.float32))
# 上方为添加代码
z2 = scale_by_y2(tf.constant(3.))
w2 = scale_by_y2(tf.constant(4.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z2))
print(sess.run(w2))
此时输出为:
6.0
15.0
12.0
16.0
3.随后将第二处的 sess.run(tf.global_variables_initializer()) 注释掉,同时z2 w2的variable_scope改为vs,无法运行
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var1 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(var1)
return x * var1
with tf.compat.v1.variable_scope('scope') as vs:
scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y',scalar=3)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
w = scale_by_y(tf.constant(5.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
with tf.compat.v1.variable_scope(vs, reuse=False):
scale_by_y2 = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='x', scalar=4)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
z2 = scale_by_y2(tf.constant(3.))
w2 = scale_by_y2(tf.constant(4.))
with tf.Session() as sess:
# sess.run(tf.global_variables_initializer())
print(sess.run(z2))
print(sess.run(w2))
4.对my_op进行修改,添加一行输出
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var1 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var1)
return x * var1
with tf.compat.v1.variable_scope('scope') as vs:
scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y',scalar=3)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
w = scale_by_y(tf.constant(5.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
with tf.compat.v1.variable_scope(vs, reuse=False):
scale_by_y2 = tf.compat.v1.make_template('scale_by_y2', my_op,
scalar_name='x', scalar=4)
z2 = scale_by_y2(tf.constant(3.))
w2 = scale_by_y2(tf.constant(4.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z2))
print(sess.run(w2))
输出为
6.0
15.0
1
1
12.0
16.0
似乎z w两个变量在创建时根本没有进入my_op函数,在sess.run()时也没有,反而是在z2 w2定义时进入了函数,但在run时同样没有进入函数,那么函数对于tensorflow而言主要是向计算图中添加节点,run时不会调用。
5.关于reuse=True,这段代码中必须scalar_name, func_name, variable_scope完全一致,这也是不出预料的,即变量的名字必须完全相同,reuse才可以,这是重新定义的值是无效的
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var1 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var1)
return x * var1
with tf.compat.v1.variable_scope('scope') as vs:
scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y',scalar=3)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
w = scale_by_y(tf.constant(5.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
with tf.compat.v1.variable_scope(vs, reuse=True):
scale_by_y2 = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y', scalar=4)
z2 = scale_by_y2(tf.constant(3.))
w2 = scale_by_y2(tf.constant(4.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z2))
print(sess.run(w2))
输出为
6.0
15.0
1
1
9.0
12.0
scalar_by_y2的倍数值是3,而非传入的4,即reuse生效,重用了之前scalar_by_y定义的倍数
5. 关于make_template的作用
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var1 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var1)
return x * var1
def my_op2(x, scalar_name, scalar):
var2 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var2)
return x + var2
with tf.compat.v1.variable_scope('scope') as vs:
scale_by_y = tf.compat.v1.make_template('scale_by_y', my_op,
scalar_name='y',scalar=3)
z = scale_by_y(tf.constant(2,dtype=tf.float32))
w = scale_by_y(tf.constant(5.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
with tf.compat.v1.variable_scope(vs, reuse=True):
scale_by_y2 = tf.compat.v1.make_template('scale_by_y', my_op2,
scalar_name='y', scalar=4)
z2 = scale_by_y2(tf.constant(3.))
w2 = scale_by_y2(tf.constant(4.))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z2))
print(sess.run(w2))
输出为
6.0
15.0
1
1
6.0
7.0
及时重新定义了函数my_op2,以及其中的变量名var2,但对于计算图而言,其名称还是 scope/scale_by_y/y:0 ,因此可以重用
6.关注make_template的作用
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var2 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var2)
return x * var2
with tf.compat.v1.variable_scope('scope') as vs:
z = my_op(tf.constant(2,dtype=tf.float32),'y',3)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
这时有正常输出:
6.0
7.添加定义w之后,程序报错
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var2 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var2)
return x * var2
with tf.compat.v1.variable_scope('scope') as vs:
z = my_op(tf.constant(2,dtype=tf.float32),'y',3)
w = my_op(tf.constant(5.),'y',3)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
# print(sess.run(w))
这里print(sess.run(w))被注释掉了,同时输出中给出的错误提示也是在z的定义处,因此直接使用my_op无法进行变量共享
7.将定义w的变量改名为x,正常输出
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var2 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var2)
return x * var2
with tf.compat.v1.variable_scope('scope') as vs:
z = my_op(tf.constant(2,dtype=tf.float32),'y',3)
w = my_op(tf.constant(5.),'x',4)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
输出为:
6.0
20.0
8.变量重用还可以在variable_scope的框架下进行,通过reuse_variables()方法可以重用变量
import tensorflow as tf
def my_op(x, scalar_name, scalar):
var2 = tf.compat.v1.get_variable(scalar_name,
shape=[],
initializer=tf.compat.v1.constant_initializer(scalar))
print(1)
print(var2)
return x * var2
with tf.compat.v1.variable_scope('scope') as vs:
z = my_op(tf.constant(2,dtype=tf.float32),'y',3)
vs.reuse_variables()
w = my_op(tf.constant(5.),'y',4)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(z))
print(sess.run(w))
输出为
6.0
15.0
可见重新定义的var1=4没有生效,而是重用了之前定义的值3