为什么tf.assign需要永久改变张量流变量的值

2024-05-23 16:33:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图修改Keras的随机梯度下降类(SGD),这样我就可以在所选的时间段为学习率分配新的值。为此,我修改了该类的get_updates方法,如下所示:

@interfaces.legacy_get_updates_support
def get_updates(self, loss, params):

---------------  My Changes Start ----------------------------------
    def lr_stepper(iteration, lr):
        ''' Wrapped python method used by tensor to determine desired learning rate'''

        # Change the learning rate at 2nd, 4th & 6th iteration
        for x in [2,4,6]:
            temp = tf.Variable(x, dtype=iteration.dtype)
            if tf.equal(temp, iteration):
                return tf.constant(0.01*x)

        # Temporary code to stop run after 10 iterations
        temp = tf.Variable(10, dtype=iteration.dtype)
        if tf.equal(temp, iteration):
            sys.exit()
        return lr

    # Key lines to change self.lr
    new_lr = tf.contrib.eager.py_func(func=lr_stepper, inp=[self.iterations, self.lr], Tout=tf.float32)
    # NOTE: K.update_add and K.update return tf.assign_add and tf.assign, respectively
    self.updates = [K.update_add(self.iterations, 1), K.update(self.lr, new_lr)]

    # Temporary code to debug output
    self.iterations = tf.Print(self.lr,
             [self.iterations, self.lr],
             message="\n Debug Vals:")

   ---------------  My Changes Stop ----------------------------------

    grads = self.get_gradients(loss, params)

    # momentum
    shapes = [K.int_shape(p) for p in params]
    moments = [K.zeros(shape) for shape in shapes]
    self.weights = [self.iterations] + moments
    etc...

我的更改是为了在第2、4和6次迭代时调整学习速率,打印出一些调试信息,然后在10次迭代后停止。来自tf.Print的输出将是消息“Debug Vals:”,后跟用方括号括起来的self.iterations的当前值,然后self.lr的值(即学习速率)也用方括号括起来

当我使用这段代码作为cifar10\u cnn.py的优化器时,从Keras的示例中,我得到以下调试输出:

 Debug Vals:[1][0.01]

 Debug Vals:[2][0.01]

 Debug Vals:[3][0.02]

 Debug Vals:[4][0.02]

 Debug Vals:[5][0.04]

 Debug Vals:[6][0.04]

 Debug Vals:[7][0.06]

 Debug Vals:[8][0.06]

 Debug Vals:[9][0.06]

注意:学习率在第3、5和7次迭代中发生了变化,尽管我预计这些变化会发生在第2、4和6次迭代中。这(我相信)是因为self.lr调整后self.iteration增加了

但是,当我第一次进行更改时,我使用的"# Key lines to change self.lr"是:

self.lr = tf.contrib.eager.py_func(func=lr_stepper,   inp=[self.iterations, self.lr], Tout=tf.float32)
self.updates = [K.update_add(self.iterations, 1)]

当我这样做时,我看到了以下输出:

 Debug Vals:[1][0.01]

 Debug Vals:[2][0.02]

 Debug Vals:[3][0.01]

 Debug Vals:[4][0.04]

 Debug Vals:[5][0.01]

 Debug Vals:[6][0.06]

 Debug Vals:[7][0.01]

 Debug Vals:[8][0.01]

 Debug Vals:[9][0.01]

在这里,我可以看到学习率在第二、第四和第六次迭代中发生了变化(现在看来很奇怪),但是这些变化的值在随后的迭代中被遗忘了

这两种情况的区别是在一种情况下使用K.updates来改变lr的值,而不是在另一种情况下。当Keras使用tensorflow后端时,K.updates,执行tf.assign

什么是tf.assign(old_tensor_variable, new_value)旧的张量=新的张量没有


Tags: todebugselfaddgettfupdatetemp