我正在编写这个程序,我必须在其中进行大量优化。有些只有 1 个变量,有些只有 2 个。起初我使用 scipy.optimize 库中的盆地跳跃算法,但我认为正常的最小化算法应该可以完成这项工作。跳盆优化或多或少是有效的,但它非常耗时。现在,我正在使用正常的最小化优化,并且我已经想出了如何针对 1 个变量进行优化。代码如下。我在这里使用 COBYLA 方法,因为这似乎是唯一有效的方法。(Nelder-Mead 和 Powell 也可以,但有时他们会返回一个负数 x,这是我无法拥有的。而且由于这两种方法都是不受约束的,所以我不能使用它们)。因此我的第一个问题:
x0 = [50]
func = lambda x: calculate_score(Sector(center, x, rot), im, msk)
ret = op.minimize(func, x0, method='COBYLA')
print(ret)
我用于优化 2 个变量的代码与 1 个变量的代码完全相同,但不知何故它给了我错误的结果。这与我使用的方法有关吗?或者这里可能是什么问题?
x0 = [50, 50]
func = lambda x: calculate_score(Triangle(center, x[0], x[1], rot), im, msk)
ret = op.minimize(func, x0, method='COBYLA')
print(ret.x[0], ret.x[1])
为了完整起见,下面是我的 calculate_score 函数代码。我可能正在考虑计算这个函数的梯度,以便给定这个梯度,BFGS 或 L-BFGS-B 方法可以工作,但我不太确定如何做到这一点。
def calculate_score(sect, im, msk):
# find the circle in the image
center, radius = find_circle(im)
# variable to count the score
score = 0
# Loop over all pixels of the detected circle
# This is more time efficient than looping over all pixels
for i in range(0 - radius, radius):
for j in range(0 - radius, radius):
pixel = Point(center.x + i, center.y + j)
# Check if pixel is in given sector
if sect.in_sector(pixel):
# Check if pixel is white
if msk[pixel.y, pixel.x]:
score -= 1 # Decrement score
else:
score += 1 # Increment score
print(score)
return score # Return score as result
简而言之,我想知道的是:
- 从盆地跳跃切换到最小化是个好主意吗?(我只是觉得盆地跳跃非常慢)
- 对于这种特定情况,我使用的 COBYLA 方法是最好的吗?
- 为什么我的 1 个变量的结果是正确的,而我的 2 个变量的结果却不是?