【问题标题】:Scipy callback is called only onceScipy 回调只被调用一次
【发布时间】:2018-06-02 13:49:30
【问题描述】:

我正在使用 tf scipy interface,在我在 tensorflow 中定义的自定义函数上使用 scipy minimize。我需要调试它,我想使用回调函数来打印一些信息。 然而,回调函数只被调用一次,尽管迭代/函数评估/梯度评估的次数不止一次。为什么?我只使用 scipy(没有 tensorflow)遇到了同样的问题。

这是一个带有 Rosenbrock 函数的 MWE(应该说最小化器进行 23 次迭代、53 次函数评估、23 次梯度评估,但 CALLBACK! 只打印两次,一次用于 step_callback,一次用于 loss_callback )。

import tensorflow as tf
import numpy as np

class Solver:
    def __init__(self, session, y, x):
        self.session = session
        self.y = y
        self.x = x
        self.optimizer = tf.contrib.opt.ScipyOptimizerInterface(self.y,
                                              options={'maxiter': 100, 'disp': True},
                                              method='SLSQP',
                                              var_list=[self.x],
                                              var_to_bounds={self.x: (1e-8, np.infty)})

    def optimize(self):
      self.optimizer.minimize(self.session, step_callback=self.callback(), loss_callback=self.callback())

    def callback(self):
        print('CALLBACK!')


def main():
    seed = 0
    np.random.seed(seed)
    tf.set_random_seed(seed)
    session = tf.Session()

    x_size = 10
    x = tf.Variable(np.random.rand(x_size), dtype=tf.float32)
    y = 0.
    for i in range(x_size-1):
        y += 100. * (x[i+1] - x[i]*x[i])**2 + (x[i] - 1)**2

    solver = Solver(session, y, x)

    session.run(tf.global_variables_initializer())

    solver.optimize()


if __name__ == '__main__':
    main()

【问题讨论】:

  • 您没有传递函数(根据文档在 scipy 和此包装器中都预期)。您正在传递对函数的评估。我从未使用过 tf 或这个包装器,所以没有代码。删除 () 以传递函数。例如。 step_callback=self.callback.
  • 天啊,真是个愚蠢的错误。谢谢! (我对 python 和 tf 很陌生)。如果你把它写成答案,我很乐意接受。

标签: python tensorflow callback scipy minimize


【解决方案1】:

(添加到我上面的评论)

根据docs

step_callback:在每个优化步骤调用的函数;参数是将所有优化变量的当前值展平为单个向量。

loss_callback:每次计算损失和梯度时调用的函数,评估的提取作为位置参数提供。

你必须传递一个函数。

一个简单的例子显示了你的问题,你没有传递一个函数;但是对函数的评估如下。

请记住,我只会展示一些纯 scipy 示例,而不是 -argument self,而是传递一个向量(这是回调中的常见情况)。它看起来不同,但它转移到你的情况下!

代码:

import numpy as np
from scipy.optimize import minimize, rosen

def callback(xs):
    print('callback')

x0 = np.zeros(5)

print('Wrong passing')
res = minimize(rosen, np.zeros(5), callback=callback(x0))  # need some arg x0 to make it run
                                                           # in your case this is "self"
print('Correct passing')
res = minimize(rosen, np.zeros(5), callback=callback)

输出:

Wrong passing
callback
alpha1:  1.0
Correct passing
callback
callback
callback
callback
...
...
alpha1:  1.0

在您的情况下,您还可以再做一个调试实验来显示问题。引入两种不同的回调,一种用于step_callback,一种用于loss_callback。您会看到每个都只调用一次(在实际开始优化之前进行一次评估!)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2021-01-04
    • 2019-08-23
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多