我是python的新手,所以有可能我做了一些非常简单的错误而不知道它。我使用scipy的optimize.fmin来优化两点之间的转换矩阵。我写了一个目标函数来乘以我的“猜测”转换矩阵和初始点,然后找到结果矩阵的每个元素和我的第二个点之间的差异。我一直得到错误:“matmul:输入操作数1的核心维度0不匹配,当我调用optimize. fmin时,gufunc signature(n?,k),(k,m?)->(n?,m?)(大小4不同于16)”。
当optimize.fmin被调用时,我的猜测矩阵似乎从4x 4变成了1x 16。
我添加了print语句来打印我的猜测和初始点矩阵的大小,这使得它们都是4x 4。然后我调用我的目标函数,它执行得很好。但是当我调用optimize. fmin时,我仍然得到错误。我在下面包含了我的代码。我的猜测转换矩阵目前是实际的转换矩阵,以保持简单。
import numpy as np
from scipy import optimize
import math
rows,cols = 4,4 #number of rows and columns in the matrices
model = np.array([
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
])
#4x4 identity matix, guess and inputArray are multiplied to create the model of goalArray
guess = np.array([
[1, -1, 2, 0],
[0, 2, 0, 0],
[1, 0, 0, 1],
[0, 1, 2, 0]
])
#4x4 identity matrix, changed by optimize.fmin to find the transformation matrix that gives goalArray when multiplied with inputArray
inputArray = np.array([
[2, 4, 6, 9],
[2, 3, 1, 0],
[7, 2, 6, 4],
[1, 5, 2, 1]
])
#4x4 matrix provided by generatePoints([2 9 2 pi -pi pi], 4) xyz_in
goalArray = np.array([
[14, 5, 17, 17],
[4, 6, 2, 0],
[3, 9, 8, 10],
[16, 7, 13, 8]
])
#4x4 matrix provided by generatePoints([2 9 2 pi -pi pi], 4) xyz_out + eye(4) for noise
#objective function passed to optimize.fmin
#multiplies inputArray by the guess transition matrix
#then finds the difference between each value in the goalArray and the model
#and adds them to find the error
def objfunc(guess, inputArray, goalArray):
sum = 0
model = guess @ inputArray
for i in range(rows):
for j in range(cols):
sum = sum + math.sqrt((goalArray[i][j] - model[i][j]) ** 2)
return sum
print(guess.shape) #prints (4,4)
print(inputArray.shape) #prints (4,4)
print(objfunc(guess, inputArray, goalArray)) #prints 0.0
minimum = optimize.fmin(objfunc, guess, args=(inputArray, goalArray)) #minimize error to find the guess transition matrix between inputArray and goalArray
#print("minimum value:", minimum[0])
#print("error:", minimum[1])
#print(guess)
字符串
1条答案
按热度按时间abithluo1#
调用optimize.fmin时,我的猜测矩阵似乎从4x4变为1x16。
是的
简短的回答是,
scipy.optimize.fmin
在调用objfun
之前,先对输入数组guess
进行重构(转换为1D)。要使代码正常工作,您至少需要在objfunc
的开头将guess整形为(4, 4)
。字符串
以及在提取结果之后。
还有其他几件事你应该做。例如,你不需要在目标函数中使用
for
循环。也就是说,型
可以替换为
型
因为算术运算是按元素对NumPy数组执行的。
但这很容易看出,你是在对每一项求平方,然后立即求平方根。如果你想求绝对值,请使用
abs
。型
如果要在求和后求平方根:
型
无论哪种方式,如果使用
numpy.linalg.norm
,其意图都将更加明确:型
另外,
optimize.fmin
是一个遗留函数。对于新代码,请使用optimize.minimize
。(请注意,minimize
的文档明确要求您的猜测必须是1D,并且传递到目标函数的参数x
将是1D。)型
这样,如果默认的优化方法不能给予足够好的结果,您就可以轻松地使用其他优化方法。
型
如果你使用绝对值的和,大多数可能不会给予你很好的结果,因为目标函数不会是光滑的。从技术上讲,
method='Nelder-Mead'
(本质上是fmin
所做的)是唯一一个不依赖于梯度的函数,但这仍然不能保证它能很好地解决你的问题。但我假设你想对一个真实的非线性问题进行非线性优化,如果
inputArray
是非奇异的,这个问题可以用线性代数来解决。型