0

我正在 scipy 中寻找一种优化方法,该方法允许我最小化对象函数 f(x,y)(返回向量),受约束 g(x,y) < 0.1 和 x 和 y 的附加界限。

我试图用 scipy.optimize.least_squares、scipy.optimize.leastsq 和 scipy.optimize.minimize 来解决我的问题。问题是 minimumsq 和 least_squares 允许对象函数是非标量的,但不给我实现约束(仅限边界)的可能性。另一方面,minimize 给了我实现约束和边界的可能性,但是 f(x,y) 必须返回一个标量。因此,我正在寻找一种将两者结合起来的解决方案。有谁知道这样的事情是否存在?

我要最小化的功能是

def my_cost(p,f_noise):
    x,y = p[0], p[1]
    f = #some function that returns a 3x1 array
    return (f - fnoise)**2

我用 minimum_squares 方法做到了这一点。

opti.least_squares(my_cost, p0[:], args = (f_noise,),gtol=1e-2, bounds=bounds)

但是在这里我有一个问题,我无法限制 p 中的变量。我需要约束 p 以使其满足

def constraint(p)
    x = p[0]
    return fy(x) - y <= 0.1 #variable y therefore becomes a function of variable x

为了实现约束,我测试了 scipy 的最小化函数

opti.minimize(my_cost, p0[:], args = (f_noise,), bounds = bounds, constraints={'type': 'eq', 'fun': constraint})

但在这里我似乎无法找到一种方法让 my_cost 和 f_noise 成为 3x1 数组。

对于任何帮助,我都非常感谢!为你的时间干杯!

4

1 回答 1

1

根据文档,目标函数在使用时必须返回浮点数scipy.optimize.minimize,而在使用时scipy.optimize.least_squares,您不能使用约束。在这种情况下,您必须了解您的最小化目的。最小化差异向量(如f-f_noise)等效于最小化元素差异,从而最小化它们的总和。f(x,y)因此,一个实际的解决方案是最小化你的和的定义的 p 范数g(x)。我建议使用平方L2 范数,因为它与您在成本函数中尝试的非常相似,而且它简单且稳定(与其他范数相比)。

在此处输入图像描述

您可以平均标准并获得均方误差 (MSE)

在此处输入图像描述

通过应用前面的概念,您将获得以下代码:

import numpy as np 
from scipy.optimize import minimize

# define fy
def fy(x):
    return x**2 * np.array([[.1],[.2],[.3]])  # some function that returns a 3x1 array

# objective func
def f(p, f_noise):
    x, y = p[0], p[1]
    f    = x * y * np.array([[1],[2],[3]])    # some function that returns a 3x1 array
    return np.linalg.norm(f - f_noise, 2)**2

# constraint
def g(p):
    x         = p[0]
    diff_norm = np.linalg.norm(fy(x) - y) 
    return threshold - diff_norm 

# init 
f_noise   = np.array([[.1],[.2],[.3]])
p0        = np.array([1, 0.5])
bounds    = ((0,2),(0,2))
y         = np.array([[.9],[.7],[.2]])
threshold = 0.1  # make sure to choose an adequate threshold

# minimize
result  =  minimize(f, p0,
                    args        = (f_noise,), 
                    bounds      = bounds, 
                    constraints = {'type': 'ineq', 'fun': g})

# print result
print(result)
于 2019-06-13T21:59:07.510 回答