Ejemplo n.º 1
0
 def objective(x):
     lamb = x.reshape(nG, nG)
     L = lamb.T - lamb
     dp_sol = exact_solver_wrapper(A_org, Q, p, L.T, delta_l, delta_g,
                                   '1+2')
     _, opt_val, A_pert = dp_sol
     grad_on_lambda = A_pert - A_pert.T
     return -opt_val, -grad_on_lambda.flatten()
Ejemplo n.º 2
0
 def objective(x):
     R = x.reshape(self.nG, self.nG)
     dp_sol = exact_solver_wrapper(self.A_org,
                                   np.tile(self.XWU, (self.nG, 1)),
                                   np.zeros(self.nG), -R,
                                   self.delta_l, self.delta_g, '1')
     _, opt_val, opt_W = dp_sol
     fval = opt_val.sum() + np.sum(
         R * A_pert) - eps * np.sum(R**2) / 2
     grad = A_pert - opt_W - eps * R
     return -fval, -grad.flatten()
Ejemplo n.º 3
0
        def objective(x):
            R = x.reshape(nG, nG)
            # Given R, find optimal W
            if params['activation'] == 'relu':
                if params['relu_bound'] == 'doubleL':
                    local_budget_sol = exact_solver_wrapper(
                        A_org, cvx_relaxation.Q, cvx_relaxation.p, -R, delta_l,
                        delta_g, '1+2')
                    _, opt_f_W, opt_W = local_budget_sol
                    opt_f_W = np.sum(opt_f_W)

                elif params['relu_bound'] == 'singleL':
                    local_budget_sol = exact_solver_wrapper(
                        A_org, doubleL_relax.Q, doubleL_relax.p, -R, delta_l,
                        delta_g, '1+2')
                    _, opt_f_W_1, opt_W_1 = local_budget_sol
                    opt_f_W_1 = np.sum(opt_f_W_1)
                    # cvx_relaxation.warm_start_W = opt_W_1
                    # opt_W, opt_f_W = cvx_relaxation.get_opt_W(R, spg_options)
                    opt_W = opt_W_1
                    opt_f_W = np.sum(
                        cvx_relaxation.g_hat(opt_W)[0] /
                        (1 + np.sum(opt_W, axis=1))) - np.sum(R * opt_W)
            else:
                # local_budget_sol = exact_solver_wrapper(A_org, np.tile(XWU, (nG, 1)), np.zeros(nG), -R, delta_l, delta_g, '1')
                # _, opt_f_W, opt_W = local_budget_sol
                # opt_f_W = np.sum(opt_f_W)

                dp_sol = exact_solver_wrapper(A_org, np.tile(XWU, (nG, 1)),
                                              np.zeros(nG), -R, delta_l,
                                              delta_g, '1+2')
                _, opt_f_W, opt_W = dp_sol

            # Given R, solve min_{Z \in co(A1) \cap co(A2) \cap A3} tr(R.T*Z)
            opt_Z = RZ_solver(x_vars, mdl, A_org, delta_l, delta_g, R)

            fval = opt_f_W + np.sum(R * opt_Z) - eps * np.sum(R**2) / 2
            grad = opt_Z - opt_W - eps * R
            return -fval, -grad.flatten()
Ejemplo n.º 4
0
def update_lb_ub(opt_R, doubleL, singleL=None):
    local_budget_sol = exact_solver_wrapper(doubleL.A_org, doubleL.Q, doubleL.p, -opt_R, \
                                                doubleL.delta_l, doubleL.delta_g, '1+2')
    opt_W = local_budget_sol[-1]

    # update lb and ub
    before_relu = opt_W @ doubleL.XW + doubleL.XW

    # case i
    i_idx = (before_relu > doubleL.ub)
    # case ii
    ii_idx = (before_relu < doubleL.lb)
    # within [lb, ub]
    idx = ~(i_idx ^ ii_idx)
    # idx = (before_relu <= doubleL.ub) & (before_relu >= doubleL.lb)
    # case iii
    iii_idx = idx & (before_relu > 0)
    # case iv
    iv_idx = idx & (before_relu < 0)

    if np.all(idx):
        flag = True
        # print('pre_relu in [lb, ub]!')
    else:
        flag = False
        # print('pre_relu NOT in [lb, ub]!')

    doubleL.ub[i_idx] = before_relu[i_idx]
    doubleL.lb[ii_idx] = before_relu[ii_idx]
    # doubleL.ub[iii_idx] = (before_relu[iii_idx] +  doubleL.ub[iii_idx])/2
    doubleL.ub[iii_idx] = before_relu[iii_idx]
    # doubleL.lb[iv_idx] = (before_relu[iv_idx] +  doubleL.lb[iv_idx])/2
    doubleL.lb[iv_idx] = before_relu[iv_idx]

    doubleL.S_minus = (doubleL.lb * doubleL.ub < 0) & np.tile((doubleL.U < 0),
                                                              (doubleL.nG, 1))
    doubleL.I_plus = (doubleL.lb > 0)
    doubleL.I_mix = (doubleL.lb * doubleL.ub < 0)
    doubleL.Q, doubleL.p = doubleL.doubleL_lb_coefficient()

    if singleL != None:
        singleL.ub = doubleL.ub
        singleL.lb = singleL.lb

        singleL.S_minus = (singleL.lb * singleL.ub < 0) & np.tile(
            (singleL.U < 0), (singleL.nG, 1))
        singleL.S_others = ~(singleL.S_minus)

    return flag
Ejemplo n.º 5
0
def dual_solver(A_org, XW, U, delta_l, delta_g, **params):
    """
    Dual approach (lower bound) for solving min_{A_G^{1+2+3}} F_c(A)

    param:
        A_org:          original adjacency matrix
        XW:             XW
        U:              (u_y-u_c)/nG
        delta_l:        row budgets (vector)
        delta_g:        global budget (scalar)
        params:         params for optimizing Lambda
                        'nonsmooth': could be 'random' or 'subgrad'
                        1. random: choose best solution from 5 random initialization
                        2. initilize LBFGS by solution of Quasi-Monotone Methods


    return a dict with keywords:
        opt_A:          optimal perturbed matrix
        opt_f:          optimal dual objective
    """

    nG = A_org.shape[0]
    XWU = XW @ U

    def objective(x):
        lamb = x.reshape(nG, nG)
        L = lamb.T - lamb
        dp_sol = exact_solver_wrapper(A_org, np.tile(XWU,
                                                     (nG, 1)), np.zeros(nG),
                                      L.T, delta_l, delta_g, '1+2')
        _, opt_val, A_pert = dp_sol
        grad_on_lambda = A_pert - A_pert.T
        return -opt_val, -grad_on_lambda.flatten()

    # print(optim.check_grad(lambda x: objective(x)[0], lambda x: objective(x)[1], lamb.flatten()))

    opt_lamb, fopt = optimize(objective, nG, params['iter'],
                              params.get('verbose'), params['nonsmooth_init'])
    L = opt_lamb.T - opt_lamb
    sol = {
        'opt_A':
        exact_solver_wrapper(A_org, np.tile(XWU, (nG, 1)), np.zeros(nG), L.T,
                             delta_l, delta_g, '1+2')[-1],
        'opt_f':
        fopt
    }
    return sol
Ejemplo n.º 6
0
def dual_solver_doubleL(A_org, Q, p, delta_l, delta_g, **params):
    """
    Dual approach (lower bound) for solving min_{A_G^{1+2+3}} F_c(A)
    where the activation is ReLU, and F_c(A) has been linearized via doubleL
                
    param: 
        A_org:          original adjacency matrix
        Q:              Q
        p:              p
        delta_l:        row budgets
        delta_g:        global budgets
        params:         params for optimizing Lambda
                        'nonsmooth': could be 'random' or 'subgrad'
                        1. random: choose best solution from 5 random initialization
                        2. initilize LBFGS by solution of Quasi-Monotone Methods
                        
    return a dict with keywords:
        opt_A:          optimal perturbed matrix
        opt_f:          optimal dual objective
    """

    nG = A_org.shape[0]

    def objective(x):
        lamb = x.reshape(nG, nG)
        L = lamb.T - lamb
        dp_sol = exact_solver_wrapper(A_org, Q, p, L.T, delta_l, delta_g,
                                      '1+2')
        _, opt_val, A_pert = dp_sol
        grad_on_lambda = A_pert - A_pert.T
        return -opt_val, -grad_on_lambda.flatten()

    # print(optim.check_grad(lambda x: objective(x)[0], lambda x: objective(x)[1], lamb.flatten()))

    opt_lamb, fopt = optimize(objective, nG, params['iter'],
                              params.get('verbose'), params['nonsmooth_init'])
    L = opt_lamb.T - opt_lamb
    sol = {
        'opt_A':
        exact_solver_wrapper(A_org, Q, p, L.T, delta_l, delta_g, '1+2')[-1],
        'opt_f':
        fopt
    }
    return sol
Ejemplo n.º 7
0
def admm_solver(A_org, XW, U, delta_l, delta_g, **params):
    """
    ADMM approach (upper bound) for solving min_{A_G^{1+2+3}} F_c(A)

    param: 
        A_org:          original adjacency matrix
        XW:             XW
        U:              (u_y-u_c)/nG
        delta_l:        row budgets
        delta_g:        global budgets
        params:         params for admm optimiztion

    return a dict with keywords:
        opt_A:          optimal perturbed matrix
        opt_f:          optimal objective value
    """

    nG = A_org.shape[0]
    XWU = XW @ U
    lamb = np.random.randn(nG, nG) * 0
    B = params['init_B']
    mu = params['mu']
    iters = params['iter']
    func_vals = [0] * iters
    for i in range(iters):
        # linear term: fnorm(A-B)^2 = \sum_{ij} A_ij^2 - 2*A_ijB_ij + B_ijB_ij
        L = -lamb.T + (np.ones((nG, nG)) - 2 * B.T) / (2 * mu)
        dp_sol = exact_solver_wrapper(A_org, np.tile(XWU,
                                                     (nG, 1)), np.zeros(nG),
                                      L.T, delta_l, delta_g, '1+2')
        _, opt_val, A_pert = dp_sol
        func_vals[i] = calculate_Fc(A_pert, XW, U)
        B = closed_form_B(lamb, A_pert, mu)
        lamb += (B - A_pert) / mu
        if params.get('verbose'):
            print(func_vals[i])

    sol = {'opt_A': A_pert, 'opt_f': func_vals[-1]}
    return sol
Ejemplo n.º 8
0
def admm_solver_doubleL(A_org, Q, p, delta_l, delta_g, **params):
    """
    ADMM approach (upper bound) for solving min_{A_G^{1+2+3}} F_c(A)
    where the activation is ReLU, and F_c(A) has been linearized via doubleL (upper bound)

    param: 
        A_org:          original adjacency matrix
        Q:              Q
        p:              p
        delta_l:        row budgets
        delta_g:        global budgets
        params:         params for admm optimiztion

    return a dict with keywords:
        opt_A:          optimal perturbed matrix
        opt_f:          optimal objective value
    """

    nG = A_org.shape[0]
    lamb = np.random.randn(nG, nG) * 0
    B = params['init_B']
    mu = params['mu']
    iters = params['iter']
    func_vals = [0] * iters
    for i in range(iters):
        # linear term: fnorm(A-B)^2 = \sum_{ij} A_ij^2 - 2*A_ijB_ij + B_ijB_ij
        L = -lamb.T + (np.ones((nG, nG)) - 2 * B.T) / (2 * mu)
        dp_sol = exact_solver_wrapper(A_org, Q, p, L.T, delta_l, delta_g,
                                      '1+2')
        _, opt_val, A_pert = dp_sol
        func_vals[i] = calculate_doubleL_Fc(A_pert, Q, p)
        B = closed_form_B(lamb, A_pert, mu)
        lamb += (B - A_pert) / mu
        if params.get('verbose'):
            print(func_vals[i])

    sol = {'opt_A': A_pert, 'opt_f': func_vals[-1]}
    return sol