The below code is for finding the minimum errors in approximating tensor unfold with three matrices a, b, c. Optimization is carried using variables a, b, c.
I am new to optimization case so please help me out in understanding this. My queries are:
khatri_rao
product using a, b, c for each iteration. params[0]/[1]/[2]
are not 2D array values. Not even initial values are seen? My code's error talks about which tuple?Any help is appreciated. Thank you
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)
the error is:
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
optimize
calls the f
function by passing a 1D array (shape (n,)), even if the given initial guess is not that shape (see for instance in _minimize_bfgs
). You could use reshape
and numpy.split
to reconstruct the correct 2D arrays a
, b
and c
from the 1D array params
:
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)