keras 优化算法过程中参数打印

想在 keras Adadelta 优化算法代码处增加一些 print 信息 打印出过程中参数的变化情况
但 print new_p 的时候提示如下错误, 应该怎么打印出 new_p 呢?

第一个 print 可以正常打印出结果 第二个 print 不行。


Myy,2018-5-8 21:09:59

new_p 是 tensor 而不是 variable,keras.backend.get_value 主要针对的是 variable。对于计算图而言,终端输出可以优先考虑使用特定的 print 函数,对于 tensorflow 来说是 tf.Print,对于 keras 来说是 keras.backend.print_tensor。按照你的做法使用 print (K.get_value (p)) 得到的是计算图计算前的变量值,也就是构建模型时初始化的值,应该不会得到你所说的 “过程中参数的变化情况”。就你想要写的代码而言,你可以使用下面的方法,在每一次训练时得到当次训练的参数(p)和下次训练的参数(即优化后的 new_p):

class Adadelta (Optimizer):
    """Adadelta optimizer.
    ...
    """

    ...

    def get_updates (self, loss, params):
        ...

        for p, g, a, d_a in zip (params, grads, accumulators, delta_accumulators):
            old_p = K.print_tensor (p, message='{}: '.format (p.name))
            self.updates.append (K.update (p, old_p))

            # update accumulator
            ...

            # Apply constraints.
            if getattr (p, 'constraint', None) is not None:
                new_p = p.constraint (new_p)

            new_p = K.print_tensor (new_p, message='{}: '.format (new_p.name))
            self.updates.append (K.update (p, new_p))

            # update delta_accumulator
            new_d_a = self.rho * d_a + (1 - self.rho) * K.square (update)
            self.updates.append (K.update (d_a, new_d_a))
        return self.updates

多说一句,我不是很确定你想要做什么,但我的这个做法仅供参考。这种做法(尤其是增加对 p 的自我赋值)虽然对于模型本身应该并没有影响,但并不好;当然,我的代码逻辑也不是很强,可能还有更优美的做法,希望高人出手指教。就我的这个做法而言,把 print 加入优化器中会导致每一步都输出模型中所有的可训练变量一次,特别是当你需要训练上千上万次时,输出量极大,可读性不高。取决于你的目的,感觉可以考虑其他做法。


yunhai_luo,2018-5-9 06:32:24

非常感谢您的回答,目前答案已经满足我的需求。
我这边这样做的原因是:
我自己实现了 Adadelta 算法,在和 keras 结果对比时发现有一定差距,因此我想打印出 keras Adadelta 函数每一步的计算结果和我自己的结果对比下看看问题出在哪里,打印的信息包括 p, g, a,d_a 以及他们更新后的数值。我现在控制训练数据只有一条,所以打印出来的结果可以一一对比。


Myy(提问者),2018-5-9 11:13

谢谢你的解释!明白了,如果是这样那恐怕改 keras 源代码还比较方便,其他方法确实很难涵盖你想要看的所有参变量。


yunhai_luo,2018-5-9 12:27

keras 只测试的话,用 keras.backend.print_tensor,需要避免太多的打印


neverchange,发表于 2018-7-4 15:55:54