在优化函数scipy中动态创建变量

问题描述 投票:0回答:1

下面的代码用于找到用三个矩阵a,b,c逼近张量展开的最小误差。使用变量a,b,c进行优化。

我是优化案例的新手,所以请帮助我理解这一点。我的疑问是:

  1. 在f里面,我们如何在每次迭代中使用a,b,c值。
  2. 我们如何为每次迭代使用a,b,c为khatri_rao产品创建变量。
  3. 对于每次迭代,params[0]/[1]/[2]的值不是2D数组值。甚至没有看到初始值?我的代码错误讲述了哪个元组?

任何帮助表示赞赏。谢谢

import scipy.optimize as optimize
import numpy as np
import sys
sys.path.append("../tensorly-master/")
import tensorly as tl

def f(params, t0, t1, t2):#arguments are tensor unfold
    a, b, c= params[0], params[1], params[2]#multi variables in optimization
    #norm of tensor unfold mode0 minus "a" matrix multiplied with transpose of ' khatri rao product of "c" & "b" '
    value0= t0 - np.matmul(a, tl.tenalg.khatri_rao([c, b], reverse=False).T)
    value1= t1 - np.matmul(b, tl.tenalg.khatri_rao([a, c], reverse=False).T)
    value2= t2 - np.matmul(c, tl.tenalg.khatri_rao([b, a], reverse=False).T)
    #sum of all norms
    values=np.linalg.norm(value0, "fro")+np.linalg.norm(value1, "fro")+np.linalg.norm(value2, "fro")
    #optimizing the sum of all norms be minimum
    return values

#randomly initialinzing tensor , three arrays and unfolding tensor
tn=np.random.uniform(low=0, high=100, size=(3,3,3))
a=np.random.uniform(low=0, high=100, size=(3,2))
b=np.random.uniform(low=0, high=100, size=(3,2))
c=np.random.uniform(low=0, high=100, size=(3,2))
t0=tl.unfold(tn, 0)
t1=tl.unfold(tn, 1)
t2=tl.unfold(tn, 2)
#optimization
result=optimize.minimize(f, [a, b, c], args=(t0, t1, t2))
if result.success:
    fitted_params = result.x
    print(fitted_params)
else:
    raise ValueError(result.message)

错误是:

error:-
Using numpy backend.
Traceback (most recent call last):
  File "stc.py", line 27, in <module>
    result=optimize.minimize(f, [a, b, c], args=(t0, t1, t2))
  File "/home/manish/.local/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 597, in minimize
    return _minimize_bfgs(fun, x0, args, jac, callback, **options)
  File "/home/manish/.local/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 963, in _minimize_bfgs
    gfk = myfprime(x0)
  File "/home/manish/.local/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 293, in function_wrapper
    return function(*(wrapper_args + args))
  File "/home/manish/.local/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 723, in approx_fprime
    return _approx_fprime_helper(xk, f, epsilon, args=args)
  File "/home/manish/.local/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 657, in _approx_fprime_helper
    f0 = f(*((xk,) + args))
  File "/home/manish/.local/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 293, in function_wrapper
    return function(*(wrapper_args + args))
  File "stc.py", line 10, in f
    value0= t0 - np.matmul(a, tl.tenalg.khatri_rao([c, b], reverse=False).T)
  File "../tensorly-master/tensorly/tenalg/_khatri_rao.py", line 70, in khatri_rao
    n_columns = matrices[0].shape[1]
IndexError: tuple index out of range
python scipy mathematical-optimization tensor
1个回答
0
投票

optimize通过传递一维数组(shape(n,))来调用f函数,即使给定的初始猜测不是那个形状(例如参见_minimize_bfgs)。您可以使用reshapenumpy.split从1D阵列a重建正确的2D阵列bcparams

import scipy.optimize as optimize
import numpy as np
import tensorly as tl

def f(params, t0, t1, t2): # arguments are tensor unfold
    a, b, c = np.split(x0.reshape(3, 6), 3, axis=1)  # unpack the variables

    # norm of tensor unfold mode0 minus "a" matrix 
    # multiplied with transpose of ' khatri rao product of "c" & "b" '
    value0= t0 - np.matmul(a, tl.tenalg.khatri_rao([c, b], reverse=False).T)
    value1= t1 - np.matmul(b, tl.tenalg.khatri_rao([a, c], reverse=False).T)
    value2= t2 - np.matmul(c, tl.tenalg.khatri_rao([b, a], reverse=False).T)
    #sum of all norms
    values = np.linalg.norm(value0, "fro") + \
             np.linalg.norm(value1, "fro") + \
             np.linalg.norm(value2, "fro")

    # optimizing the sum of all norms be minimum
    return values

# randomly initializing tensor, three arrays and unfolding tensor
tn = np.random.uniform(low=0, high=100, size=(3,3,3))
t0 = tl.unfold(tn, 0)
t1 = tl.unfold(tn, 1)
t2 = tl.unfold(tn, 2)

# Initial guess :
a = np.random.uniform(low=0, high=100, size=(3,2))
b = np.random.uniform(low=0, high=100, size=(3,2))
c = np.random.uniform(low=0, high=100, size=(3,2))

x0 = np.hstack([a, b, c]).ravel()

# optimization
result = optimize.minimize(f, x0, args=(t0, t1, t2))

if result.success:
    fitted_params = result.x
    print(fitted_params)
else:
    raise ValueError(result.message)
© www.soinside.com 2019 - 2024. All rights reserved.