【问题标题】:Tensorflow variable scope: reuse if variable existsTensorflow 变量范围:如果变量存在则重用
【发布时间】:2016-11-27 11:22:34
【问题描述】:

我想要一段代码,如果它不存在,则在范围内创建一个变量,如果它已经存在,则访问该变量。我需要它是 same 代码,因为它将被多次调用。

但是,Tensorflow 需要我指定是要创建还是重用变量,如下所示:

with tf.variable_scope("foo"): #create the first time
    v = tf.get_variable("v", [1])

with tf.variable_scope("foo", reuse=True): #reuse the second time
    v = tf.get_variable("v", [1])

如何让它确定是自动创建还是重用它?即,我希望上面的两个代码块是 same 并让程序运行。

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    ValueError 在创建新变量但未声明形状或在创建变量期间违反重用时在 get_variable() 中引发。因此,你可以试试这个:

    def get_scope_variable(scope_name, var, shape=None):
        with tf.variable_scope(scope_name) as scope:
            try:
                v = tf.get_variable(var, shape)
            except ValueError:
                scope.reuse_variables()
                v = tf.get_variable(var)
        return v
    
    v1 = get_scope_variable('foo', 'v', [1])
    v2 = get_scope_variable('foo', 'v')
    assert v1 == v2
    

    请注意,以下内容也有效:

    v1 = get_scope_variable('foo', 'v', [1])
    v2 = get_scope_variable('foo', 'v', [1])
    assert v1 == v2
    

    更新。新的 API 现在支持自动重用:

    def get_scope_variable(scope, var, shape=None):
        with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
            v = tf.get_variable(var, shape)
        return v
    

    【讨论】:

    • 有没有办法使用顶级范围(即没有范围)来做到这一点?
    • @holdenlee 是的,只需将范围设置为''(即空字符串)
    • tf.make_template 也可用于创建不存在的新变量,如果存在则静默重用。
    【解决方案2】:

    新的 AUTO_REUSE 选项可以解决问题。

    来自tf.variable_scope API docs:如果reuse=tf.AUTO_REUSE,如果变量不存在,我们创建变量,否则返回它们。

    共享变量AUTO_REUSE的基本示例:

    def foo():
      with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
        v = tf.get_variable("v", [1])
      return v
    
    v1 = foo()  # Creates v.
    v2 = foo()  # Gets the same, existing v.
    assert v1 == v2
    

    【讨论】:

      【解决方案3】:

      我们可以在tf.varaible_scope 上编写我们的抽象,而不是在第一次调用时使用reuse=None,并在随后的调用中使用reuse=True

      def variable_scope(name_or_scope, *args, **kwargs):
        if isinstance(name_or_scope, str):
          scope_name = tf.get_variable_scope().name + '/' + name_or_scope
        elif isinstance(name_or_scope, tf.Variable):
          scope_name = name_or_scope.name
      
        if scope_name in variable_scope.scopes:
          kwargs['reuse'] = True
        else:
          variable_scope.scopes.add(scope_name)
      
        return tf.variable_scope(name_or_scope, *args, **kwargs)
      variable_scope.scopes = set()
      

      用法:

      with variable_scope("foo"): #create the first time
          v = tf.get_variable("v", [1])
      
      with variable_scope("foo"): #reuse the second time
          v = tf.get_variable("v", [1])
      

      【讨论】:

        【解决方案4】:

        虽然使用“try...except...”子句有效,但我认为更优雅和可维护的方法是将变量初始化过程与“重用”过程分开。

        def initialize_variable(scope_name, var_name, shape):
            with tf.variable_scope(scope_name) as scope:
                v = tf.get_variable(var_name, shape)
                scope.reuse_variable()
        
        def get_scope_variable(scope_name, var_name):
            with tf.variable_scope(scope_name, reuse=True):
                v = tf.get_variable(var_name)
            return v
        

        由于通常我们只需要初始化变量,但多次重用/共享它,分离两个进程使代码更干净。同样这样,我们不需要每次都通过“try”子句来检查变量是否已经创建。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-18
          • 2019-09-28
          • 1970-01-01
          • 1970-01-01
          • 2020-09-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多