scipy 如何从spicle.optimize.minimize的所有迭代中返回参数

eulz3vhy  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(73)

我使用scipy.optimize.fmin来优化Rosenbrock函数:

import scipy
import bumpy as np
def rosen(x):
    """The Rosenbrock function"""
    return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)

x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
scipy.optimize.fmin(rosen, x0, full_output=True)

字符串
这将返回一个解的元组(最小化函数的参数、函数最小值、迭代次数、函数调用次数)。
但是,我希望能够在每一步的值图。例如,我将绘制迭代次数沿沿着的x轴和运行最小值沿沿着的y轴。

vxbzzdmp

vxbzzdmp1#

fmin可以接受一个可选的回调函数,它在每一步都被调用,所以你可以创建一个简单的函数来获取每一步的值:

def save_step(k):
    global steps
    steps.append(k)

steps = []
scipy.optimize.fmin(rosen, x0, full_output=True, callback=save_step)
print np.array(steps)[:10]

字符串
输出量:

[[ 1.339       0.721       0.824       1.71        1.236     ]
 [ 1.339       0.721       0.824       1.71        1.236     ]
 [ 1.339       0.721       0.824       1.71        1.236     ]
 [ 1.339       0.721       0.824       1.71        1.236     ]
 [ 1.2877696   0.7417984   0.8013696   1.587184    1.3580544 ]
 [ 1.28043136  0.76687744  0.88219136  1.3994944   1.29688704]
 [ 1.28043136  0.76687744  0.88219136  1.3994944   1.29688704]
 [ 1.28043136  0.76687744  0.88219136  1.3994944   1.29688704]
 [ 1.35935594  0.83266045  0.8240753   1.02414244  1.38852256]
 [ 1.30094767  0.80530982  0.85898166  1.0331386   1.45104273]]

svgewumm

svgewumm2#

谢谢Randy的回答。
因为一些优化方法在调用回调函数时会发出更多的参数(例如:'trust-blog'),我发现这个解决方案更有效:

import numpy

steps = []

def save_step(*args):
    for arg in args:
        if type(arg) is numpy.ndarray:
            steps.append(arg)

字符串
使用的例子是:

def f(x):
    x1 = x[0]
    x2 = x[1]
    return -(-4 * x1 * x1 - 4 * x2 * x2 + 4 * x1 * x2 + 8 * x1 + 20 * x2)

def gradient(x):
    x1 = x[0]
    x2 = x[1]
    return np.array([
        -(-8 * x1 + 4 * x2 + 8),
        -(-8 * x2 + 4 * x1 + 20)
    ])

start_point = np.zeros(2)

result = minimize(
    fun=f,
    x0=start_point,
    method='trust-constr',
    jac=gradient,
    callback=save_step
)
print(result)
print(steps)

相关问题