【问题标题】:Does tf.zeros() return tf.get_variable()?tf.zeros() 是否返回 tf.get_variable()?
【发布时间】:2018-09-26 11:39:45
【问题描述】:

试图理解 keras 优化器 (source code) 中的 SGD 优化代码。在get_updates 模块中,我们有:

# momentum
shapes = [K.int_shape(p) for p in params]
moments = [K.zeros(shape) for shape in shapes]
self.weights = [self.iterations] + moments
for p, g, m in zip(params, grads, moments):
    v = self.momentum * m - lr * g  # velocity
    self.updates.append(K.update(m, v))

在哪里K = keras.backend。现在,既然moments 被设置为一个零张量列表,而m 是这个列表的迭代,为什么m 不总是在v = self.momentum * m - lr * g 行中计算为零张量?

现在我查找了 tensorflow (source code) 的 keras.backend.zeros 的代码,keras.backend.zeros 返回 tf.zeros,这显然返回了一个恒定的零张量。 (编辑:如果指定了形状,则返回使用 tf.zeros 初始化的 tf.Variable。)

我的直觉是它会返回类似tf.get_variable() 的东西,初始化器为零,因此张量不会每次都被覆盖。相反,名称为 m 的张量会不断被 K.update() 更新。

那么tf.zeros() 的行为实际上与tf.get_variable() 的行为相似吗?初始化为零?我还有什么遗漏的吗?

编辑:所以即使指定了形状,上面链接的源代码似乎仍然返回一个新的张量变量,而不是重用现有的张量变量(即使用get_variable()),无论如何这似乎很困难因为没有指定名称。仍然对为什么返回现有变量而不是新的零张量变量感到困惑。

【问题讨论】:

    标签: python tensorflow machine-learning keras gradient-descent


    【解决方案1】:

    我认为您错过了正确的K.zeros 功能。这是 keras 2.1 (keras/backend/tensorflow_backend.py) 中的源代码:

    def zeros(shape, dtype=None, name=None):
        """Instantiates an all-zeros variable and returns it.
    
        # Arguments
            shape: Tuple of integers, shape of returned Keras variable
            dtype: String, data type of returned Keras variable
            name: String, name of returned Keras variable
    
        # Returns
            A variable (including Keras metadata), filled with `0.0`.
    
        # Example
        ```python
            >>> from keras import backend as K
            >>> kvar = K.zeros((3,4))
            >>> K.eval(kvar)
            array([[ 0.,  0.,  0.,  0.],
                   [ 0.,  0.,  0.,  0.],
                   [ 0.,  0.,  0.,  0.]], dtype=float32)
        ```
        """
        if dtype is None:
            dtype = floatx()
        tf_dtype = tf.as_dtype(dtype)
        return variable(tf.constant_initializer(0., dtype=tf_dtype)(shape),
                        dtype, name)
    

    如您所见,它实际上返回的是 用零初始化的变量,而不是常量零张量。 documentation 声明相同:

    实例化一个全零变量并返回它。


    编辑:后续问题的答案。

    这实际上是一个很好的观察:你是对的,随后对Optimizer.get_updates(loss, params) 的调用将创建new 变量,将new 操作分配给self.updates 和新权重为self.weights。从某种意义上说,get_updates 方法是优化器构造函数的一部分。

    但它是这样工作的:这个方法在每个模型实例中被准确地调用一次。它返回在循环中针对不同批次多次应用的更新操作列表,但操作本身保持不变。下面是Model类(keras/engine/training.py)的相关代码:

    def _make_train_function(self):
        ...
        if self.train_function is None:
            ...
            with K.name_scope('training'):
                with K.name_scope(self.optimizer.__class__.__name__):
                    training_updates = self.optimizer.get_updates(
                        params=self._collected_trainable_weights,
                        loss=self.total_loss)
                updates = self.updates + training_updates + self.metrics_updates
                # Gets loss and metrics. Updates weights at each call.
                self.train_function = K.function(inputs,
                                                 [self.total_loss] + self.metrics_tensors,
                                                 updates=updates,
                                                 name='train_function',
                                                 **self._function_kwargs)
    

    self.optimizer.get_updates(...) 只被调用一次来构造train_function

    请随意检查其他优化器并检查它们是否都准备好权重并更新 get_updates() 方法内的操作。

    【讨论】:

    • 我点击了你的链接,它把我带到了与我相同的功能,github.com/keras-team/keras/blob/master/keras/backend/…。这有v = tf.zeros(shape=shape, dtype=tf_dtype, name=name) if py_all(v.get_shape().as_list()): return variable(v, dtype=dtype, name=name) return v
    • 更正了链接。显然,master 与 2.1 不同。
    • 谢谢。那么master分支现在不同了是什么意思呢?我们可以期待这种情况在未来发生变化吗?
    • 扩展了。 pydoc 说:“请注意,如果 shape 是符号,我们不能返回一个变量,而是返回一个动态形状的张量。” 像你这样的普通情况会以同样的方式表现。跨度>
    • 抱歉,再问一个问题 Maxim - 如果未指定名称,Keras 如何知道将现有张量列表返回到 moments 而不是零张量的新列表?您可以指出我的任何资源将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 2021-05-13
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    相关资源
    最近更新 更多