Gekko:无法在合理的时间内(在线,远程=True)获得解(离线,Solver= 1,2,3) &



下面的简单优化模型(支持向量机,参见https://www.supplychaindataanalytics.com/creating-a-support-vector-machine-using-gekko-in-python/了解更多信息)是T=86和U=6的NLP(为这个最小工作示例生成的数据集)。

import numpy as np
import gekko as op
import itertools as it
a = np.random.rand(86, 6)
b = np.random.randint(0,6, size=(86))
C = range(len(set(b))) #Set of classes
U = range(len(a[0]))  #Set of input features
T = range(len(b)) #Set of the training points
def model (C,U,T,a,b,solve="y"):
save_b = tuple(b)
alpha_c=[None for j in C]
z_c=[None for j in C]
for j in C:
for t in T:
if b[t] == j:
b[t] = +1
else:
b[t] = -1
print(b)
m = op.GEKKO(remote=False, name='SupportVectorMachine') 
alpha = {t: m.Var(lb=0, ub=None) for t in T}
n_a = {(t,i): a[t][i] for t,i in it.product(T,U)}
n_b = {t: b[t] for t in T}  
objs = {0: m.sum([alpha[t] for t in T]) - 0.5*m.sum([alpha[t]*alpha[tt] * n_b[t]*n_b[tt] * m.sum([n_a[(t,i)]*n_a[(tt,i)] for i in U]) for t,tt in it.product(T,T)])}
cons = {0: {0: ( m.sum([alpha[t]*n_b[t] for t in T]) == 0) for t in T}}
m.Maximize(objs[0])
for keys1 in cons:
for keys2 in cons[keys1]: m.Equation(cons[keys1][keys2])   
if solve == "y":
m.options.SOLVER=1
m.solve(disp=False)
for keys in alpha: 
alpha[keys] =  alpha[keys].value[0]
print(f"alpha[{keys}]", alpha[keys])
x = [None for i in U]
for i in U:
x[i]=sum(alpha[t]*b[t]*n_a[(t,i)] for t in T)
for t in T:
if alpha[t]>0: 
z=b[t] - sum(x[i]*n_a[(t,i)] for i in U)
break
b = list(save_b)
alpha_c[j]=alpha
z_c[j]=z
return m,z,alpha
m, z, alpha = model(C,U,T,a,b) #Model and solve the problem

对于m.options.SOLVER=1,代码退出:

FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\USERNAME\AppData\Local\Temp\tmpj66p0g5qsupportvectormachine\options.json'

对于m.options.SOLVER=2,代码以:

退出。FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\USERNAME\AppData\Local\Temp\tmpgat29b25supportvectormachine\options.json'

对于m.options.SOLVER=3,代码退出:

FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\USERNAME\AppData\Local\Temp\tmpgat29b25supportvectormachine\options.json'

对于m = op.GEKKO(remote=True, name='SupportVectorMachine'),代码似乎需要太多的时间来运行,并且没有报告输出。

我想知道为什么会发生这种情况,以及我如何解决代码问题?我们是否需要每次都向求解器算法提供初始猜测?(我使用gekko (1.21.5)。)提前谢谢。

ٍ编辑:在谷歌的协作实验室中,它以:

退出Exception: @error: Solution Not Found

尝试IMODE=2(回归模式),其中模型仅定义一次并自动应用于每个数据点。这极大地提高了模型编译的速度。下面是IMODE=2的一个最小示例。对于相同的示例和一个非线性回归示例,也有与Scipy最小化的比较。

import numpy as np
from gekko import GEKKO
# load data
xm = np.array([18.3447,79.86538,85.09788,10.5211,44.4556, 
69.567,8.960,86.197,66.857,16.875, 
52.2697,93.917,24.35,5.118,25.126, 
34.037,61.4445,42.704,39.531,29.988])
ym = np.array([5.072,7.1588,7.263,4.255,6.282, 
6.9118,4.044,7.2595,6.898,4.8744, 
6.5179,7.3434,5.4316,3.38,5.464, 
5.90,6.80,6.193,6.070,5.737])
# define model
m = GEKKO()
# one value across all data
a,b,c = m.Array(m.FV,3,value=0)
c.LOWER = -100; c.UPPER = 100
# load data
x = m.Param(value=xm)
ymeas = m.Param(value=ym)
# predicted value
ypred = m.Var()
a.STATUS = 1; b.STATUS = 1; c.STATUS = 1
m.Equation(ypred == a + b/x + c*m.log(x))
m.Minimize(((ypred-ymeas)/ymeas)**2)
m.options.IMODE = 2   # regression mode
m.solve() # remote=False for local solve
print('Final SSE Objective: ' + str(m.options.objfcnval))

代码中还有一些东西可以提高性能。

  1. 目标函数中的m.sum([n_a[(t,i)]*n_a[(tt,i)] for i in U])可以用正则求和代替sum([n_a[(t,i)]*n_a[(tt,i)] for i in U])。当所有参数都是浮点数时,这允许计算值而不是求和的Gekko符号形式。

  2. cons可以定义一次(维度T)而不是重复相同的约束(维度T*T)吗?

cons = {0: m.sum([alpha[t]*n_b[t] for t in T]) == 0}
m.Maximize(objs[0])
for keys1 in cons:
m.Equation(cons[keys1])

感谢张贴SVM代码。如果能将其转化为IMODE=2,则可以大大提高求解效率。如果不可能(保持IMODE=3默认),那么希望上面的建议有所帮助。

我们正在Gekko中开发一个新的模块来导入sklearn(sklearn示例)、tensorflowgpflow和其他模型到Gekko中。潜在的方法是使用那些特别制作的回归包,并将模型导出到更通用的优化gekko包。我们发现,当只需要一阶导数时,一般的基于梯度的求解器可能会在拟合中做太多的工作,因为它提供了稀疏一阶和二阶导数的约束和目标的自动微分。为每种回归方法专门设计的优化器可能更有效,特别是在gpu上训练的大型数据集。更多的文档和结果预计将在2022年9月左右的下一个Gekkov1.1+版本中发布。

最新更新