首页 > 解决方案 > 不可散列类型的错误:'numpy.ndarray'

问题描述

我正在做一个优化问题来找到最小值。过程并不重要,我的代码背后的逻辑是正确的(由我的主管验证)。但是,尽管代码在其他环境中有效,但在我的环境中无效。它总是显示不可散列的 numpy 数组错误。

这是我的代码。如果有人可以帮助我,我将不胜感激。

import math
import random
import sympy as sp
import numpy as np
from sympy.vector import *

x1,x2=sp.symbols('x1 x2')
f1=x1*x1+x2*x2
df1x1=sp.diff(f1,x1)
df1x2=sp.diff(f1,x2)

gradf1 = [df1x1,df1x2]

def f(x):
    return f1.evalf(subs={x1:x[0],x2:x[1]})

def gradf(x):
    return [df1x1.evalf(subs={x1:x[0],x2:x[1]}),df1x2.evalf(subs={x1:x[0],x2:x[1]})]

p=[[],[]]
def Momentum(f,gradf,x0,alphi,beta):
    x=x0
    v=np.array([0,0])
    while True:
        g=np.array(gradf(x))
        v=beta*v-alphi*g
        xx=(np.array(x)+v).tolist()
        print(xx,f(xx))
        if f(xx)>f(x):
            break
        x=xx
        p[0].append(float(x[0]))
        p[1].append(float(x[1]))
    return x

X1 = np.arange(-1.5, 3.5 + 0.05, 0.05)
X2 = np.arange(-1.0, 4.0 + 0.05, 0.05)
[x1, x2] = np.meshgrid(X1, X2)
ff =x1**2/5+x2**2
plt.contour(x1, x2, ff, 20) # contour plot
x0=[2,1]
p[0].append(x0[0])
p[1].append(x0[1])

xmin=Momentum(f,gradf,[0,1],1,1)
print('xmin:',xmin,',fmin:',f(xmin))

plt.plot(p[0],p[1], 'g*-') # traces for convergence
plt.show()

标签: pythonnumpysympymathematical-optimization

解决方案


回溯的完整错误:

In [5]: xmin=Momentum(f,gradf,[0,1],1,1)
Traceback (most recent call last):
  File "<ipython-input-5-7180eedc63ce>", line 1, in <module>
    xmin=Momentum(f,gradf,[0,1],1,1)
  File "<ipython-input-1-e190aed0f5ac>", line 25, in Momentum
    g=np.array(gradf(x))
  File "<ipython-input-1-e190aed0f5ac>", line 18, in gradf
    return [df1x1.evalf(subs={x1:x[0],x2:x[1]}),df1x2.evalf(subs={x1:x[0],x2:x[1]})]
TypeError: unhashable type: 'numpy.ndarray'

更改数组名称

 [xx1, xx2] = np.meshgrid(X1, X2)

允许Momentum运行,尽管运行速度非常慢(即使没有print)。我没有研究过这段代码,但是sympy反复运行表达式,效率很低。为了获得更好的数字结果,请使用sympy.lambdify来创建一个可以完全处理数字的 numpy 函数。

没有数组重定义的干扰,grad运行:

In [19]: timeit gradf([0,1])
129 µs ± 1.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

推荐阅读