tensorflow笔记 变量

用jupyter调试模型的时候,经常会遇到类似的错误

Variable embedding already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?
Variable encoder/embedding does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?

tf创建变量主要与三个函数tf.Variable,tf.get_variable,tf.variable_scope有关

  • tf.variable_scope
    tf.variable_scope(name, reuse)目的是创建一个变量空间,可以将之视为一个文件夹,里面储存相应在这个空间中创建的变量。

    如果变量空间没有同名变量,用get_variable()必须设置reuse=False来创建一个新变量,但如果有同名变量,reuse=False会导致上面的第一个报错。如果变量空间有同名变量,用get_variable()必须设置reuse=True来用已有变量,否则会导致第二个报错。所以最好直接令reuse=tf.AUTO_REUSE.

  • tf.Variable
    tf.Variable(name, shape)创建一个新的变量,需要赋予初始值,可以不给名字,如果名字存在,会在一个变量空间中再创建一个。

  • tf.get_variable
    tf.get_variable(name, shape)必须要给一个名字,会先搜索变量空间是否有同名的变量,如果有,检查shape是否一致,不一致会报错,一致就用该变量。如果没有,就新建一个变量。注意这里同名的变量要求是之前用get_variable创建的,即无法获取用Variable创建的同名向量。

例子:

import tensorflow as tf
with tf.variable_scope("foo", reuse=False):
    a = tf.Variable(tf.ones([2,2]),name='c')
with tf.Session() as sess:
    init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
    sess.run(init)
    print(sess.run(a))

将这段代码运行两次,看看变量空间:

import tensorflow.contrib.slim as slim
slim.get_variables()
#Output:
[<tf.Variable 'foo/c:0' shape=(2, 2) dtype=float32_ref>,
<tf.Variable 'foo_1/c:0' shape=(2, 2) dtype=float32_ref>]

重启kernel再运行下面这段代码

import tensorflow as tf
with tf.variable_scope("foo", reuse=False):
    a = tf.Variable(tf.ones([2,2]),name='c')
    b = tf.get_variable('c',[2,2])
with tf.Session() as sess:
    init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
    sess.run(init)
    print(sess.run(a))
    print(sess.run(b))

看看变量空间:

import tensorflow.contrib.slim as slim
slim.get_variables()
#Output:
[<tf.Variable 'foo/c:0' shape=(2, 2) dtype=float32_ref>,
 <tf.Variable 'foo/c_1:0' shape=(2, 2) dtype=float32_ref>]

再运行一次:

[<tf.Variable 'foo/c:0' shape=(2, 2) dtype=float32_ref>,
 <tf.Variable 'foo/c_1:0' shape=(2, 2) dtype=float32_ref>,
 <tf.Variable 'foo_1/c:0' shape=(2, 2) dtype=float32_ref>]

可以看出,Variable每次都会新建一个变量,如果有同名会建在foo_1下,get_variable如果没有会新建一个变量c_1,如果有就使用原来的变量。

猜你喜欢

转载自blog.csdn.net/thormas1996/article/details/81129379