Scipy 回调只调用一次
Scipy callback is called only once
我正在使用 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()
(添加到我上面的评论中)
根据 docs:
step_callback: A function to be called at each optimization step; arguments are the current values of all optimization variables flattened into a single vector.
loss_callback: A function to be called every time the loss and gradients are computed, with evaluated fetches supplied as positional arguments.
你必须传递一个函数。
一个简单的例子来说明你的问题,你没有传递一个函数;但是函数的评估 如下。
请记住,我只会展示一些纯粹的 scipy-example 而不是 -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
。您会看到 每个调用恰好一次(实际开始优化之前的单次评估!)。
我正在使用 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()
(添加到我上面的评论中)
根据 docs:
step_callback: A function to be called at each optimization step; arguments are the current values of all optimization variables flattened into a single vector.
loss_callback: A function to be called every time the loss and gradients are computed, with evaluated fetches supplied as positional arguments.
你必须传递一个函数。
一个简单的例子来说明你的问题,你没有传递一个函数;但是函数的评估 如下。
请记住,我只会展示一些纯粹的 scipy-example 而不是 -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
。您会看到 每个调用恰好一次(实际开始优化之前的单次评估!)。