From fb6315d5d14a203b1a65fe3f3b983ebaee271a06 Mon Sep 17 00:00:00 2001 From: fabian-sp Date: Fri, 1 Mar 2024 14:46:28 +0100 Subject: [PATCH 01/13] move to own class --- dev/debug_sp_class.py | 33 -- example_rosenbrock.py | 5 +- ncopt/{sqpgs.py => old_sqpgs.py} | 0 ncopt/sqpgs/__init__.py | 2 + ncopt/sqpgs/defaults.py | 35 ++ ncopt/sqpgs/main.py | 559 +++++++++++++++++++ ncopt/tests/test_rosenbrock.py | 20 +- scripts/timing_rosenbrock.py | 49 ++ train_max_fun.py => scripts/train_max_fun.py | 0 9 files changed, 658 insertions(+), 45 deletions(-) delete mode 100755 dev/debug_sp_class.py rename ncopt/{sqpgs.py => old_sqpgs.py} (100%) create mode 100644 ncopt/sqpgs/__init__.py create mode 100644 ncopt/sqpgs/defaults.py create mode 100644 ncopt/sqpgs/main.py create mode 100644 scripts/timing_rosenbrock.py rename train_max_fun.py => scripts/train_max_fun.py (100%) diff --git a/dev/debug_sp_class.py b/dev/debug_sp_class.py deleted file mode 100755 index d8f4a76..0000000 --- a/dev/debug_sp_class.py +++ /dev/null @@ -1,33 +0,0 @@ -# test Subproblem class - - -#%% -# dim = 10 -# nI = 3 -# nE = 2 -# p0 = 4 -# pI = 5*np.ones(nI, dtype = int) -# pE = 2*np.ones(nE, dtype = int) - -# H = np.eye(dim) -# rho = 0.1 - -# D_f = np.random.rand(p0+1, dim) -# D_gI = [np.random.rand(pI[j]+1, dim) for j in range(nI)] -# D_gE = [np.random.rand(pE[j]+1, dim) for j in range(nE)] - -# f_k = np.random.rand(1) -# gI_k = np.random.rand(nI) -# gE_k = np.random.rand(nE) - - -# SP = Subproblem(dim, nI, nE, p0, pI, pE) -# SP.update(H, rho, D_f, D_gI, D_gE, f_k, gI_k, gE_k) - -# inG = SP.inG - - -# SP.solve() - -# d_k=SP.d - diff --git a/example_rosenbrock.py b/example_rosenbrock.py index aabcd2c..f4a5c3a 100755 --- a/example_rosenbrock.py +++ b/example_rosenbrock.py @@ -4,7 +4,7 @@ import numpy as np import matplotlib.pyplot as plt -from ncopt.sqpgs import SQP_GS +from ncopt.sqpgs import SQPGS from ncopt.funs import f_rosenbrock, g_max, g_linear #from ncopt.torch_obj import Net @@ -38,7 +38,8 @@ for i in range(20): x0 = np.random.randn(2)# np.zeros(2) - x_k, x_hist, SP = SQP_GS(f, gI, gE, x0, tol = 1e-6, max_iter = 100, verbose = False) + problem = SQPGS(f, gI, gE, x0, tol = 1e-6, max_iter = 100, verbose = False) + x_k = problem.solve() print(x_k) ax.plot(x_hist[:,0], x_hist[:,1], c = "silver", lw = 0.7, ls = '--', alpha = 0.5) ax.scatter(x_k[0], x_k[1], marker = "+", s = 50, c = "k", alpha = 1, zorder = 210) diff --git a/ncopt/sqpgs.py b/ncopt/old_sqpgs.py similarity index 100% rename from ncopt/sqpgs.py rename to ncopt/old_sqpgs.py diff --git a/ncopt/sqpgs/__init__.py b/ncopt/sqpgs/__init__.py new file mode 100644 index 0000000..194bafb --- /dev/null +++ b/ncopt/sqpgs/__init__.py @@ -0,0 +1,2 @@ +from .main import SQPGS + diff --git a/ncopt/sqpgs/defaults.py b/ncopt/sqpgs/defaults.py new file mode 100644 index 0000000..03feb05 --- /dev/null +++ b/ncopt/sqpgs/defaults.py @@ -0,0 +1,35 @@ +import copy + +class Dotdict(dict): + """dot.notation access to dictionary attributes""" + __getattr__ = dict.get + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + + +_defaults = {'tol': 1e-8, + 'max_iter': 100, + 'verbose': True, + 'assert_tol': 1e-5, + } + +_option_defaults = {'eps': 1e-1, + 'rho' : 1e-1, + 'theta' : 1e-1, + 'eta' : 1e-8, + 'gamma' : 0.5, + 'beta_eps' : 0.5, + 'beta_rho' : 0.5, + 'beta_theta' : 0.8, + 'nu' : 10, + 'xi_s' : 1e3, + 'xi_y' : 1e3, + 'xi_sy' : 1e-6, + 'iter_H': 10, + 'num_points_obj' : 2, + 'num_points_gI' : 3, + 'num_points_gE' : 4, + } + +DEFAULT_ARG = Dotdict(_defaults) +DEFAULT_OPTION = Dotdict(_option_defaults) \ No newline at end of file diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py new file mode 100644 index 0000000..3b5cf49 --- /dev/null +++ b/ncopt/sqpgs/main.py @@ -0,0 +1,559 @@ +""" +@author: Fabian Schaipp +""" + +import numpy as np +import cvxopt as cx + +import copy +from typing import Optional + +from .defaults import DEFAULT_ARG, DEFAULT_OPTION + +class SQPGS: + def __init__(self, + f, + gI, + gE, + x0: Optional[np.array]=None, + tol: float=DEFAULT_ARG.tol, + max_iter: int=DEFAULT_ARG.max_iter, + verbose: bool=DEFAULT_ARG.verbose, + options: dict={}, + assert_tol: float=DEFAULT_ARG.assert_tol + ) -> None: + + if tol < 0: + raise ValueError(f"Tolerance must be non-negative, but was specified as {tol}.") + if max_iter < 0: + raise ValueError(f"Maximum number of iterations must be non-negative, but was specified as {max_iter}.") + if assert_tol < 0: + raise ValueError(f"Assertion tolerance must be non-negative, but was specified as {assert_tol}.") + + self.f = f + self.gI = gI + self.gE = gE + self.tol = tol + self.max_iter = max_iter + self.verbose = verbose + self.options = options + self.assert_tol = assert_tol + + # Set options/hyperparameters + # (defaults are chose according to recommendations in paper) + self.options = copy.deepcopy(DEFAULT_OPTION.copy()) + self.options.update(options) + + ############################################################### + ########## Extract dimensions + + # extract dimensions of constraints + self.dim = self.f.dim + self.dimI = np.array([g.dimOut for g in self.gI], dtype=int) + self.dimE = np.array([g.dimOut for g in self.gE], dtype=int) + + + self.nI_ = len(self.gI) # number of inequality function objects + self.nE_ = len(self.gE) # number of equality function objects + + self.nI = sum(self.dimI) # number of inequality costraints + self.nE = sum(self.dimE) # number of equality costraints + + ############################################################### + ########## Initialize + + self.status = 'not optimal' + + # starting point + if x0 is None: + self.x_k = np.zeros(self.dim) + else: + self.x_k = x0.copy() + + return + + def solve(self): + ############################################################### + ########## Set all hyperparameters + + eps = self.options['eps'] # sampling radius + rho = self.options['rho'] + theta = self.options['theta'] + + eta = self.options['eta'] + gamma = self.options['gamma'] + beta_eps = self.options['beta_eps'] + beta_rho = self.options['beta_rho'] + beta_theta = self.options['beta_theta'] + nu = self.options['nu'] + xi_s = self.options['xi_s'] + xi_y = self.options['xi_y'] + xi_sy = self.options['xi_sy'] + iter_H = self.options['iter_H'] + + p0 = self.options['num_points_obj'] # sample points for objective + pI_ = self.options['num_points_gI'] * np.ones(self.nI_, dtype=int) # sample points for ineq constraint + pE_ = self.options['num_points_gE'] * np.ones(self.nE_, dtype=int) # sample points for eq constraint + + pI = np.repeat(pI_, self.dimI) + pE = np.repeat(pE_, self.dimE) + ############################################################### + + self.SP = SubproblemSQPGS(self.dim, p0, pI, pE, self.assert_tol) + + E_k = np.inf # for stopping criterion + x_hist = [self.x_k] + x_kmin1 = None # last iterate + g_kmin1 = None # + + # Hessian matrix + H = np.eye(self.dim) + s_hist = np.zeros((self.dim, iter_H)) + y_hist = np.zeros((self.dim, iter_H)) + + do_step = False + + hdr_fmt = "%4s\t%10s\t%5s\t%5s\t%10s\t%10s" + out_fmt = "%4d\t%10.4g\t%10.4g\t%10.4g\t%10.4g\t%10s" + if self.verbose: + print(hdr_fmt % ("iter", "f(x_k)", "max(g_j(x_k))", "E_k", "step", "subproblem status")) + + ############################################## + # START OF LOOP + ############################################## + for iter_k in range(self.max_iter): + + if E_k <= self.tol: + self.status = 'optimal' + break + + ############################################## + # SAMPLING + ############################################## + B_f = sample_points(self.x_k, eps, p0) + B_f = np.vstack((self.x_k, B_f)) + + B_gI = list() + for j in np.arange(self.nI_): + B_j = sample_points(self.x_k, eps, pI_[j]) + B_j = np.vstack((self.x_k, B_j)) + B_gI.append(B_j) + + B_gE = list() + for j in np.arange(self.nE_): + B_j = sample_points(self.x_k, eps, pE_[j]) + B_j = np.vstack((self.x_k, B_j)) + B_gE.append(B_j) + + + #################################### + # COMPUTE GRADIENTS AND EVALUATE + ################################### + D_f = compute_gradients(self.f, B_f)[0] # returns list, always has one element + + D_gI = list() + for j in np.arange(self.nI_): + D_gI += compute_gradients(self.gI[j], B_gI[j]) + + D_gE = list() + for j in np.arange(self.nE_): + D_gE += compute_gradients(self.gE[j], B_gE[j]) + + f_k = self.f.eval(self.x_k) + # hstack cannot handle empty lists! + if self.nI_ > 0: + gI_k = np.hstack([self.gI[j].eval(self.x_k) for j in range(self.nI_)]) + else: + gI_k = np.array([]) + + if self.nE_ > 0: + gE_k = np.hstack([self.gE[j].eval(self.x_k) for j in range(self.nE_)]) + else: + gE_k = np.array([]) + + ############################################## + # SUBPROBLEM + ############################################## + + self.SP.update(H, rho, D_f, D_gI, D_gE, f_k, gI_k, gE_k) + self.SP.solve() + + d_k = self.SP.d.copy() + # compute g_k from paper + g_k = self.SP.lambda_f @ D_f \ + + np.sum([self.SP.lambda_gI[j] @ D_gI[j] for j in range(self.nI)], axis = 0) \ + + np.sum([self.SP.lambda_gE[j] @ D_gE[j] for j in range(self.nE)], axis = 0) + + # evaluate v(x) at x=x_k + v_k = np.maximum(gI_k, 0).sum() + np.sum(np.abs(gE_k)) + phi_k = rho*f_k + v_k + delta_q = phi_k - q_rho(d_k, rho, H, f_k, gI_k, gE_k, D_f, D_gI, D_gE) + + assert delta_q >= -self.assert_tol, f"Value is supposed to be non-negative, but is {delta_q}." + assert np.abs(self.SP.lambda_f.sum() - rho) <= self.assert_tol, f"Value is supposed to be negative, but is {np.abs(self.SP.lambda_f.sum() - rho)}." + + if self.verbose: + print(out_fmt % (iter_k, f_k, np.max(np.hstack((gI_k,gE_k))), E_k, do_step, self.SP.status)) + + new_E_k = stop_criterion(self.gI, self.gE, g_k, self.SP, gI_k, gE_k, B_gI, B_gE, self.nI_, self.nE_, pI, pE) + E_k = min(E_k, new_E_k) + + ############################################## + # STEP + ############################################## + + do_step = delta_q > nu*eps**2 # Flag whether step is taken or not + if do_step: + alpha = 1. + phi_new = phi_rho(self.x_k + alpha*d_k, self.f, self.gI, self.gE, rho) + + # Armijo step size rule + while phi_new > phi_k - eta*alpha*delta_q: + alpha *= gamma + phi_new = phi_rho(self.x_k + alpha*d_k, self.f, self.gI, self.gE, rho) + + # update Hessian + if x_kmin1 is not None: + s_k = self.x_k - x_kmin1 + s_hist = np.roll(s_hist, 1, axis=1) + s_hist[:,0] = s_k + + y_k = g_k - g_kmin1 + y_hist = np.roll(y_hist, 1, axis=1) + y_hist[:,0] = y_k + + hH = np.eye(self.dim) + for l in np.arange(iter_H): + sl = s_hist[:,l] + yl = y_hist[:,l] + + cond1 = (np.linalg.norm(sl) <= xi_s*eps) and (np.linalg.norm(yl) <= xi_y*eps) + cond2 = (np.inner(sl,yl) >= xi_sy*eps**2) + cond = cond1 and cond2 + + if cond: + Hs = hH @ sl + hH = hH - np.outer(Hs,Hs)/(sl @ Hs + 1e-16) + np.outer(yl,yl)/(yl @ sl + 1e-16) + + H = hH.copy() + + #################################### + # ACTUAL STEP + ################################### + x_kmin1 = self.x_k.copy() + g_kmin1 = g_k.copy() + + self.x_k = self.x_k + alpha*d_k + + ############################################## + # NO STEP + ############################################## + else: + if v_k <= theta: + theta *= beta_theta + else: + rho *= beta_rho + + eps *= beta_eps + + + x_hist.append(self.x_k) + + ############################################## + # END OF LOOP + ############################################## + x_hist = np.vstack(x_hist) + + if E_k > self.tol: + self.status = 'max iterations reached' + + print(f"SQP-GS has terminated with status: {self.status}.") + + return self.x_k + +def sample_points(x, eps, N): + """ + sample N points uniformly distributed in eps-ball around x + """ + dim = len(x) + U = np.random.randn(N, dim) + norm_U = np.linalg.norm(U, axis=1) + R = np.random.rand(N)**(1/dim) + Z = eps * (R/norm_U)[:,np.newaxis] * U + + return x + Z + + +def q_rho(d, rho, H, f_k, gI_k, gE_k, D_f, D_gI, D_gE): + term1 = rho* (f_k + np.max(D_f @ d)) + + term2 = 0 + for j in np.arange(len(D_gI)): + term2 += np.maximum(gI_k[j] + D_gI[j] @ d, 0).max() + + term3 = 0 + for l in np.arange(len(D_gE)): + term3 += np.abs(gE_k[l] + D_gE[l] @ d).max() + + term4 = 0.5 * d.T@H@d + return term1+term2+term3+term4 + +def phi_rho(x, f, gI, gE, rho): + term1 = rho*f.eval(x) + + # inequalities + if len(gI) > 0: + term2 = np.sum(np.hstack([np.maximum(gI[j].eval(x), 0) for j in range(len(gI))])) + else: + term2 = 0 + # equalities: max(x,0) + max(-x,0) = abs(x) + if len(gE) > 0: + term3 = np.sum(np.hstack([np.abs(gE[l].eval(x)) for l in range(len(gE))])) + else: + term3 = 0 + + return term1+term2+term3 + +def stop_criterion(gI, gE, g_k, SP, gI_k, gE_k, B_gI, B_gE, nI_, nE_, pI, pE): + """ + computes E_k in the paper + """ + val1 = np.linalg.norm(g_k, np.inf) + + # as gI or gE could be empty, we need a max value for empty arrays --> initial argument + val2 = np.max(gI_k, initial=-np.inf) + val3 = np.max(np.abs(gE_k), initial=-np.inf) + + gI_vals = list() + for j in np.arange(nI_): + gI_vals += eval_ineq(gI[j], B_gI[j]) + + val4 = -np.inf + for j in np.arange(len(gI_vals)): + val4 = np.maximum(val4, np.max(SP.lambda_gI[j] * gI_vals[j])) + + gE_vals = list() + for j in np.arange(nE_): + gE_vals += eval_ineq(gE[j], B_gE[j]) + + val5 = -np.inf + for j in np.arange(len(gE_vals)): + val5 = np.maximum(val5, np.max(SP.lambda_gE[j] * gE_vals[j])) + + return np.max(np.array([val1, val2, val3, val4, val5])) + +def eval_ineq(fun, X): + """ + evaluate function at multiple inputs + needed in stop_criterion + + Returns + ------- + list of array, number of entries = fun.dimOut + """ + (N, _) = X.shape + D = np.zeros((N, fun.dimOut)) + for i in np.arange(N): + D[i,:,] = fun.eval(X[i,:]) + + return [D[:,j] for j in range(fun.dimOut)] + + +def compute_gradients(fun, X): + """ + computes gradients of function object f at all rows of array X + + Returns + ------- + list of 2d-matrices, length of fun.dimOut + """ + (N, dim) = X.shape + + # fun.grad returns Jacobian, i.e. dimOut x dim + D = np.zeros((N, fun.dimOut, dim)) + for i in np.arange(N): + D[i,:,:] = fun.grad(X[i,:]) + + return [D[:,j,:] for j in np.arange(fun.dimOut)] +#%% + +class SubproblemSQPGS: + def __init__(self, dim, p0, pI, pE, assert_tol): + """ + dim : solution space dimension + p0 : number of sample points for f (excluding x_k itself) + pI : array, number of sample points for inequality constraint (excluding x_k itself) + pE : array, number of sample points for equality constraint (excluding x_k itself) + """ + + self.dim = dim + self.nI = len(pI) + self.nE = len(pE) + self.p0 = p0 + self.pI = pI + self.pE = pE + + self.assert_tol = assert_tol + + self.P, self.q, self.inG, self.inh, self.nonnegG, self.nonnegh = self.initialize() + + + def solve(self): + """ + This solves the quadratic program. In every iteration, you should call self.update() before solving in order to have the correct subproblem data. + + self.d: array + search direction + + self.lambda_f: array + KKT multipier for objective. + + self.lambda_gE: list + KKT multipier for equality constraints. + + self.lambda_gI: list + KKT multipier for inequality constraints. + + """ + cx.solvers.options['show_progress'] = False + + iG = np.vstack((self.inG, self.nonnegG)) + ih = np.hstack((self.inh, self.nonnegh)) + + qp = cx.solvers.qp(P=cx.matrix(self.P), q=cx.matrix(self.q), G=cx.matrix(iG), h=cx.matrix(ih)) + + self.status = qp["status"] + self.cvx_sol_x = np.array(qp['x']).squeeze() + + self.d = self.cvx_sol_x[:self.dim] + self.z = self.cvx_sol_x[self.dim] + + self.rI = self.cvx_sol_x[self.dim +1 : self.dim +1 +self.nI] + self.rE = self.cvx_sol_x[self.dim +1 + self.nI : ] + + assert len(self.rE) == self.nE + assert np.all(self.rI >= -self.assert_tol) , f"Array should be non-negative, but minimal value is {np.min(self.rI)}." + assert np.all(self.rE >= -self.assert_tol), f"Array should be non-negative, but minimal value is {np.min(self.rE)}." + + # extract dual variables = KKT multipliers + self.cvx_sol_z = np.array(qp['z']).squeeze() + lambda_f = self.cvx_sol_z[:self.p0+1] + + lambda_gI = list() + for j in np.arange(self.nI): + start_ix = self.p0+1+(1+self.pI)[:j].sum() + lambda_gI.append( self.cvx_sol_z[start_ix : start_ix + 1+self.pI[j]] ) + + lambda_gE = list() + for j in np.arange(self.nE): + start_ix = self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + + # from ineq with + + vec1 = self.cvx_sol_z[start_ix : start_ix + 1+self.pE[j]] + + # from ineq with - + vec2 = self.cvx_sol_z[start_ix+(1+self.pE).sum() : start_ix + (1+self.pE).sum() + 1+self.pE[j]] + + # see Direction.m line 620 in the original Matlab code + lambda_gE.append(vec1-vec2) + + self.lambda_f = lambda_f.copy() + self.lambda_gI = lambda_gI.copy() + self.lambda_gE = lambda_gE.copy() + + return + + + def initialize(self): + """ + The quadratic subrpoblem we solve in every iteration is of the form: + + min_y 1/2* yPy + q*y subject to Gy <= h + + variable structure: y=(d,z,rI,rE) with + d = search direction + z = helper variable for objective + rI = helper variable for inequality constraints + rI = helper variable for equality constraints + + This function initializes the variables P,q,G,h. The entries which change in every iteration are then updated in self.update() + + G and h consist of two parts: + 1) inG, inh: the inequalities from the paper + 2) nonnegG, nonnegh: nonnegativity bounds rI >= 0, rE >= 0 + """ + + dimQP = self.dim+1 + self.nI + self.nE + + P = np.zeros((dimQP, dimQP)) + q = np.zeros(dimQP) + + inG = np.zeros((1 + self.p0+np.sum(1+self.pI) + 2*np.sum(1+self.pE), dimQP)) + inh = np.zeros( 1 + self.p0+np.sum(1+self.pI) + 2*np.sum(1+self.pE)) + + # structure of inG (p0+1, sum(1+pI), sum(1+pE), sum(1+pE)) + inG[:self.p0+1, self.dim] = -1 + + for j in range(self.nI): + inG[self.p0+1+(1+self.pI)[:j].sum() : self.p0+1+(1+self.pI)[:j].sum() + self.pI[j]+1, self.dim+1+j] = -1 + + for j in range(self.nE): + inG[self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, self.dim+1+self.nI+j] = -1 + inG[self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, self.dim+1+self.nI+j] = -1 + + # we have nI+nE r-variables + nonnegG = np.hstack((np.zeros((self.nI + self.nE, self.dim + 1)), -np.eye(self.nI + self.nE))) + nonnegh = np.zeros(self.nI + self.nE) + + return P,q,inG,inh,nonnegG,nonnegh + + + def update(self, H, rho, D_f, D_gI, D_gE, f_k, gI_k, gE_k): + """ + + Parameters + ---------- + H : array + Hessian approximation + rho : float + parameter + D_f : array + gradient of f at the sampled points + D_gI : list + j-th element is the gradient array of c^j at the sampled points. + D_gE : list + j-th element is the gradient array of h^j at the sampled points. + f_k : float + evaluation of f at x_k. + gI_k : array + evaluation of inequality constraints at x_k. + gE_k : array + evaluation of equality constraints at x_k. + + Returns + ------- + None. + + """ + self.P[:self.dim, :self.dim] = H + self.q = np.hstack((np.zeros(self.dim), rho, np.ones(self.nI), np.ones(self.nE))) + + self.inG[:self.p0+1, :self.dim] = D_f + self.inh[:self.p0+1] = -f_k + + for j in range(self.nI): + self.inG[self.p0+1+(1+self.pI)[:j].sum() : self.p0+1+(1+self.pI)[:j].sum() + self.pI[j]+1, :self.dim] = D_gI[j] + self.inh[self.p0+1+(1+self.pI)[:j].sum() : self.p0+1+(1+self.pI)[:j].sum() + self.pI[j]+1] = -gI_k[j] + + for j in range(self.nE): + self.inG[self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, :self.dim] = D_gE[j] + self.inG[self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, :self.dim] = -D_gE[j] + + self.inh[self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1] = -gE_k[j] + self.inh[self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1] = gE_k[j] + + + return + + + diff --git a/ncopt/tests/test_rosenbrock.py b/ncopt/tests/test_rosenbrock.py index 9018e7d..9333c4d 100755 --- a/ncopt/tests/test_rosenbrock.py +++ b/ncopt/tests/test_rosenbrock.py @@ -8,9 +8,7 @@ tests_path = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, tests_path + '/../..') -#os.chdir('../..') - -from ncopt.sqpgs import SQP_GS +from ncopt.sqpgs import SQPGS from ncopt.funs import f_rosenbrock, g_max, g_linear f = f_rosenbrock() @@ -20,8 +18,9 @@ def test_rosenbrock_from_zero(): gI = [g] gE = [] xstar = np.array([1/np.sqrt(2), 0.5]) - x_k, x_hist, SP = SQP_GS(f, gI, gE, tol = 1e-8, max_iter = 200, verbose = False) - np.testing.assert_array_almost_equal(x_k, xstar, decimal = 4) + problem = SQPGS(f, gI, gE, tol=1e-8, max_iter=200, verbose=False) + x_k = problem.solve() + np.testing.assert_array_almost_equal(x_k, xstar, decimal=4) return @@ -30,8 +29,9 @@ def test_rosenbrock_from_rand(): gE = [] xstar = np.array([1/np.sqrt(2), 0.5]) x0 = np.random.rand(2) - x_k, x_hist, SP = SQP_GS(f, gI, gE, x0, tol = 1e-8, max_iter = 200, verbose = False) - np.testing.assert_array_almost_equal(x_k, xstar, decimal = 4) + problem = SQPGS(f, gI, gE, x0=x0, tol=1e-8, max_iter=200, verbose=False) + x_k = problem.solve() + np.testing.assert_array_almost_equal(x_k, xstar, decimal=4) return @@ -40,8 +40,8 @@ def test_rosenbrock_with_eq(): gI = [] gE = [g1] xstar = np.ones(2) - x0 = np.zeros(2) - x_k, x_hist, SP = SQP_GS(f, gI, gE, x0, tol = 1e-8, max_iter = 200, verbose = False) - np.testing.assert_array_almost_equal(x_k, xstar, decimal = 4) + problem = SQPGS(f, gI, gE, tol=1e-8, max_iter=200, verbose=False) + x_k = problem.solve() + np.testing.assert_array_almost_equal(x_k, xstar, decimal=4) return \ No newline at end of file diff --git a/scripts/timing_rosenbrock.py b/scripts/timing_rosenbrock.py new file mode 100644 index 0000000..8855b36 --- /dev/null +++ b/scripts/timing_rosenbrock.py @@ -0,0 +1,49 @@ +""" +author: Fabian Schaipp +""" +import numpy as np +import sys + +sys.path.append('..') + +from ncopt.sqpgs import SQPGS +from ncopt.funs import f_rosenbrock, g_max, g_linear + +#%% +f = f_rosenbrock() +g = g_max() + +# inequality constraints (list of functions) +gI = [g] + +xstar = np.array([1/np.sqrt(2), 0.5]) + +np.random.seed(31) +x0 = np.random.randn(2) + +#%% Timing one scalar inequality constraint + +# equality constraints (list of scalar functions) +gE = [] +problem = SQPGS(f, gI, gE, x0, tol=1e-20, max_iter=100, verbose=False) + +%timeit -n 20 x_k = problem.solve() + +# result (start of refactoring): +# 168 ms ± 2.96 ms per loop (mean ± std. dev. of 7 runs, 20 loops each) + +#%% Timing equality constraint + +A = np.eye(2); b = np.zeros(2); g1 = g_linear(A, b) + +# equality constraints (list of scalar functions) +gE = [g1] +problem = SQPGS(f, gI, gE, x0, tol=1e-20, max_iter=100, verbose=False) + +np.random.seed(31) +x0 = np.random.randn(2) + +%timeit -n 10 x_k = problem.solve() + +# result (start of refactoring): +# 291 ms ± 3.53 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) \ No newline at end of file diff --git a/train_max_fun.py b/scripts/train_max_fun.py similarity index 100% rename from train_max_fun.py rename to scripts/train_max_fun.py From 0d2af1973ee048fa2ff584643ff72c58f19f2e56 Mon Sep 17 00:00:00 2001 From: fabian-sp Date: Fri, 1 Mar 2024 15:00:23 +0100 Subject: [PATCH 02/13] small edits --- README.md | 14 +- ncopt/old_sqpgs.py | 553 -------------------------------------------- ncopt/sqpgs/main.py | 7 + 3 files changed, 17 insertions(+), 557 deletions(-) delete mode 100755 ncopt/old_sqpgs.py diff --git a/README.md b/README.md index cb60bc3..4710574 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,11 @@ This repository contains a `Python` implementation of the SQP-GS (*Sequential Qu The algorithm can solve problems of the form +``` min f(x) s.t. g(x) <= 0 h(x) = 0 +``` where `f`, `g` and `h` are locally Lipschitz functions. Hence, the algorithm can solve problems with nonconvex and nonsmooth objective and constraints. For details, we refer to the original paper. @@ -25,8 +27,11 @@ To reproduce this experiment, see the file `example_rosenbrock.py`. ## Implementation details The solver can be called via - SQP_GS(f, gI, gE) - +```python + from ncopt.sqpgs import SQPGS + problem = SQPGS(f, gI, gE) + problem.solve() +``` It has three main arguments, called `f`, `gI` and `gE`. `f` is the objective. `gI` and `gE` are lists of inequality and equality constraint functions. Each element of `gI` and `gE` as well as the objective `f` needs to be an instance of a class which contains the following properties. The constraint functions are allowed to have multi-dimensional output. ### Attributes @@ -45,6 +50,7 @@ Moreover, we implemented a class for a constraint coming from a Pytorch neural n ## References -* [1] F. E. Curtis and M. L. Overton, A sequential quadratic programming algorithm for nonconvex, nonsmooth constrained optimization, SIAM Journal on Optimization, 22 (2012), pp. 474–500, https://doi.org/10.1137/090780201. +[1] Frank E. Curtis and Michael L. Overton, A sequential quadratic programming algorithm for nonconvex, nonsmooth constrained optimization, +SIAM Journal on Optimization 2012 22:2, 474-500, https://doi.org/10.1137/090780201. -* [2] F. E. Curtis, MATLAB implementation of SLQP-GS, https://coral.ise.lehigh.edu/frankecurtis/software/. +[2] Frank E. Curtis and Michael L. Overton, MATLAB implementation of SLQP-GS, https://coral.ise.lehigh.edu/frankecurtis/software/. diff --git a/ncopt/old_sqpgs.py b/ncopt/old_sqpgs.py deleted file mode 100755 index 7829022..0000000 --- a/ncopt/old_sqpgs.py +++ /dev/null @@ -1,553 +0,0 @@ -""" -author: Fabian Schaipp - -Notation is (wherever possible) inspired by Curtis, Overton "SQP FOR NONSMOOTH CONSTRAINED OPTIMIZATION" -""" - -import numpy as np -import cvxopt as cx - -def sample_points(x, eps, N): - """ - sample N points uniformly distributed in eps-ball around x - """ - dim = len(x) - U = np.random.randn(N, dim) - norm_U = np.linalg.norm(U, axis = 1) - R = np.random.rand(N)**(1/dim) - Z = eps * (R/norm_U)[:,np.newaxis] * U - - return x + Z - - -def q_rho(d, rho, H, f_k, gI_k, gE_k, D_f, D_gI, D_gE): - term1 = rho* (f_k + np.max(D_f @ d)) - - term2 = 0 - for j in np.arange(len(D_gI)): - term2 += np.maximum(gI_k[j] + D_gI[j] @ d, 0).max() - - term3 = 0 - for l in np.arange(len(D_gE)): - term3 += np.abs(gE_k[l] + D_gE[l] @ d).max() - - term4 = 0.5 * d.T@H@d - return term1+term2+term3+term4 - -def phi_rho(x, f, gI, gE, rho): - term1 = rho*f.eval(x) - - # inequalities - if len(gI) > 0: - term2 = np.sum(np.hstack([np.maximum(gI[j].eval(x), 0) for j in range(len(gI))])) - else: - term2 = 0 - # equalities: max(x,0) + max(-x,0) = abs(x) - if len(gE) > 0: - term3 = np.sum(np.hstack([np.abs(gE[l].eval(x)) for l in range(len(gE))])) - else: - term3 = 0 - - return term1+term2+term3 - -def stop_criterion(gI, gE, g_k, SP, gI_k, gE_k, B_gI, B_gE, nI_, nE_, pI, pE): - """ - computes E_k in the paper - """ - val1 = np.linalg.norm(g_k, np.inf) - - # as gI or gE could be empty, we need a max value for empty arrays --> initial argument - val2 = np.max(gI_k, initial = -np.inf) - val3 = np.max(np.abs(gE_k), initial = -np.inf) - - gI_vals = list() - for j in np.arange(nI_): - gI_vals += eval_ineq(gI[j], B_gI[j]) - - val4 = -np.inf - for j in np.arange(len(gI_vals)): - val4 = np.maximum(val4, np.max(SP.lambda_gI[j] * gI_vals[j])) - - gE_vals = list() - for j in np.arange(nE_): - gE_vals += eval_ineq(gE[j], B_gE[j]) - - val5 = -np.inf - for j in np.arange(len(gE_vals)): - val5 = np.maximum(val5, np.max(SP.lambda_gE[j] * gE_vals[j])) - - return np.max(np.array([val1, val2, val3, val4, val5])) - -def eval_ineq(fun, X): - """ - evaluate function at multiple inputs - needed in stop_criterion - - Returns - ------- - list of array, number of entries = fun.dimOut - """ - (N, _) = X.shape - D = np.zeros((N, fun.dimOut)) - for i in np.arange(N): - D[i,:,] = fun.eval(X[i,:]) - - return [D[:,j] for j in range(fun.dimOut)] - - -def compute_gradients(fun, X): - """ - computes gradients of function object f at all rows of array X - - Returns - ------- - list of 2d-matrices, length of fun.dimOut - """ - (N, dim) = X.shape - - # fun.grad returns Jacobian, i.e. dimOut x dim - D = np.zeros((N, fun.dimOut, dim)) - for i in np.arange(N): - D[i,:,:] = fun.grad(X[i,:]) - - # TODO: write this directly in return statement - D_list = list() - for j in np.arange(fun.dimOut): - D_list.append(D[:,j,:]) - - return D_list - - - -def SQP_GS(f, gI, gE, x0 = None, tol = 1e-8, max_iter = 100, verbose = True, assert_tol = 1e-5): - """ - each element of gI, gE needs attribute g.dimOut - - Parameters - ---------- - f : TYPE - DESCRIPTION. - gI : TYPE - DESCRIPTION. - gE : TYPE - DESCRIPTION. - x0: array - Starting point. The default is zero. - tol : TYPE, optional - DESCRIPTION. The default is 1e-8. - max_iter : TYPE, optional - DESCRIPTION. The default is 100. - verbose : TYPE, optional - DESCRIPTION. The default is True. - - Returns - ------- - x_k : TYPE - DESCRIPTION. - x_hist : TYPE - DESCRIPTION. - SP : TYPE - DESCRIPTION. - - """ - eps = 1e-1 # sampling radius - rho = 1e-1 - theta = 1e-1 - - # extract dimensions of constraints - dim = f.dim - dimI = np.array([g.dimOut for g in gI], dtype = int) - dimE = np.array([g.dimOut for g in gE], dtype = int) - - - nI_ = len(gI) # number of inequality function objects - nE_ = len(gE) # number of equality function objects - - nI = sum(dimI) # number of inequality costraints - nE = sum(dimE) # number of equality costraints - - p0 = 2 # sample points for objective - pI_ = 3 * np.ones(nI_, dtype = int) # sample points for ineq constraint - pE_ = 4 * np.ones(nE_, dtype = int) # sample points for eq constraint - - pI = np.repeat(pI_, dimI) - pE = np.repeat(pE_, dimE) - - # parameters (set after recommendations in paper) - # TODO: add params argument to set these - eta = 1e-8 - gamma = 0.5 - beta_eps = 0.5 - beta_rho = 0.5 - beta_theta = 0.8 - nu = 10 - xi_s = 1e3 - xi_y = 1e3 - xi_sy = 1e-6 - - # initialize subproblem object - SP = Subproblem(dim, nI, nE, p0, pI, pE) - - if x0 is None: - x_k = np.zeros(dim) - else: - x_k = x0.copy() - - iter_H = 10 - E_k = np.inf - - x_hist = [x_k] - x_kmin1 = None; g_kmin1 = None; - s_hist = np.zeros((dim, iter_H)) - y_hist = np.zeros((dim, iter_H)) - - H = np.eye(dim) - - status = 'not optimal'; step = np.nan - - hdr_fmt = "%4s\t%10s\t%5s\t%5s\t%10s\t%10s" - out_fmt = "%4d\t%10.4g\t%10.4g\t%10.4g\t%10.4g\t%10s" - if verbose: - print(hdr_fmt % ("iter", "f(x_k)", "max(g_j(x_k))", "E_k", "step", "subproblem status")) - - ############################################## - # START OF LOOP - ############################################## - - for iter_k in range(max_iter): - - if E_k <= tol: - status = 'optimal' - break - - ############################################## - # SAMPLING - ############################################## - B_f = sample_points(x_k, eps, p0) - B_f = np.vstack((x_k, B_f)) - - B_gI = list() - for j in np.arange(nI_): - B_j = sample_points(x_k, eps, pI_[j]) - B_j = np.vstack((x_k, B_j)) - B_gI.append(B_j) - - B_gE = list() - for j in np.arange(nE_): - B_j = sample_points(x_k, eps, pE_[j]) - B_j = np.vstack((x_k, B_j)) - B_gE.append(B_j) - - - #################################### - # COMPUTE GRADIENTS AND EVALUATE - ################################### - D_f = compute_gradients(f, B_f)[0] # returns list, always has one element - - D_gI = list() - for j in np.arange(nI_): - D_gI += compute_gradients(gI[j], B_gI[j]) - - D_gE = list() - for j in np.arange(nE_): - D_gE += compute_gradients(gE[j], B_gE[j]) - - f_k = f.eval(x_k) - # hstack cannot handle empty lists! - if nI_ > 0: - gI_k = np.hstack([gI[j].eval(x_k) for j in range(nI_)]) - else: - gI_k = np.array([]) - - if nE_ > 0: - gE_k = np.hstack([gE[j].eval(x_k) for j in range(nE_)]) - else: - gE_k = np.array([]) - - ############################################## - # SUBPROBLEM - ############################################## - #print("H EIGVALS", np.linalg.eigh(H)[0]) - - SP.update(H, rho, D_f, D_gI, D_gE, f_k, gI_k, gE_k) - SP.solve() - - d_k = SP.d.copy() - # compute g_k from paper - g_k = SP.lambda_f @ D_f + np.sum([SP.lambda_gI[j] @ D_gI[j] for j in range(nI)], axis = 0) \ - + np.sum([SP.lambda_gE[j] @ D_gE[j] for j in range(nE)], axis = 0) - - # evaluate v(x) at x=x_k - v_k = np.maximum(gI_k, 0).sum() + np.sum(np.abs(gE_k)) - phi_k = rho*f_k + v_k - delta_q = phi_k - q_rho(d_k, rho, H, f_k, gI_k, gE_k, D_f, D_gI, D_gE) - - assert delta_q >= -assert_tol - assert np.abs(SP.lambda_f.sum() - rho) <= assert_tol, f"{np.abs(SP.lambda_f.sum() - rho)}" - - - if verbose: - print(out_fmt % (iter_k, f_k, np.max(np.hstack((gI_k,gE_k))), E_k, step, SP.status)) - - new_E_k = stop_criterion(gI, gE, g_k, SP, gI_k, gE_k, B_gI, B_gE, nI_, nE_, pI, pE) - E_k = min(E_k, new_E_k) - - ############################################## - # STEP - ############################################## - - step = delta_q > nu*eps**2 - if step: - alpha = 1. - phi_new = phi_rho(x_k + alpha*d_k, f, gI, gE, rho) - - # Armijo step size rule - while phi_new > phi_k - eta*alpha*delta_q: - alpha *= gamma - phi_new = phi_rho(x_k + alpha*d_k, f, gI, gE, rho) - - # update Hessian - if x_kmin1 is not None: - s_k = x_k - x_kmin1 - s_hist = np.roll(s_hist, 1, axis = 1) - s_hist[:,0] = s_k - - y_k = g_k - g_kmin1 - y_hist = np.roll(y_hist, 1, axis = 1) - y_hist[:,0] = y_k - - hH = np.eye(dim) - for l in np.arange(iter_H): - sl = s_hist[:,l] - yl = y_hist[:,l] - - cond = (np.linalg.norm(sl) <= xi_s*eps) and (np.linalg.norm(yl) <= xi_y*eps) and (np.inner(sl,yl) >= xi_sy*eps**2) - - if cond: - Hs = hH@sl - hH = hH - np.outer(Hs,Hs)/(sl @ Hs + 1e-16) + np.outer(yl,yl)/(yl @ sl + 1e-16) - - # TODO: is this really necessary? - assert np.all(np.abs(hH - hH.T) <= 1e-8), f"{H}" - - H = hH.copy() - - #################################### - # ACTUAL STEP - ################################### - x_kmin1 = x_k.copy() - g_kmin1 = g_k.copy() - - x_k = x_k + alpha*d_k - - ############################################## - # NO STEP - ############################################## - else: - if v_k <= theta: - theta *= beta_theta - else: - rho *= beta_rho - - eps *= beta_eps - - - x_hist.append(x_k) - - ############################################## - # END OF LOOP - ############################################## - x_hist = np.vstack(x_hist) - - if E_k > tol: - status = 'max iterations reached' - - print(f"SQP-GS has terminated with status {status}") - - return x_k, x_hist, SP - -#%% - -class Subproblem: - def __init__(self, dim, nI, nE, p0, pI, pE): - """ - dim : solution space dimension - nI : number of inequality constraints - nE : number of equality constraints - p0 : number of sample points for f (excluding x_k itself) - pI : array, number of sample points for inequality constraint (excluding x_k itself) - pE : array, number of sample points for equality constraint (excluding x_k itself) - """ - assert len(pI) == nI - assert len(pE) == nE - - self.dim = dim - self.nI = nI - self.nE = nE - self.p0 = p0 - self.pI = pI - self.pE = pE - - self.P, self.q, self.inG, self.inh, self.nonnegG, self.nonnegh = self.initialize() - - - def solve(self): - """ - This solves the quadratic program. In every iteration, you should call self.update() before solving in order to have the correct subproblem data. - - self.d: array - search direction - - self.lambda_f: array - KKT multipier for objective. - - self.lambda_gE: list - KKT multipier for equality constraints. - - self.lambda_gI: list - KKT multipier for inequality constraints. - - """ - cx.solvers.options['show_progress'] = False - - iG = np.vstack((self.inG, self.nonnegG)) - ih = np.hstack((self.inh, self.nonnegh)) - - qp = cx.solvers.qp(P = cx.matrix(self.P), q = cx.matrix(self.q), G = cx.matrix(iG), h = cx.matrix(ih)) - - self.status = qp["status"] - self.cvx_sol_x = np.array(qp['x']).squeeze() - - self.d = self.cvx_sol_x[:self.dim] - self.z = self.cvx_sol_x[self.dim] - - self.rI = self.cvx_sol_x[self.dim +1 : self.dim +1 +self.nI] - self.rE = self.cvx_sol_x[self.dim +1 + self.nI : ] - - # TODO: pipe through assert_tol - assert len(self.rE) == self.nE - assert np.all(self.rI >= -1e-5) , f"{self.rI}" - assert np.all(self.rE >= -1e-5), f"{self.rE}" - - # extract dual variables = KKT multipliers - self.cvx_sol_z = np.array(qp['z']).squeeze() - lambda_f = self.cvx_sol_z[:self.p0+1] - - lambda_gI = list() - for j in np.arange(self.nI): - start_ix = self.p0+1+(1+self.pI)[:j].sum() - lambda_gI.append( self.cvx_sol_z[start_ix : start_ix + 1+self.pI[j]] ) - - lambda_gE = list() - for j in np.arange(self.nE): - start_ix = self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() - - # from ineq with + - vec1 = self.cvx_sol_z[start_ix : start_ix + 1+self.pE[j]] - - # from ineq with - - vec2 = self.cvx_sol_z[start_ix+(1+self.pE).sum() : start_ix + (1+self.pE).sum() + 1+self.pE[j]] - - # see Direction.m line 620 - lambda_gE.append(vec1-vec2) - - self.lambda_f = lambda_f.copy() - self.lambda_gI = lambda_gI.copy() - self.lambda_gE = lambda_gE.copy() - - return - - - def initialize(self): - """ - The quadratic subrpoblem we solve in every iteration is of the form: - - min_y 1/2* yPy + q*y subject to Gy <= h - - variable structure: y=(d,z,rI,rE) with - d = search direction - z = helper variable for objective - rI = helper variable for inequality constraints - rI = helper variable for equality constraints - - This function initializes the variables P,q,G,h. The entries which change in every iteration are then updated in self.update() - - G and h consist of two parts: - 1) inG, inh: the inequalities from the paper - 2) nonnegG, nonnegh: nonnegativity bounds rI >= 0, rE >= 0 - """ - - dimQP = self.dim+1 + self.nI + self.nE - - P = np.zeros((dimQP, dimQP)) - q = np.zeros(dimQP) - - inG = np.zeros((1 + self.p0+np.sum(1+self.pI) + 2*np.sum(1+self.pE), dimQP)) - inh = np.zeros( 1 + self.p0+np.sum(1+self.pI) + 2*np.sum(1+self.pE)) - - # structure of inG (p0+1, sum(1+pI), sum(1+pE), sum(1+pE)) - inG[:self.p0+1, self.dim] = -1 - - for j in range(self.nI): - inG[self.p0+1+(1+self.pI)[:j].sum() : self.p0+1+(1+self.pI)[:j].sum() + self.pI[j]+1, self.dim+1+j] = -1 - - for j in range(self.nE): - inG[self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, self.dim+1+self.nI+j] = -1 - inG[self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, self.dim+1+self.nI+j] = -1 - - # we have nI+nE r-variables - nonnegG = np.hstack((np.zeros((self.nI + self.nE, self.dim + 1)), -np.eye(self.nI + self.nE))) - nonnegh = np.zeros(self.nI + self.nE) - - return P,q,inG,inh,nonnegG,nonnegh - - - def update(self, H, rho, D_f, D_gI, D_gE, f_k, gI_k, gE_k): - """ - - Parameters - ---------- - H : array - Hessian approximation - rho : float - parameter - D_f : array - gradient of f at the sampled points - D_gI : list - j-th element is the gradient array of c^j at the sampled points. - D_gE : list - j-th element is the gradient array of h^j at the sampled points. - f_k : float - evaluation of f at x_k. - gI_k : array - evaluation of inequality constraints at x_k. - gE_k : array - evaluation of equality constraints at x_k. - - Returns - ------- - None. - - """ - self.P[:self.dim, :self.dim] = H - self.q = np.hstack((np.zeros(self.dim), rho, np.ones(self.nI), np.ones(self.nE))) - - self.inG[:self.p0+1, :self.dim] = D_f - self.inh[:self.p0+1] = -f_k - - for j in range(self.nI): - self.inG[self.p0+1+(1+self.pI)[:j].sum() : self.p0+1+(1+self.pI)[:j].sum() + self.pI[j]+1, :self.dim] = D_gI[j] - self.inh[self.p0+1+(1+self.pI)[:j].sum() : self.p0+1+(1+self.pI)[:j].sum() + self.pI[j]+1] = -gI_k[j] - - for j in range(self.nE): - self.inG[self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, :self.dim] = D_gE[j] - self.inG[self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1, :self.dim] = -D_gE[j] - - self.inh[self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1] = -gE_k[j] - self.inh[self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() : self.p0+1+(1+self.pI).sum()+(1+self.pE).sum()+(1+self.pE)[:j].sum() + self.pE[j]+1] = gE_k[j] - - - return - - - diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py index 3b5cf49..191327b 100644 --- a/ncopt/sqpgs/main.py +++ b/ncopt/sqpgs/main.py @@ -1,5 +1,12 @@ """ @author: Fabian Schaipp + +Implements the SQP-GS algorithm from + + Frank E. Curtis and Michael L. Overton, A sequential quadratic programming algorithm for nonconvex, nonsmooth constrained optimization, + SIAM Journal on Optimization 2012 22:2, 474-500, https://doi.org/10.1137/090780201. + +The notation of the code tries to follow closely the notation of the paper. """ import numpy as np From e066f5b72648d43b6af525e3d6a5fa29c328f3a8 Mon Sep 17 00:00:00 2001 From: fabian-sp Date: Fri, 1 Mar 2024 16:33:00 +0100 Subject: [PATCH 03/13] add timings --- example_rosenbrock.py | 2 ++ ncopt/sqpgs/main.py | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/example_rosenbrock.py b/example_rosenbrock.py index f4a5c3a..ebc8f63 100755 --- a/example_rosenbrock.py +++ b/example_rosenbrock.py @@ -41,6 +41,8 @@ problem = SQPGS(f, gI, gE, x0, tol = 1e-6, max_iter = 100, verbose = False) x_k = problem.solve() print(x_k) + + x_hist = problem.x_hist ax.plot(x_hist[:,0], x_hist[:,1], c = "silver", lw = 0.7, ls = '--', alpha = 0.5) ax.scatter(x_k[0], x_k[1], marker = "+", s = 50, c = "k", alpha = 1, zorder = 210) diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py index 191327b..9ef9cbc 100644 --- a/ncopt/sqpgs/main.py +++ b/ncopt/sqpgs/main.py @@ -13,6 +13,7 @@ import cvxopt as cx import copy +import time from typing import Optional from .defaults import DEFAULT_ARG, DEFAULT_OPTION @@ -125,11 +126,13 @@ def solve(self): if self.verbose: print(hdr_fmt % ("iter", "f(x_k)", "max(g_j(x_k))", "E_k", "step", "subproblem status")) + self.timings = {'total': [], 'sp_update': [], 'sp_solve': []} ############################################## # START OF LOOP ############################################## for iter_k in range(self.max_iter): - + + t0 = time.perf_counter() if E_k <= self.tol: self.status = 'optimal' break @@ -182,9 +185,15 @@ def solve(self): # SUBPROBLEM ############################################## + t01 = time.perf_counter() self.SP.update(H, rho, D_f, D_gI, D_gE, f_k, gI_k, gE_k) + t11 = time.perf_counter() self.SP.solve() - + t21 = time.perf_counter() + + self.timings['sp_update'].append(t11-t01) + self.timings['sp_solve'].append(t21-t11) + d_k = self.SP.d.copy() # compute g_k from paper g_k = self.SP.lambda_f @ D_f \ @@ -265,11 +274,13 @@ def solve(self): x_hist.append(self.x_k) + t1 = time.perf_counter() + self.timings['total'].append(t1-t0) ############################################## # END OF LOOP ############################################## - x_hist = np.vstack(x_hist) + self.x_hist = np.vstack(x_hist) if E_k > self.tol: self.status = 'max iterations reached' From 708241184ad9ce29112467faa78e66f77befb4c0 Mon Sep 17 00:00:00 2001 From: fabian-sp Date: Mon, 4 Mar 2024 19:30:05 +0100 Subject: [PATCH 04/13] initial script for jacobians --- scripts/compute_jacobian.py | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 scripts/compute_jacobian.py diff --git a/scripts/compute_jacobian.py b/scripts/compute_jacobian.py new file mode 100644 index 0000000..ab87dab --- /dev/null +++ b/scripts/compute_jacobian.py @@ -0,0 +1,62 @@ +import torch +from torch.autograd.functional import jacobian + +d = 10 +m = 3 +b = 4 + + +class Quadratic(torch.nn.Module): + def __init__(self, input_dim): + super().__init__() + self.A = torch.nn.Parameter(torch.randn((input_dim, input_dim))) + + def forward(self, x): + return (1/2) * x @ self.A @ x + +def compute_batch_jacobian_naive(model: torch.nn.Module, inputs: torch.Tensor): + """Function for computing the Jacobian of model(inputs), with respect to inputs. + Assume inputs has shape (batch, **d), where d itself could be a tuple. + Assume that model maps tensors of shape d to tensors of shape m (with m integer). + + Then the Jacobian of model has shape (m,d). + The output of this function should have shape (b,m,d) + + Parameters + ---------- + model : torch.nn.Module + The function of which to compute the Jacobian. + inputs : torch.Tensor + The inputs for model. First dimension should be batch dimension. + """ + b = inputs.size(0) + return torch.stack([jacobian(model, inputs[i]) for i in range(b)]) + + +def test_quadratic_jacobian(): + torch.manual_seed(1) + inputs = torch.randn(b,d) + model = Quadratic(d) + + # f(x) = 0.5 x^T A x --> Df(x) = 0.5*(A+A.T)x + expected = 0.5 * inputs @ (model.A.T + model.A) + jac = compute_batch_jacobian_naive(model, inputs) + + assert torch.allclose(expected, jac, rtol=1e-5, atol=1e-5) + + return + + +# TODO: test for multi-dim output, and d being a tuple (eg use convolution, softmax) +#%% multi-dim output + +model = torch.nn.Sequential(torch.nn.Linear(d,m), + torch.nn.Softmax()) + +inputs = torch.randn(b,d) +output = model(inputs) + + +jac = compute_batch_jacobian_naive(model, inputs) + +assert jac.shape == torch.Size([b,m,d]) \ No newline at end of file From 552253369763817d3b57b2135d1c8c49a4aba2d6 Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Tue, 5 Mar 2024 14:29:56 +0100 Subject: [PATCH 05/13] add jacobian functions and tests --- ncopt/tests/test_jacobians.py | 101 ++++++++++++++++++++++++++++++++++ ncopt/utils.py | 69 +++++++++++++++++++++++ scripts/compute_jacobian.py | 62 --------------------- 3 files changed, 170 insertions(+), 62 deletions(-) create mode 100644 ncopt/tests/test_jacobians.py create mode 100644 ncopt/utils.py delete mode 100644 scripts/compute_jacobian.py diff --git a/ncopt/tests/test_jacobians.py b/ncopt/tests/test_jacobians.py new file mode 100644 index 0000000..3d7617a --- /dev/null +++ b/ncopt/tests/test_jacobians.py @@ -0,0 +1,101 @@ +import torch +import sys, os + +tests_path = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, tests_path + '/../..') + +from ncopt.utils import compute_batch_jacobian_naive, compute_batch_jacobian_vmap + +d = 10 +m = 3 +b = 4 + +class Quadratic(torch.nn.Module): + def __init__(self, input_dim): + super().__init__() + self.A = torch.nn.Parameter(torch.randn((input_dim, input_dim))) + + def forward(self, x): + return (1/2) * x @ self.A @ x + + +class DummyNet(torch.nn.Module): + def __init__(self, d=7, C=1, num_classes=10): + super(DummyNet, self).__init__() + + self.conv = torch.nn.Conv2d(1, 8, kernel_size=5, stride=1, padding=2) + self.linear_input_dim = 8*C*d*d + self.linear = torch.nn.Linear(self.linear_input_dim, num_classes) + + def forward(self, x): + x = torch.nn.functional.relu(self.conv(x)) + x = x.view(-1, self.linear_input_dim) # Batch dimension specified by -1. + x = self.linear(x) + return x + +###################################################### +#### Tests start here + +def test_quadratic_jacobian(): + torch.manual_seed(1) + inputs = torch.randn(b,d) + model = Quadratic(d) + + # f(x) = 0.5 x^T A x --> Df(x) = 0.5*(A+A.T)x + expected = 0.5 * inputs @ (model.A.T + model.A) + + jac1 = compute_batch_jacobian_naive(model, inputs) + jac2 = compute_batch_jacobian_vmap(model, inputs) + + assert torch.allclose(expected, jac1, rtol=1e-5, atol=1e-5) + assert torch.allclose(jac1, jac2, rtol=1e-5, atol=1e-5) + + return + +def test_multidim_output(): + + model = torch.nn.Sequential(torch.nn.Linear(d,m), + torch.nn.Softmax(dim=-1)) + + inputs = torch.randn(b,d) + output = model(inputs) + assert output.shape == torch.Size([b,m]) + + jac1 = compute_batch_jacobian_naive(model, inputs) + jac2 = compute_batch_jacobian_vmap(model, inputs) + + + assert jac1.shape == torch.Size([b,m,d]) + assert jac2.shape == torch.Size([b,m,d]) + + assert torch.allclose(jac1, jac2, rtol=1e-5, atol=1e-5) + + return + + +def test_multidim_output_multiaxis_input(): + + pixel = 7 + channel = 1 + num_classes = 9 + input_dim = (channel,pixel,pixel) + inputs = torch.randn(b,*input_dim) + + model = DummyNet(d=pixel, C=channel, num_classes=num_classes) + output = model(inputs) + + assert output.shape == torch.Size([b,num_classes]) + + jac1 = compute_batch_jacobian_naive(model, inputs) + jac2 = compute_batch_jacobian_vmap(model, inputs) + + # this case has an extra dimension, due to the view operation + assert jac1.shape == torch.Size([b,1,num_classes,*input_dim]) + assert jac2.shape == torch.Size([b,1,num_classes,*input_dim]) + + assert torch.allclose(jac1, jac2, rtol=1e-5, atol=1e-5) + + + + + diff --git a/ncopt/utils.py b/ncopt/utils.py new file mode 100644 index 0000000..cbc5bea --- /dev/null +++ b/ncopt/utils.py @@ -0,0 +1,69 @@ +import torch +from torch.autograd.functional import jacobian +from torch.func import vmap, jacrev, functional_call + +#%% Computing Jacobians +""" +Important: jacobian and jacrev do the forward pass for each row of the input, that is, +WITHOUT the batch dimension! + +E.g. if input has shape (d1, d2), then normal forward pas has input +(b, d1, d2); but jacobian/jacrev will do the forward pass with a (d1,d2) tensor. + +This becomes an issue when there are reshape/view modules, because they often will +have different results when there is no batch dimension. + +* If the forward method uses rehshape/view, the batch dimension should be + specified with -1, and not with x.shape[0] or similar! +* For the Jacobian, we get an extra dimension in such cases --> needs to be + removed later on +""" + +""" + + Functions for computing the Jacobian of model(inputs) wrt. inputs. + Assume inputs has shape (batch, *d), where d itself could be a tuple. + Assume that model output has shape m (with m integer). + + Then the Jacobian of model has shape (m,d). + The output of the below functions should have + - either shape (b,m,*d), + - or shape (b,1,m,*d) (see above for explanation). + + For more info see: + * https://discuss.pytorch.org/t/computing-batch-jacobian-efficiently/80771/11 + * https://pytorch.org/tutorials/intermediate/jacobians_hessians.html +""" + +def compute_batch_jacobian_naive(model: torch.nn.Module, inputs: torch.Tensor): + """ + + Parameters + ---------- + model : torch.nn.Module + The function of which to compute the Jacobian. + inputs : torch.Tensor + The inputs for model. First dimension should be batch dimension. + """ + b = inputs.size(0) + # want to have batch dimension --> double brackets + return torch.stack([jacobian(model, inputs[i]) for i in range(b)]) + +def compute_batch_jacobian_vmap(model: torch.nn.Module, inputs: torch.Tensor): + """ + + Parameters + ---------- + model : torch.nn.Module + The function of which to compute the Jacobian. + inputs : torch.Tensor + The inputs for model. First dimension should be batch dimension. + """ + params = dict(model.named_parameters()) + + def fmodel(params, inputs): #functional version of model + return functional_call(model, params, inputs) + + # argnums specifies which argument to compute jacobian wrt + # in_dims: dont map over params (None), map over first dim of inputs (0) + return vmap(jacrev(fmodel, argnums=(1)), in_dims=(None,0))(params, inputs) diff --git a/scripts/compute_jacobian.py b/scripts/compute_jacobian.py deleted file mode 100644 index ab87dab..0000000 --- a/scripts/compute_jacobian.py +++ /dev/null @@ -1,62 +0,0 @@ -import torch -from torch.autograd.functional import jacobian - -d = 10 -m = 3 -b = 4 - - -class Quadratic(torch.nn.Module): - def __init__(self, input_dim): - super().__init__() - self.A = torch.nn.Parameter(torch.randn((input_dim, input_dim))) - - def forward(self, x): - return (1/2) * x @ self.A @ x - -def compute_batch_jacobian_naive(model: torch.nn.Module, inputs: torch.Tensor): - """Function for computing the Jacobian of model(inputs), with respect to inputs. - Assume inputs has shape (batch, **d), where d itself could be a tuple. - Assume that model maps tensors of shape d to tensors of shape m (with m integer). - - Then the Jacobian of model has shape (m,d). - The output of this function should have shape (b,m,d) - - Parameters - ---------- - model : torch.nn.Module - The function of which to compute the Jacobian. - inputs : torch.Tensor - The inputs for model. First dimension should be batch dimension. - """ - b = inputs.size(0) - return torch.stack([jacobian(model, inputs[i]) for i in range(b)]) - - -def test_quadratic_jacobian(): - torch.manual_seed(1) - inputs = torch.randn(b,d) - model = Quadratic(d) - - # f(x) = 0.5 x^T A x --> Df(x) = 0.5*(A+A.T)x - expected = 0.5 * inputs @ (model.A.T + model.A) - jac = compute_batch_jacobian_naive(model, inputs) - - assert torch.allclose(expected, jac, rtol=1e-5, atol=1e-5) - - return - - -# TODO: test for multi-dim output, and d being a tuple (eg use convolution, softmax) -#%% multi-dim output - -model = torch.nn.Sequential(torch.nn.Linear(d,m), - torch.nn.Softmax()) - -inputs = torch.randn(b,d) -output = model(inputs) - - -jac = compute_batch_jacobian_naive(model, inputs) - -assert jac.shape == torch.Size([b,m,d]) \ No newline at end of file From 1f70fec1678cf9982fa287312e73c13dbd2c0b39 Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Tue, 5 Mar 2024 14:32:25 +0100 Subject: [PATCH 06/13] add data folders --- data/checkpoints/README.md | 1 + data/img/README.md | 1 + 2 files changed, 2 insertions(+) create mode 100644 data/checkpoints/README.md create mode 100644 data/img/README.md diff --git a/data/checkpoints/README.md b/data/checkpoints/README.md new file mode 100644 index 0000000..5359f4e --- /dev/null +++ b/data/checkpoints/README.md @@ -0,0 +1 @@ +# Folder for storing Pytorch checkpoints \ No newline at end of file diff --git a/data/img/README.md b/data/img/README.md new file mode 100644 index 0000000..2ac05e0 --- /dev/null +++ b/data/img/README.md @@ -0,0 +1 @@ +# Folder for storing images \ No newline at end of file From 5df0c84fe88d285e5e4236d7b10d9e4bf5a5ddf5 Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Tue, 5 Mar 2024 15:05:56 +0100 Subject: [PATCH 07/13] add checkpoint and refactor training script --- data/checkpoints/max2d.pt | Bin 0 -> 2368 bytes scripts/train_max_fun.py | 199 +++++++++++++++----------------------- 2 files changed, 77 insertions(+), 122 deletions(-) create mode 100644 data/checkpoints/max2d.pt diff --git a/data/checkpoints/max2d.pt b/data/checkpoints/max2d.pt new file mode 100644 index 0000000000000000000000000000000000000000..8a0b45670fed4a386338f4375783b0c1fd9f4b5c GIT binary patch literal 2368 zcmbtWO^n+_6n3(Iso6j17HC<@KTTmb8z)Y(DcwzLAbYTYGziH;s$3_YjV}=La*;ZYiG;%yM-@NaA zdGC#D^3X8HrBd7tHp$I!wst0`FX$T8GM!hfsx-~LJYcUS1K`ri2*OFnX&R7__bSu) zW;;5uRF7(usJhvtkZd*`%OXu`I&F`C!PSXN^k;B|hoQrD7)~pD5M~LP)5L5U6h@lV zahpa)^{Hujyy}vMZ(6!aN!xQ=buGukXgaNoA;`m>T8qF~1mUZeqtO?mNgh&40{3KL zk1~YMX2%C!9;R@|37M0Va`HTk<0Ek%CN>O4WRk*E9j3#Bkxj$YJh;<9SH_qT9VNhB z1}`Tm>dt z^)qIdLk)G!?vS?GZoyMB7oHmBh^mvOb{3A}B!jn!M~UmK!O})_oOUJ@4VE`TrB@x7 zXqcjv=aos^uA592l*rT?7J*|M3Xij9+r$Y=wOly9QmJ*>jp9lei3ie2cp6of6U5hi zKU0&(QeS`fVIzUb#YSz%f|}x_Zb3E9QsS@zs7lK>RMbF$-Qv|UDYXbAvA%S5KcmUU z&LqaUW3j4U$X2DJ|BJ!Z;g2fc{61BDcJ7zLwav{6V`5)_?=))xY}|}VG0sG&O1WJy zxv=@_r8jUezkmJw#pf&!*tnVB<+$HmRXVZ@zgvGxAc+^}uOBGwd;6`AFBg8e$as8m zX!gz9jz7P<_yysE6210riTV8z{`lwC@lS9|-T1qmrz(|qFF>AWp1*vj^%84cZ0xN3 zEGKq7XIMjA@Q90*W}eg7m7tn>Rm$Erk!+z@%ol`mAuEc)qEHrva!C-1LP;o;M6poH zi)B$PE#?@@3$K4#O(R1#YI1^+?cIFw5@yYz-}>*tL2SJ8SmWKc6W9K#)Bnz>nmjr>*F_v0n(tv*l`z|S{=~iz(Eeo26Af|f WyMp_^yMZm& max(c1*x[0], c2*x[1]) - 1 -The idea is to use a neural network as a constraint for SQP-GS. +Serves as example how to use neural networks as constraint functions for SQP-GS. """ import numpy as np @@ -11,174 +11,129 @@ import torch from torch.optim.lr_scheduler import StepLR -c1 = np.sqrt(2); c2 = 2. +c1 = np.sqrt(2) +c2 = 2. @np.vectorize def g(x0,x1): return np.maximum(c1*x0, c2*x1) - 1 -def generate_data(N): - x0 = 2*np.random.randn(N)# * 10 - 5 - x1 = 2*np.random.randn(N)# * 10 - 5 - x0.sort();x1.sort() +def generate_data(grid_points): + x0 = 2*np.random.randn(grid_points) + x1 = 2*np.random.randn(grid_points) + x0.sort() + x1.sort() X0,X1 = np.meshgrid(x0,x1) return X0,X1 -X0, X1 = generate_data(200) +grid_points = 500 +X0, X1 = generate_data(grid_points) Z = g(X0,X1) -#%% +#%% Preparations tmp = np.stack((X0.reshape(-1),X1.reshape(-1))).T -# pytorch weights are in torch.float32, numpy data is float64! -tX = torch.tensor(tmp, dtype = torch.float32) -tZ = torch.tensor(Z.reshape(-1), dtype = torch.float32) - -N = len(tX) +# pytorch weights are in torch.float32, numpy data is float64 +tX = torch.tensor(tmp, dtype=torch.float32) +tZ = torch.tensor(Z.reshape(-1), dtype=torch.float32) -#%% -# # D_in is input dimension; -# # H is hidden dimension; D_out is output dimension. - -# D_in, H, D_out = 2, 200, 1 - -# # define model and loss function. -# model = torch.nn.Sequential( -# torch.nn.Linear(D_in, H), -# torch.nn.ReLU(), -# torch.nn.Linear(H, H), -# torch.nn.ReLU(), -# torch.nn.Linear(H, H), -# torch.nn.ReLU(), -# torch.nn.Linear(H, H), -# torch.nn.ReLU(), -# torch.nn.Linear(H, D_out), -# ) - -# loss_fn = torch.nn.MSELoss(reduction='mean') +num_samples = len(tX) # number of training points #%% -class myNN(torch.nn.Module): +class Max2D(torch.nn.Module): def __init__(self): super().__init__() - self.l1 = torch.nn.Linear(2, 2) # layer 1 - #self.l2 = torch.nn.Linear(20, 2) # layer 2 - #self.relu = torch.nn.ReLU() - self.max = torch.max + self.l1 = torch.nn.Linear(2, 2) def forward(self, x): x = self.l1(x) - x,_ = self.max(x, dim = -1) + x,_ = torch.max(x, dim=-1) return x loss_fn = torch.nn.MSELoss(reduction='mean') - -model = myNN() - -# set weights manually -#model.state_dict()["l1.weight"][:] = torch.diag(torch.tensor([c1,c2])) -#model.state_dict()["l1.bias"][:] = -torch.ones(2) +model = Max2D() print(model.l1.weight) print(model.l1.bias) -#testing -x = torch.tensor([1.,4.]) -model(x) -g(x[0], x[1]) +# testing +x = torch.tensor([1., 4.]) +print("True value: ", g(x[0], x[1]), ". Predicted value: ", model(x).item()) -#%% -learning_rate = 1e-3 -N_EPOCHS = 11 -b = 15 -#optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) -optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate, momentum=0.9, nesterov=True) +#%% Training + +lr = 1e-3 +num_epochs = 10 +batch_size = 25 -scheduler = StepLR(optimizer, step_size=1, gamma=0.5) +optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9) +scheduler = StepLR(optimizer, step_size=5, gamma=0.5) -def sample_batch(N, b): - S = torch.randint(high = N, size = (b,)) +def sample_batch(num_samples, b): + S = torch.randint(high=num_samples, size=(b,)) return S -for epoch in range(N_EPOCHS): - print(f"..................EPOCH {epoch}..................") - - for t in range(int(N/b)): - - S = sample_batch(N, b) - x_batch = tX[S]; z_batch = tZ[S] - - # forward pass - y_pred = model.forward(x_batch) +for epoch in range(num_epochs): - # compute loss. - loss = loss_fn(y_pred.squeeze(), z_batch) - - # zero gradients + epoch_loss = 0 + for t in range(num_samples//batch_size): + + S = sample_batch(num_samples, batch_size) + x_batch = tX[S] + z_batch = tZ[S] + optimizer.zero_grad() - - # backward pass + + loss = loss_fn(model.forward(x_batch), z_batch) loss.backward() - - # iteration optimizer.step() - - print(model.l1.weight) - print(model.l1.bias) + epoch_loss += loss.item() - print(loss.item()) - scheduler.step() - #print(optimizer) - -optimizer.zero_grad() - -#%% plot results - -N_test = 200 -X0_test,X1_test = generate_data(N_test) - -tmp = np.stack((X0_test.reshape(-1), X1_test.reshape(-1))).T - -# pytorch weights are in torch.float32, numpy data is float64! -X_test = torch.tensor(tmp, dtype = torch.float32) - -Z_test = model.forward(X_test).detach().numpy().squeeze() - -Z_test_arr = Z_test.reshape(N_test, N_test) - -Z_true = g(X0_test,X1_test).reshape(-1) - - -fig, axs = plt.subplots(1,2) -axs[0].scatter(tmp[:,0], tmp[:,1], c = Z_test) -#axs[1].scatter(tmp[:,0], tmp[:,1], c = Z_true) -axs[1].scatter(tmp[:,0], tmp[:,1], c = Z_test-Z_true, vmin = -1e-1, vmax = 1e-1, cmap = "coolwarm") + print(f"Epoch {epoch+1}/{num_epochs}: loss={np.mean(epoch_loss)}") + scheduler.step() +print("Learned parameters:") +print(model.l1.weight) +print(model.l1.bias) -#%% -from mpl_toolkits.mplot3d import Axes3D -fig = plt.figure() -ax = fig.gca(projection='3d') +#%% Save checkpoint -# Plot the surface. -ax.plot_surface(X0_test, X1_test, Z_test_arr, cmap=plt.cm.coolwarm, linewidth=0, antialiased=False) +path = '../data/checkpoints/max2d.pt' +torch.save({'epoch': epoch, + 'model_state_dict': model.state_dict(), + 'optimizer_state_dict': optimizer.state_dict(), + }, path) + -#%% test auto-diff gradient +#%% Plot results -x0 = torch.tensor([np.sqrt(2),0.5], dtype = torch.float32) +N_test = 200 +X0_test, X1_test = generate_data(N_test) -x0.requires_grad_(True) -model.zero_grad() +tmp = np.stack((X0_test.reshape(-1), X1_test.reshape(-1))).T -y0 = model(x0) -y0.backward() +# pytorch weights are in torch.float32, numpy data is float64 +X_test = torch.tensor(tmp, dtype=torch.float32) -x0.grad.data +Z_test = model.forward(X_test).detach().numpy().squeeze() +Z_test_arr = Z_test.reshape(N_test, N_test) +Z_true = g(X0_test,X1_test) -W = model[-3].weight.detach().numpy() +print("Test mean squared error: ", np.mean((Z_test-Z_true.reshape(-1))**2)) +fig, axs = plt.subplots(1,2, figsize=(8,4)) +ax = axs[0] +ax.contourf(X0_test, X1_test, Z_test_arr, cmap='magma', vmin=-10,vmax=10,levels=50) +ax.set_xlim(-5,5) +ax.set_ylim(-5,5) +ax.set_title("Learned contours") +ax = axs[1] +ax.contourf(X0_test, X1_test, Z_true, cmap='magma', vmin=-10,vmax=10,levels=50) +ax.set_xlim(-5,5) +ax.set_ylim(-5,5) +ax.set_title("True contours") From 39cd797cac48dcab6230239a6f6633bc18ff0280 Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Tue, 5 Mar 2024 19:22:41 +0100 Subject: [PATCH 08/13] style example --- README.md | 2 +- data/img/rosenbrock.png | Bin 0 -> 85476 bytes example_rosenbrock.py | 68 ++++++++++++++++++++++++---------- ncopt/tests/test_jacobians.py | 1 + ncopt/utils.py | 38 +++++++++++++++++++ rosenbrock.png | Bin 174385 -> 0 bytes 6 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 data/img/rosenbrock.png delete mode 100644 rosenbrock.png diff --git a/README.md b/README.md index 4710574..418fbdb 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The code was tested for a 2-dim nonsmooth version of the Rosenbrock function, co To reproduce this experiment, see the file `example_rosenbrock.py`. -![SQP-GS trajectories for a 2-dim example](rosenbrock.png "SQP-GS trajectories for a 2-dim example") +![SQP-GS trajectories for a 2-dim example](data/img/rosenbrock.png "SQP-GS trajectories for a 2-dim example") ## Implementation details diff --git a/data/img/rosenbrock.png b/data/img/rosenbrock.png new file mode 100644 index 0000000000000000000000000000000000000000..c7f75642cb251c7e266e561b694c15b2c4570a4a GIT binary patch literal 85476 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 z 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 t)tkNC|7$ie=9B+#r?db6zd!7HgQI+4c logging.Logger: + """Construct a logging.Logger instance with an appropriate configuration. + + Params: + name: name for the Logger instance. + verbose: (optional) whether or not the logger should print verbosely + (ie. at the `INFO` level). + debug: (optional) whether or not the logger should print in debug mode + (ie. at the `DEBUG` level). + log_file: (optional) path to a file where the log should be stored. The + log is printed to `stdout` when `None`. + + Returns: + Instance of logging.Logger. + """ + + level = logging.WARNING + if debug: + level = logging.DEBUG + elif verbose: + level = logging.INFO + + logging.basicConfig(level=level, filename=log_file) + logger = logging.getLogger(name) + logging.root.setLevel(level) + logger.setLevel(level) + return logger diff --git a/rosenbrock.png b/rosenbrock.png deleted file mode 100644 index 78f5862d41553718016aa344b93df1b5a42c87c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174385 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

Mc{Ij@0UAKHzM>JUrow6R& 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 RcmY==c?Bv-fa&g2{UV5iU$L- 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 JySv8E{uk(Ac<2BC From da9a0faf9466a12170b1cd690cb6f6d59b5e4c07 Mon Sep 17 00:00:00 2001 From: fabian-sp Date: Wed, 6 Mar 2024 14:07:08 +0100 Subject: [PATCH 09/13] add forward option --- ncopt/tests/test_jacobians.py | 16 ++++++++++++++++ ncopt/utils.py | 12 +++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ncopt/tests/test_jacobians.py b/ncopt/tests/test_jacobians.py index 4e6f4b4..f800973 100644 --- a/ncopt/tests/test_jacobians.py +++ b/ncopt/tests/test_jacobians.py @@ -53,6 +53,22 @@ def test_quadratic_jacobian(): return +def test_forward_backward_jacobian(): + torch.manual_seed(1) + inputs = torch.randn(b,d) + model = Quadratic(d) + + # f(x) = 0.5 x^T A x --> Df(x) = 0.5*(A+A.T)x + expected = 0.5 * inputs @ (model.A.T + model.A) + + jac1 = compute_batch_jacobian_vmap(model, inputs, forward=False) + jac2 = compute_batch_jacobian_vmap(model, inputs, forward=True) + + assert torch.allclose(expected, jac1, rtol=1e-5, atol=1e-5) + assert torch.allclose(jac1, jac2, rtol=1e-5, atol=1e-5) + + return + def test_multidim_output(): model = torch.nn.Sequential(torch.nn.Linear(d,m), diff --git a/ncopt/utils.py b/ncopt/utils.py index 3c566cd..3e6465c 100644 --- a/ncopt/utils.py +++ b/ncopt/utils.py @@ -1,6 +1,6 @@ import torch from torch.autograd.functional import jacobian -from torch.func import vmap, jacrev, functional_call +from torch.func import vmap, jacrev, jacfwd, functional_call import logging from typing import Optional @@ -52,7 +52,8 @@ def compute_batch_jacobian_naive(model: torch.nn.Module, inputs: torch.Tensor): # want to have batch dimension --> double brackets return torch.stack([jacobian(model, inputs[i]) for i in range(b)]) -def compute_batch_jacobian_vmap(model: torch.nn.Module, inputs: torch.Tensor): +def compute_batch_jacobian_vmap(model: torch.nn.Module, inputs: torch.Tensor, + forward: bool=False): """ Parameters @@ -61,6 +62,8 @@ def compute_batch_jacobian_vmap(model: torch.nn.Module, inputs: torch.Tensor): The function of which to compute the Jacobian. inputs : torch.Tensor The inputs for model. First dimension should be batch dimension. + forward: bool. + Whether to compute in forward mode (jacrev or jacfwd). By default False. """ params = dict(model.named_parameters()) @@ -69,7 +72,10 @@ def fmodel(params, inputs): #functional version of model # argnums specifies which argument to compute jacobian wrt # in_dims: dont map over params (None), map over first dim of inputs (0) - return vmap(jacrev(fmodel, argnums=(1)), in_dims=(None,0))(params, inputs) + if not forward: + return vmap(jacrev(fmodel, argnums=(1)), in_dims=(None,0))(params, inputs) + else: + return vmap(jacfwd(fmodel, argnums=(1)), in_dims=(None,0))(params, inputs) #%% # copied from https://github.com/aaronpmishkin/experiment_utils/blob/main/src/experiment_utils/utils.py#L298 From 1c611c9cab25f73a30016039723d8ab2ad41c494 Mon Sep 17 00:00:00 2001 From: fabian-sp Date: Wed, 6 Mar 2024 23:34:59 +0100 Subject: [PATCH 10/13] start logging --- example_rosenbrock.py | 5 +++-- ncopt/sqpgs/defaults.py | 2 ++ ncopt/sqpgs/main.py | 26 +++++++++++++++++++------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/example_rosenbrock.py b/example_rosenbrock.py index 8049cc6..1e88f82 100755 --- a/example_rosenbrock.py +++ b/example_rosenbrock.py @@ -57,7 +57,8 @@ for i in range(20): x0 = np.random.randn(2) - problem = SQPGS(f, gI, gE, x0, tol=1e-6, max_iter=100, verbose=False) + problem = SQPGS(f, gI, gE, x0, tol=1e-6, max_iter=100, verbose=False, + store_history=True) x_k = problem.solve() print(x_k) @@ -80,4 +81,4 @@ ax.legend(handles=legend_elements, ncol=3, fontsize=8) fig.tight_layout() -fig.savefig('data/img/rosenbrock.png') +# fig.savefig('data/img/rosenbrock.png') diff --git a/ncopt/sqpgs/defaults.py b/ncopt/sqpgs/defaults.py index 03feb05..43a414d 100644 --- a/ncopt/sqpgs/defaults.py +++ b/ncopt/sqpgs/defaults.py @@ -11,6 +11,8 @@ class Dotdict(dict): 'max_iter': 100, 'verbose': True, 'assert_tol': 1e-5, + 'store_history': False, + 'log_every': 10 } _option_defaults = {'eps': 1e-1, diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py index 9ef9cbc..210f7de 100644 --- a/ncopt/sqpgs/main.py +++ b/ncopt/sqpgs/main.py @@ -17,6 +17,7 @@ from typing import Optional from .defaults import DEFAULT_ARG, DEFAULT_OPTION +from ..utils import get_logger class SQPGS: def __init__(self, @@ -28,7 +29,9 @@ def __init__(self, max_iter: int=DEFAULT_ARG.max_iter, verbose: bool=DEFAULT_ARG.verbose, options: dict={}, - assert_tol: float=DEFAULT_ARG.assert_tol + assert_tol: float=DEFAULT_ARG.assert_tol, + store_history: bool=DEFAULT_ARG.store_history, + log_every: int=DEFAULT_ARG.log_every ) -> None: if tol < 0: @@ -46,6 +49,8 @@ def __init__(self, self.verbose = verbose self.options = options self.assert_tol = assert_tol + self.store_history = store_history + self.log_every = log_every # Set options/hyperparameters # (defaults are chose according to recommendations in paper) @@ -71,6 +76,7 @@ def __init__(self, ########## Initialize self.status = 'not optimal' + self.logger = get_logger(name='ncopt', verbose=self.verbose) # starting point if x0 is None: @@ -110,7 +116,6 @@ def solve(self): self.SP = SubproblemSQPGS(self.dim, p0, pI, pE, self.assert_tol) E_k = np.inf # for stopping criterion - x_hist = [self.x_k] x_kmin1 = None # last iterate g_kmin1 = None # @@ -126,6 +131,7 @@ def solve(self): if self.verbose: print(hdr_fmt % ("iter", "f(x_k)", "max(g_j(x_k))", "E_k", "step", "subproblem status")) + x_hist = [self.x_k] if self.store_history else None self.timings = {'total': [], 'sp_update': [], 'sp_solve': []} ############################################## # START OF LOOP @@ -208,9 +214,12 @@ def solve(self): assert delta_q >= -self.assert_tol, f"Value is supposed to be non-negative, but is {delta_q}." assert np.abs(self.SP.lambda_f.sum() - rho) <= self.assert_tol, f"Value is supposed to be negative, but is {np.abs(self.SP.lambda_f.sum() - rho)}." - if self.verbose: - print(out_fmt % (iter_k, f_k, np.max(np.hstack((gI_k,gE_k))), E_k, do_step, self.SP.status)) + # if self.verbose: + # print(out_fmt % (iter_k, f_k, np.max(np.hstack((gI_k,gE_k))), E_k, do_step, self.SP.status)) + _viol = np.max(np.hstack((gI_k, np.abs(gE_k)))) + self.logger.info(f"Iter {iter_k+1}, objective {f_k:.3E}, constraint violation {_viol:.3E}, accuracy {E_k:.3E}, avg runtime per iter {np.mean(self.timings['total']):.3E}.") + new_E_k = stop_criterion(self.gI, self.gE, g_k, self.SP, gI_k, gE_k, B_gI, B_gE, self.nI_, self.nE_, pI, pE) E_k = min(E_k, new_E_k) @@ -273,19 +282,22 @@ def solve(self): eps *= beta_eps - x_hist.append(self.x_k) + if self.store_history: + x_hist.append(self.x_k) t1 = time.perf_counter() self.timings['total'].append(t1-t0) ############################################## # END OF LOOP ############################################## - self.x_hist = np.vstack(x_hist) + self.x_hist = np.vstack(x_hist) if self.store_history else None if E_k > self.tol: self.status = 'max iterations reached' - print(f"SQP-GS has terminated with status: {self.status}.") + _final_msg = f"SQP-GS has terminated with status: {self.status}, final accuracy {E_k}." + self.logger.info(_final_msg) + print(_final_msg) # we always want to display this. return self.x_k From e7a8db0a24fb07e0435624fe6a8730a06f6ac79b Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Thu, 7 Mar 2024 09:47:38 +0100 Subject: [PATCH 11/13] log every N steps --- example_rosenbrock.py | 2 +- ncopt/sqpgs/main.py | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/example_rosenbrock.py b/example_rosenbrock.py index 1e88f82..96e21ec 100755 --- a/example_rosenbrock.py +++ b/example_rosenbrock.py @@ -81,4 +81,4 @@ ax.legend(handles=legend_elements, ncol=3, fontsize=8) fig.tight_layout() -# fig.savefig('data/img/rosenbrock.png') +fig.savefig('data/img/rosenbrock.png') diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py index 210f7de..3def857 100644 --- a/ncopt/sqpgs/main.py +++ b/ncopt/sqpgs/main.py @@ -126,11 +126,6 @@ def solve(self): do_step = False - hdr_fmt = "%4s\t%10s\t%5s\t%5s\t%10s\t%10s" - out_fmt = "%4d\t%10.4g\t%10.4g\t%10.4g\t%10.4g\t%10s" - if self.verbose: - print(hdr_fmt % ("iter", "f(x_k)", "max(g_j(x_k))", "E_k", "step", "subproblem status")) - x_hist = [self.x_k] if self.store_history else None self.timings = {'total': [], 'sp_update': [], 'sp_solve': []} ############################################## @@ -214,11 +209,10 @@ def solve(self): assert delta_q >= -self.assert_tol, f"Value is supposed to be non-negative, but is {delta_q}." assert np.abs(self.SP.lambda_f.sum() - rho) <= self.assert_tol, f"Value is supposed to be negative, but is {np.abs(self.SP.lambda_f.sum() - rho)}." - # if self.verbose: - # print(out_fmt % (iter_k, f_k, np.max(np.hstack((gI_k,gE_k))), E_k, do_step, self.SP.status)) - - _viol = np.max(np.hstack((gI_k, np.abs(gE_k)))) - self.logger.info(f"Iter {iter_k+1}, objective {f_k:.3E}, constraint violation {_viol:.3E}, accuracy {E_k:.3E}, avg runtime per iter {np.mean(self.timings['total']):.3E}.") + # Logging, start after first iteration + if iter_k % self.log_every == 1: + _viol = np.max(np.hstack((gI_k, np.abs(gE_k)))) + self.logger.info(f"Iter {iter_k}, objective {f_k:.3E}, constraint violation {_viol:.3E}, accuracy {E_k:.3E}, avg runtime/iter {(1/1000)*np.mean(self.timings['total']):.3E} ms.") new_E_k = stop_criterion(self.gI, self.gE, g_k, self.SP, gI_k, gE_k, B_gI, B_gE, self.nI_, self.nE_, pI, pE) E_k = min(E_k, new_E_k) From 58640740ea5e8c3894f417f96674a2ba1278c3e3 Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Thu, 7 Mar 2024 09:51:56 +0100 Subject: [PATCH 12/13] fix --- ncopt/sqpgs/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py index 3def857..78a9e1c 100644 --- a/ncopt/sqpgs/main.py +++ b/ncopt/sqpgs/main.py @@ -212,7 +212,7 @@ def solve(self): # Logging, start after first iteration if iter_k % self.log_every == 1: _viol = np.max(np.hstack((gI_k, np.abs(gE_k)))) - self.logger.info(f"Iter {iter_k}, objective {f_k:.3E}, constraint violation {_viol:.3E}, accuracy {E_k:.3E}, avg runtime/iter {(1/1000)*np.mean(self.timings['total']):.3E} ms.") + self.logger.info(f"Iter {iter_k}, objective {f_k:.3E}, constraint violation {_viol:.3E}, accuracy {E_k:.3E}, avg runtime/iter {(1e3)*np.mean(self.timings['total']):.3E} ms.") new_E_k = stop_criterion(self.gI, self.gE, g_k, self.SP, gI_k, gE_k, B_gI, B_gE, self.nI_, self.nE_, pI, pE) E_k = min(E_k, new_E_k) From f40a4f38e27eb862fa435603606d1d0c73b38230 Mon Sep 17 00:00:00 2001 From: Fabian Schaipp Date: Thu, 7 Mar 2024 09:59:59 +0100 Subject: [PATCH 13/13] fix constraint violation formula --- ncopt/sqpgs/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ncopt/sqpgs/main.py b/ncopt/sqpgs/main.py index 78a9e1c..7bb0bf0 100644 --- a/ncopt/sqpgs/main.py +++ b/ncopt/sqpgs/main.py @@ -211,8 +211,10 @@ def solve(self): # Logging, start after first iteration if iter_k % self.log_every == 1: - _viol = np.max(np.hstack((gI_k, np.abs(gE_k)))) - self.logger.info(f"Iter {iter_k}, objective {f_k:.3E}, constraint violation {_viol:.3E}, accuracy {E_k:.3E}, avg runtime/iter {(1e3)*np.mean(self.timings['total']):.3E} ms.") + violI_k = np.maximum(gI_k, 0) + violE_k = np.abs(gE_k) + viol_k = np.max(np.hstack((violI_k, violE_k))) + self.logger.info(f"Iter {iter_k}, objective {f_k:.3E}, constraint violation {viol_k:.3E}, accuracy {E_k:.3E}, avg runtime/iter {(1e3)*np.mean(self.timings['total']):.3E} ms.") new_E_k = stop_criterion(self.gI, self.gE, g_k, self.SP, gI_k, gE_k, B_gI, B_gE, self.nI_, self.nE_, pI, pE) E_k = min(E_k, new_E_k)