Ejemplo n.º 1
0
 def callback(self, learner):
     self.round = self.round + 1
     tp = KernelPairwisePredictor(learner.A, learner.input1_inds,
                                  learner.input2_inds).predict(
                                      K_test1, K_test2)
     print(
         str(self.round) + ' ' +
         str(np.mean(np.abs(tp -
                            ordrls_testpred.ravel(order='F')))))
Ejemplo n.º 2
0
 def cgcb(v):
     if self.compute_risk:
         P = sampled_kronecker_products.sampled_vec_trick(
             v, K2, K1, self.input2_inds, self.input1_inds,
             self.input2_inds, self.input1_inds)
         z = (Y - P)
         Ka = sampled_kronecker_products.sampled_vec_trick(
             v, K2, K1, self.input2_inds, self.input1_inds,
             self.input2_inds, self.input1_inds)
         loss = (np.dot(z, z) + regparam * np.dot(v, Ka))
         print("loss", 0.5 * loss)
         if loss < self.bestloss:
             self.A = v.copy()
             self.bestloss = loss
     else:
         self.A = v
     if not self.callbackfun is None:
         self.predictor = KernelPairwisePredictor(
             self.A, self.input1_inds, self.input2_inds)
         self.callbackfun.callback(self)
Ejemplo n.º 3
0
    def __init__(self, **kwargs):
        self.Y = kwargs["Y"]
        #self.Y = array_tools.as_2d_array(Y)
        self.trained = False
        if "regparam" in kwargs:
            self.regparam = kwargs["regparam"]
        else:
            self.regparam = 0.
        regparam = self.regparam
        if CALLBACK_FUNCTION in kwargs:
            self.callbackfun = kwargs[CALLBACK_FUNCTION]
        else:
            self.callbackfun = None
        if "compute_risk" in kwargs:
            self.compute_risk = kwargs["compute_risk"]
        else:
            self.compute_risk = False

        if 'K1' in kwargs or 'pko' in kwargs:
            if 'pko' in kwargs:
                pko = kwargs['pko']
            else:
                self.input1_inds = np.array(kwargs["label_row_inds"],
                                            dtype=np.int32)
                self.input2_inds = np.array(kwargs["label_col_inds"],
                                            dtype=np.int32)
                K1 = kwargs['K1']
                K2 = kwargs['K2']
                if 'weights' in kwargs: weights = kwargs['weights']
                else: weights = None
                pko = pairwise_kernel_operator.PairwiseKernelOperator(
                    K1, K2, self.input1_inds, self.input2_inds,
                    self.input1_inds, self.input2_inds, weights)
            self.pko = pko
            if 'maxiter' in kwargs: maxiter = int(kwargs['maxiter'])
            else: maxiter = None

            Y = np.array(self.Y).ravel(order='F')
            self.bestloss = float("inf")

            def mv(v):
                return pko.matvec(v) + regparam * v

            def mvr(v):
                raise Exception('This function should not be called!')

            def cgcb(v):
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        v, K2, K1, self.input2_inds, self.input1_inds,
                        self.input2_inds, self.input1_inds)
                    z = (Y - P)
                    Ka = sampled_kronecker_products.sampled_vec_trick(
                        v, K2, K1, self.input2_inds, self.input1_inds,
                        self.input2_inds, self.input1_inds)
                    loss = (np.dot(z, z) + regparam * np.dot(v, Ka))
                    print("loss", 0.5 * loss)
                    if loss < self.bestloss:
                        self.A = v.copy()
                        self.bestloss = loss
                else:
                    self.A = v
                if not self.callbackfun is None:
                    #self.predictor = KernelPairwisePredictor(self.A, self.input1_inds, self.input2_inds, self.pko.weights)
                    self.callbackfun.callback(self)

            G = LinearOperator((self.Y.shape[0], self.Y.shape[0]),
                               matvec=mv,
                               rmatvec=mvr,
                               dtype=np.float64)
            self.A = minres(G,
                            self.Y,
                            maxiter=maxiter,
                            callback=cgcb,
                            tol=1e-20)[0]
            self.predictor = KernelPairwisePredictor(
                self.A, self.pko.original_col_inds_K1,
                self.pko.original_col_inds_K2, self.pko.weights)
            if not self.callbackfun is None:
                self.callbackfun.finished(self)
        else:
            self.input1_inds = np.array(kwargs["label_row_inds"],
                                        dtype=np.int32)
            self.input2_inds = np.array(kwargs["label_col_inds"],
                                        dtype=np.int32)
            X1 = kwargs['X1']
            X2 = kwargs['X2']
            self.X1, self.X2 = X1, X2

            if 'maxiter' in kwargs: maxiter = int(kwargs['maxiter'])
            else: maxiter = None

            if 'weights' in kwargs: weights = kwargs['weights']
            else: weights = None

            Y = np.array(self.Y).ravel(order='F')
            self.bestloss = float("inf")

            def mv(v):
                v_after = pko.matvec(v)
                v_after = pko.rmatvec(v_after) + regparam * v
                return v_after

            def cgcb(v):
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        v, X2, X1, self.input2_inds, self.input1_inds)
                    z = (Y - P)
                    loss = (np.dot(z, z) + regparam * np.dot(v, v))
                    if loss < self.bestloss:
                        self.W = v.copy().reshape(pko.shape, order='F')
                        self.bestloss = loss
                else:
                    self.W = v
                if not self.callbackfun is None:
                    self.predictor = LinearPairwisePredictor(self.W)
                    self.callbackfun.callback(self)

            v_init = np.array(self.Y).reshape(self.Y.shape[0])
            pko = pairwise_kernel_operator.PairwiseKernelOperator(
                X1, X2, self.input1_inds, self.input2_inds, None, None,
                weights)
            G = LinearOperator((pko.shape[1], pko.shape[1]),
                               matvec=mv,
                               dtype=np.float64)
            v_init = pko.rmatvec(v_init)
            '''if 'warm_start' in kwargs:
                x0 = np.array(kwargs['warm_start']).reshape(kronfcount, order = 'F')
            else:
                x0 = None'''
            minres(G, v_init, maxiter=maxiter, callback=cgcb, tol=1e-20
                   )  #[0].reshape((pko_T.shape[0], pko.shape[1]), order='F')
            self.predictor = LinearPairwisePredictor(self.W, self.input1_inds,
                                                     self.input2_inds, weights)
            if not self.callbackfun is None:
                self.callbackfun.finished(self)
Ejemplo n.º 4
0
    def solve(self, regparam):
        """Re-trains KronRLS for the given regparam
               
        Parameters
        ----------
        regparam : float, optional
            regularization parameter, regparam > 0

        Notes
        -----    
                
        Computational complexity of re-training:
        
        m = n_samples1, n = n_samples2, d = n_features1, e  = n_features2
        
        O(ed^2 + de^2) Linear version (assumption: d < m, e < n)
        
        O(m^3 + n^3) Kernel version
        """
        self.regparam = regparam
        if self.kernelmode:
            K1, K2 = self.K1, self.K2
            #assert self.Y.shape == (self.K1.shape[0], self.K2.shape[0]), 'Y.shape!=(K1.shape[0],K2.shape[0]). Y.shape=='+str(Y.shape)+', K1.shape=='+str(self.K1.shape)+', K2.shape=='+str(self.K2.shape)
            if not self.trained:
                self.trained = True
                evals1, V = la.eigh(K1)
                evals1 = np.mat(evals1).T
                V = np.mat(V)
                self.evals1 = evals1
                self.V = V

                evals2, U = la.eigh(K2)
                evals2 = np.mat(evals2).T
                U = np.mat(U)
                self.evals2 = evals2
                self.U = U
                self.VTYU = V.T * self.Y * U

            newevals = 1. / (self.evals1 * self.evals2.T + regparam)

            self.A = np.multiply(self.VTYU, newevals)
            self.A = self.V * self.A * self.U.T
            self.A = np.asarray(self.A)
            label_row_inds, label_col_inds = np.unravel_index(
                np.arange(K1.shape[0] * K2.shape[0]),
                (K1.shape[0], K2.shape[0]))
            label_row_inds = np.array(label_row_inds, dtype=np.int32)
            label_col_inds = np.array(label_col_inds, dtype=np.int32)
            self.predictor = KernelPairwisePredictor(self.A.ravel(),
                                                     label_row_inds,
                                                     label_col_inds)
        else:
            X1, X2 = self.X1, self.X2
            Y = self.Y.reshape((X1.shape[0], X2.shape[0]), order='F')
            if not self.trained:
                self.trained = True
                V, svals1, rsvecs1 = linalg.svd_economy_sized(X1)
                svals1 = np.mat(svals1)
                self.svals1 = svals1.T
                self.evals1 = np.multiply(self.svals1, self.svals1)
                self.V = V
                self.rsvecs1 = np.mat(rsvecs1)

                if X1.shape == X2.shape and (X1 == X2).all():
                    svals2, U, rsvecs2 = svals1, V, rsvecs1
                else:
                    U, svals2, rsvecs2 = linalg.svd_economy_sized(X2)
                    svals2 = np.mat(svals2)
                self.svals2 = svals2.T
                self.evals2 = np.multiply(self.svals2, self.svals2)
                self.U = U
                self.rsvecs2 = np.mat(rsvecs2)

                self.VTYU = V.T * Y * U

            kronsvals = self.svals1 * self.svals2.T

            newevals = np.divide(kronsvals,
                                 np.multiply(kronsvals, kronsvals) + regparam)
            self.W = np.multiply(self.VTYU, newevals)
            self.W = self.rsvecs1.T * self.W * self.rsvecs2
            self.predictor = LinearPairwisePredictor(
                np.array(self.W).ravel(order='F'))
Ejemplo n.º 5
0
    def __init__(self, **kwargs):
        Y = kwargs["Y"]
        self.input1_inds = np.array(kwargs["label_row_inds"], dtype=np.int32)
        self.input2_inds = np.array(kwargs["label_col_inds"], dtype=np.int32)
        Y = array_tools.as_2d_array(Y)
        self.Y = np.mat(Y)
        self.trained = False
        if "regparam" in kwargs:
            self.regparam = kwargs["regparam"]
        else:
            self.regparam = 0.
        if CALLBACK_FUNCTION in kwargs:
            self.callbackfun = kwargs[CALLBACK_FUNCTION]
        else:
            self.callbackfun = None
        if "compute_risk" in kwargs:
            self.compute_risk = kwargs["compute_risk"]
        else:
            self.compute_risk = False

        regparam = self.regparam
        if 'K1' in kwargs:

            K1 = kwargs['K1']
            K2 = kwargs['K2']

            if 'maxiter' in kwargs: maxiter = int(kwargs['maxiter'])
            else: maxiter = None

            Y = np.array(self.Y).ravel(order='F')
            self.bestloss = float("inf")

            def mv(v):
                return sampled_kronecker_products.sampled_vec_trick(
                    v, K2, K1, self.input2_inds, self.input1_inds,
                    self.input2_inds, self.input1_inds) + regparam * v

            def mv_mk(v):
                vsum = regparam * v
                for i in range(len(K1)):
                    K1i = K1[i]
                    K2i = K2[i]
                    inds2 = self.input2_inds[i]
                    inds1 = self.input1_inds[i]
                    vsum += weights[
                        i] * sampled_kronecker_products.sampled_vec_trick(
                            v, K2i, K1i, inds2, inds1, inds2, inds1)
                return vsum

            def mvr(v):
                raise Exception('You should not be here!')

            def cgcb(v):
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        v, K2, K1, self.input2_inds, self.input1_inds,
                        self.input2_inds, self.input1_inds)
                    z = (Y - P)
                    Ka = sampled_kronecker_products.sampled_vec_trick(
                        v, K2, K1, self.input2_inds, self.input1_inds,
                        self.input2_inds, self.input1_inds)
                    loss = (np.dot(z, z) + regparam * np.dot(v, Ka))
                    print("loss", 0.5 * loss)
                    if loss < self.bestloss:
                        self.A = v.copy()
                        self.bestloss = loss
                else:
                    self.A = v
                if not self.callbackfun is None:
                    self.predictor = KernelPairwisePredictor(
                        self.A, self.input1_inds, self.input2_inds)
                    self.callbackfun.callback(self)

            if isinstance(K1, (list, tuple)):
                if 'weights' in kwargs: weights = kwargs['weights']
                else: weights = np.ones((len(K1)))
                G = LinearOperator(
                    (len(self.input1_inds[0]), len(self.input1_inds[0])),
                    matvec=mv_mk,
                    rmatvec=mvr,
                    dtype=np.float64)
            else:
                weights = None
                G = LinearOperator(
                    (len(self.input1_inds), len(self.input1_inds)),
                    matvec=mv,
                    rmatvec=mvr,
                    dtype=np.float64)
            self.A = minres(G,
                            self.Y,
                            maxiter=maxiter,
                            callback=cgcb,
                            tol=1e-20)[0]
            self.predictor = KernelPairwisePredictor(self.A, self.input1_inds,
                                                     self.input2_inds, weights)
        else:
            X1 = kwargs['X1']
            X2 = kwargs['X2']
            self.X1, self.X2 = X1, X2

            if 'maxiter' in kwargs: maxiter = int(kwargs['maxiter'])
            else: maxiter = None

            if isinstance(X1, (list, tuple)):
                raise NotImplementedError(
                    "Got list or tuple as X1 but multiple kernel learning has not been implemented for the proal case yet."
                )
                x1tsize, x1fsize = X1[0].shape  #m, d
                x2tsize, x2fsize = X2[0].shape  #q, r
            else:
                x1tsize, x1fsize = X1.shape  #m, d
                x2tsize, x2fsize = X2.shape  #q, r

            kronfcount = x1fsize * x2fsize

            Y = np.array(self.Y).ravel(order='F')
            self.bestloss = float("inf")

            def mv(v):
                v_after = sampled_kronecker_products.sampled_vec_trick(
                    v, X2, X1, self.input2_inds, self.input1_inds)
                v_after = sampled_kronecker_products.sampled_vec_trick(
                    v_after, X2.T, X1.T, None, None, self.input2_inds,
                    self.input1_inds) + regparam * v
                return v_after

            def mv_mk(v):
                vsum = regparam * v
                for i in range(len(X1)):
                    X1i = X1[i]
                    X2i = X2[i]
                    v_after = sampled_kronecker_products.sampled_vec_trick(
                        v, X2i, X1i, self.input2_inds, self.input1_inds)
                    v_after = sampled_kronecker_products.sampled_vec_trick(
                        v_after, X2i.T, X1i.T, None, None, self.input2_inds,
                        self.input1_inds)
                    vsum = vsum + v_after
                return vsum

            def mvr(v):
                raise Exception('You should not be here!')
                return None

            def cgcb(v):
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        v, X2, X1, self.input2_inds, self.input1_inds)
                    z = (Y - P)
                    loss = (np.dot(z, z) + regparam * np.dot(v, v))
                    if loss < self.bestloss:
                        self.W = v.copy().reshape((x1fsize, x2fsize),
                                                  order='F')
                        self.bestloss = loss
                else:
                    self.W = v.reshape((x1fsize, x2fsize), order='F')
                if not self.callbackfun is None:
                    self.predictor = LinearPairwisePredictor(self.W)
                    self.callbackfun.callback(self)

            if isinstance(X1, (list, tuple)):
                G = LinearOperator((kronfcount, kronfcount),
                                   matvec=mv_mk,
                                   rmatvec=mvr,
                                   dtype=np.float64)
                vsum = np.zeros(kronfcount)
                v_init = np.array(self.Y).reshape(self.Y.shape[0])
                for i in range(len(X1)):
                    X1i = X1[i]
                    X2i = X2[i]
                    vsum += sampled_kronecker_products.sampled_vec_trick(
                        v_init, X2i.T, X1i.T, None, None, self.input2_inds,
                        self.input1_inds)
                v_init = vsum
            else:
                G = LinearOperator((kronfcount, kronfcount),
                                   matvec=mv,
                                   rmatvec=mvr,
                                   dtype=np.float64)
                v_init = np.array(self.Y).reshape(self.Y.shape[0])
                v_init = sampled_kronecker_products.sampled_vec_trick(
                    v_init, X2.T, X1.T, None, None, self.input2_inds,
                    self.input1_inds)

            v_init = np.array(v_init).reshape(kronfcount)
            if 'warm_start' in kwargs:
                x0 = np.array(kwargs['warm_start']).reshape(kronfcount,
                                                            order='F')
            else:
                x0 = None
            minres(G, v_init, x0=x0, maxiter=maxiter, callback=cgcb,
                   tol=1e-20)[0].reshape((x1fsize, x2fsize), order='F')
            self.predictor = LinearPairwisePredictor(self.W)
            if not self.callbackfun is None:
                self.callbackfun.finished(self)
Ejemplo n.º 6
0
    def solve(self, regparam1, regparam2):
        """Re-trains TwoStepRLS for the given regparams
               
        Parameters
        ----------
        regparam1: float
            regularization parameter 1, regparam1 > 0
        
        regparam2: float
            regularization parameter 2, regparam2 > 0
            
        Notes
        -----    
                
        Computational complexity of re-training:
        
        m = n_samples1, n = n_samples2, d = n_features1, e  = n_features2
        
        O(ed^2 + de^2) Linear version (assumption: d < m, e < n)
        
        O(m^3 + n^3) Kernel version
        """
        self.regparam1 = regparam1
        self.regparam2 = regparam2
        if self.kernelmode:
            K1, K2 = self.K1, self.K2
            Y = self.Y.reshape((K1.shape[0], K2.shape[0]), order='F')
            if not self.trained:
                self.trained = True
                evals1, V = linalg.eig_psd(K1)
                evals1 = np.mat(evals1).T
                evals1 = np.multiply(evals1, evals1)
                V = np.mat(V)
                self.evals1 = evals1
                self.V = V

                evals2, U = linalg.eig_psd(K2)
                evals2 = np.mat(evals2).T
                evals2 = np.multiply(evals2, evals2)
                U = np.mat(U)
                self.evals2 = evals2
                self.U = U
                self.VTYU = V.T * self.Y * U

            self.newevals1 = 1. / (self.evals1 + regparam1)
            self.newevals2 = 1. / (self.evals2 + regparam2)
            newevals = self.newevals1 * self.newevals2.T

            self.A = np.multiply(self.VTYU, newevals)
            self.A = self.V * self.A * self.U.T
            self.A = np.array(self.A)
            label_row_inds, label_col_inds = np.unravel_index(
                np.arange(K1.shape[0] * K2.shape[0]),
                (K1.shape[0], K2.shape[0]))
            label_row_inds = np.array(label_row_inds, dtype=np.int32)
            label_col_inds = np.array(label_col_inds, dtype=np.int32)
            self.predictor = KernelPairwisePredictor(self.A.ravel(),
                                                     label_row_inds,
                                                     label_col_inds)

        else:
            X1, X2 = self.X1, self.X2
            Y = self.Y.reshape((X1.shape[0], X2.shape[0]), order='F')
            if not self.trained:
                self.trained = True
                V, svals1, rsvecs1 = linalg.svd_economy_sized(X1)
                svals1 = np.mat(svals1)
                self.svals1 = svals1.T
                self.evals1 = np.multiply(self.svals1, self.svals1)
                self.V = V
                self.rsvecs1 = np.mat(rsvecs1)

                if X1.shape == X2.shape and (X1 == X2).all():
                    svals2, U, rsvecs2 = svals1, V, rsvecs1
                else:
                    U, svals2, rsvecs2 = linalg.svd_economy_sized(X2)
                    svals2 = np.mat(svals2)
                self.svals2 = svals2.T
                self.evals2 = np.multiply(self.svals2, self.svals2)
                self.U = U
                self.rsvecs2 = np.mat(rsvecs2)

                self.VTYU = V.T * Y * U

            self.newevals1 = 1. / (self.evals1 + regparam1)
            self.newevals2 = 1. / (self.evals2 + regparam2)
            newevals = np.multiply(self.svals1, self.newevals1) * np.multiply(
                self.svals2, self.newevals2).T

            self.W = np.multiply(self.VTYU, newevals)
            self.W = self.rsvecs1.T * self.W * self.rsvecs2
            #self.predictor = LinearPairwisePredictor(self.W)
            self.predictor = LinearPairwisePredictor(np.array(self.W))
Ejemplo n.º 7
0
    def __init__(self, **kwargs):
        self.Y = kwargs["Y"]
        #self.Y = array_tools.as_2d_array(Y)
        self.trained = False
        if "regparam" in kwargs:
            self.regparam = kwargs["regparam"]
        else:
            self.regparam = 0.
        regparam = self.regparam
        if CALLBACK_FUNCTION in kwargs:
            self.callbackfun = kwargs[CALLBACK_FUNCTION]
        else:
            self.callbackfun = None
        if "compute_risk" in kwargs:
            self.compute_risk = kwargs["compute_risk"]
        else:
            self.compute_risk = False

        if 'K1' in kwargs or 'pko' in kwargs:
            if 'pko' in kwargs:
                pko = kwargs['pko']
            else:
                self.input1_inds = np.array(kwargs["label_row_inds"],
                                            dtype=np.int32)
                self.input2_inds = np.array(kwargs["label_col_inds"],
                                            dtype=np.int32)
                K1 = kwargs['K1']
                K2 = kwargs['K2']
                if 'weights' in kwargs: weights = kwargs['weights']
                else: weights = None
                pko = pairwise_kernel_operator.PairwiseKernelOperator(
                    K1, K2, self.input1_inds, self.input2_inds,
                    self.input1_inds, self.input2_inds, weights)
            self.pko = pko
            if 'maxiter' in kwargs: maxiter = int(kwargs['maxiter'])
            else: maxiter = None

            Y = np.array(self.Y).ravel(order='F')
            self.bestloss = float("inf")

            def mv(v):
                return pko.matvec(v) + regparam * v

            def mvr(v):
                raise Exception('This function should not be called!')

            def cgcb(v):
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        v, K2, K1, self.input2_inds, self.input1_inds,
                        self.input2_inds, self.input1_inds)
                    z = (Y - P)
                    Ka = sampled_kronecker_products.sampled_vec_trick(
                        v, K2, K1, self.input2_inds, self.input1_inds,
                        self.input2_inds, self.input1_inds)
                    loss = (np.dot(z, z) + regparam * np.dot(v, Ka))
                    print("loss", 0.5 * loss)
                    if loss < self.bestloss:
                        self.A = v.copy()
                        self.bestloss = loss
                else:
                    self.A = v
                if not self.callbackfun is None:
                    self.predictor = KernelPairwisePredictor(
                        self.A, self.pko.col_inds_K1, self.pko.col_inds_K2,
                        self.pko.weights)
                    self.callbackfun.callback(self)

            G = LinearOperator((self.Y.shape[0], self.Y.shape[0]),
                               matvec=mv,
                               rmatvec=mvr,
                               dtype=np.float64)
            self.A = minres(G,
                            self.Y,
                            maxiter=maxiter,
                            callback=cgcb,
                            tol=1e-20)[0]
            self.predictor = KernelPairwisePredictor(self.A,
                                                     self.pko.col_inds_K1,
                                                     self.pko.col_inds_K2,
                                                     self.pko.weights)
        else:  #Primal case. Does not work with the operator interface yet.
            self.input1_inds = np.array(kwargs["label_row_inds"],
                                        dtype=np.int32)
            self.input2_inds = np.array(kwargs["label_col_inds"],
                                        dtype=np.int32)
            X1 = kwargs['X1']
            X2 = kwargs['X2']
            self.X1, self.X2 = X1, X2

            if 'maxiter' in kwargs: maxiter = int(kwargs['maxiter'])
            else: maxiter = None

            if isinstance(X1, (list, tuple)):
                raise NotImplementedError(
                    "Got list or tuple as X1 but multiple kernel learning has not been implemented for the primal case yet."
                )
                if 'weights' in kwargs: weights = kwargs['weights']
                else: weights = np.ones((len(X1)))
                x1tsize, x1fsize = X1[0].shape  #m, d
                x2tsize, x2fsize = X2[0].shape  #q, r
            else:
                weights = None
                x1tsize, x1fsize = X1.shape  #m, d
                x2tsize, x2fsize = X2.shape  #q, r

            kronfcount = x1fsize * x2fsize

            Y = np.array(self.Y).ravel(order='F')
            self.bestloss = float("inf")

            def mv(v):
                v_after = sampled_kronecker_products.sampled_vec_trick(
                    v, X2, X1, self.input2_inds, self.input1_inds)
                v_after = sampled_kronecker_products.sampled_vec_trick(
                    v_after, X2.T, X1.T, None, None, self.input2_inds,
                    self.input1_inds) + regparam * v
                return v_after

            def mvr(v):
                raise Exception('This function should not be called!')

            def cgcb(v):
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        v, X2, X1, self.input2_inds, self.input1_inds)
                    z = (Y - P)
                    loss = (np.dot(z, z) + regparam * np.dot(v, v))
                    if loss < self.bestloss:
                        self.W = v.copy().reshape((x1fsize, x2fsize),
                                                  order='F')
                        self.bestloss = loss
                else:
                    self.W = v.reshape((x1fsize, x2fsize), order='F')
                if not self.callbackfun is None:
                    self.predictor = LinearPairwisePredictor(self.W)
                    self.callbackfun.callback(self)

            G = LinearOperator((kronfcount, kronfcount),
                               matvec=mv,
                               rmatvec=mvr,
                               dtype=np.float64)
            v_init = np.array(self.Y).reshape(self.Y.shape[0])
            v_init = sampled_kronecker_products.sampled_vec_trick(
                v_init, X2.T, X1.T, None, None, self.input2_inds,
                self.input1_inds)

            v_init = np.array(v_init).reshape(kronfcount)
            if 'warm_start' in kwargs:
                x0 = np.array(kwargs['warm_start']).reshape(kronfcount,
                                                            order='F')
            else:
                x0 = None
            minres(G, v_init, x0=x0, maxiter=maxiter, callback=cgcb,
                   tol=1e-20)[0].reshape((x1fsize, x2fsize), order='F')
            self.predictor = LinearPairwisePredictor(self.W, self.input1_inds,
                                                     self.input2_inds, weights)
            if not self.callbackfun is None:
                self.callbackfun.finished(self)
Ejemplo n.º 8
0
    def __init__(self, **kwargs):
        self.resource_pool = kwargs
        Y = kwargs[TRAIN_LABELS]
        self.label_row_inds = np.array(kwargs["label_row_inds"],
                                       dtype=np.int32)
        self.label_col_inds = np.array(kwargs["label_col_inds"],
                                       dtype=np.int32)
        self.Y = Y
        self.trained = False
        if "regparam" in kwargs:
            self.regparam = kwargs["regparam"]
        else:
            self.regparam = 1.0
        if CALLBACK_FUNCTION in kwargs:
            self.callbackfun = kwargs[CALLBACK_FUNCTION]
        else:
            self.callbackfun = None
        if "compute_risk" in kwargs:
            self.compute_risk = kwargs["compute_risk"]
        else:
            self.compute_risk = False

        regparam = self.regparam

        if not 'K1' in self.resource_pool:
            self.regparam = regparam
            X1 = self.resource_pool['X1']
            X2 = self.resource_pool['X2']
            self.X1, self.X2 = X1, X2

            if 'maxiter' in self.resource_pool:
                maxiter = int(self.resource_pool['maxiter'])
            else:
                maxiter = 1000

            if 'inneriter' in self.resource_pool:
                inneriter = int(self.resource_pool['inneriter'])
            else:
                inneriter = 50

            x1tsize, x1fsize = X1.shape  #m, d
            x2tsize, x2fsize = X2.shape  #q, r

            label_row_inds = np.array(self.label_row_inds, dtype=np.int32)
            label_col_inds = np.array(self.label_col_inds, dtype=np.int32)

            Y = self.Y
            rowind = label_row_inds
            colind = label_col_inds
            lamb = self.regparam
            rowind = np.array(rowind, dtype=np.int32)
            colind = np.array(colind, dtype=np.int32)
            fdim = X1.shape[1] * X2.shape[1]
            w = np.zeros(fdim)
            #np.random.seed(1)
            #w = np.random.random(fdim)
            self.bestloss = float("inf")

            def mv(v):
                return hessian(w, v, X1, X2, Y, rowind, colind, lamb)

            for i in range(maxiter):
                g = gradient(w, X1, X2, Y, rowind, colind, lamb)
                G = LinearOperator((fdim, fdim),
                                   matvec=mv,
                                   rmatvec=mv,
                                   dtype=np.float64)
                self.best_residual = float("inf")
                self.w_new = qmr(G, g, tol=1e-10, maxiter=inneriter)[0]
                if np.all(w == w - self.w_new):
                    break
                w = w - self.w_new
                if self.compute_risk:
                    P = sampled_kronecker_products.sampled_vec_trick(
                        w, X1, X2, rowind, colind)
                    z = (1. - Y * P)
                    z = np.where(z > 0, z, 0)
                    loss = 0.5 * (np.dot(z, z) + lamb * np.dot(w, w))
                    if loss < self.bestloss:
                        self.W = w.reshape((x1fsize, x2fsize), order='F')
                        self.bestloss = loss
                else:
                    self.W = w.reshape((x1fsize, x2fsize), order='F')
                if self.callbackfun is not None:
                    self.callbackfun.callback(self)
            self.predictor = LinearPairwisePredictor(self.W)
        else:
            K1 = self.resource_pool['K1']
            K2 = self.resource_pool['K2']
            if 'maxiter' in self.resource_pool:
                maxiter = int(self.resource_pool['maxiter'])
            else:
                maxiter = 100
            if 'inneriter' in self.resource_pool:
                inneriter = int(self.resource_pool['inneriter'])
            else:
                inneriter = 1000
            label_row_inds = np.array(self.label_row_inds, dtype=np.int32)
            label_col_inds = np.array(self.label_col_inds, dtype=np.int32)

            Y = self.Y
            rowind = label_row_inds
            colind = label_col_inds
            lamb = self.regparam
            rowind = np.array(rowind, dtype=np.int32)
            colind = np.array(colind, dtype=np.int32)
            ddim = len(rowind)
            a = np.zeros(ddim)
            self.bestloss = float("inf")

            def func(a):
                P = sampled_kronecker_products.sampled_vec_trick(
                    a, K2, K1, colind, rowind, colind, rowind)
                z = (1. - Y * P)
                z = np.where(z > 0, z, 0)
                Ka = sampled_kronecker_products.sampled_vec_trick(
                    a, K2, K1, colind, rowind, colind, rowind)
                return 0.5 * (np.dot(z, z) + lamb * np.dot(a, Ka))

            def mv(v):
                rows = rowind[sv]
                cols = colind[sv]
                p = np.zeros(len(rowind))
                A = sampled_kronecker_products.sampled_vec_trick(
                    v, K2, K1, cols, rows, colind, rowind)
                p[sv] = A
                return p + lamb * v

            def mv_mk(v):
                rows = rowind[sv]
                cols = colind[sv]
                p = np.zeros(len(rowind))
                skpsum = np.zeros(len(sv))
                for i in range(len(K1)):
                    K1i = K1[i]
                    K2i = K2[i]
                    skpsum += weights[
                        i] * sampled_kronecker_products.sampled_vec_trick(
                            v, K2i, K1i, cols, rows, colind, rowind)
                p[sv] = skpsum
                return p + lamb * v

            def rv(v):
                rows = rowind[sv]
                cols = colind[sv]
                p = sampled_kronecker_products.sampled_vec_trick(
                    v[sv], K2, K1, colind, rowind, cols, rows)
                return p + lamb * v

            def rv_mk(v):
                rows = rowind[sv]
                cols = colind[sv]
                psum = np.zeros(len(v))
                for i in range(len(K1)):
                    K1i = K1[i]
                    K2i = K2[i]
                    psum += weights[
                        i] * sampled_kronecker_products.sampled_vec_trick(
                            v[sv], K2i, K1i, colind, rowind, cols, rows)
                return psum + lamb * v

            for i in range(maxiter):
                if isinstance(K1, (list, tuple)):
                    if 'weights' in kwargs: weights = kwargs['weights']
                    else: weights = np.ones((len(K1)))
                    A = LinearOperator((ddim, ddim),
                                       matvec=mv_mk,
                                       rmatvec=rv_mk,
                                       dtype=np.float64)
                    P = np.zeros(ddim)
                    for i in range(len(K1)):
                        K1i = K1[i]
                        K2i = K2[i]
                        prod_i = weights[
                            i] * sampled_kronecker_products.sampled_vec_trick(
                                a, K2i, K1i, colind, rowind, colind, rowind)
                        P += prod_i
                else:
                    weights = None
                    A = LinearOperator((ddim, ddim),
                                       matvec=mv,
                                       rmatvec=rv,
                                       dtype=np.float64)
                    P = sampled_kronecker_products.sampled_vec_trick(
                        a, K2, K1, colind, rowind, colind, rowind)
                z = (1. - Y * P)
                z = np.where(z > 0, z, 0)
                sv = np.nonzero(z)[0]
                B = np.zeros(P.shape)
                B[sv] = P[sv] - Y[sv]
                B = B + lamb * a
                #solve Ax = B
                self.a_new = qmr(A, B, tol=1e-10, maxiter=inneriter)[0]
                if np.all(a == a - self.a_new):
                    break
                a = a - self.a_new
                if self.compute_risk:
                    loss = func(a)
                    if loss < self.bestloss:
                        self.A = a
                        self.bestloss = loss
                else:
                    self.A = a
                self.predictor = KernelPairwisePredictor(a, rowind, colind)
                if self.callbackfun is not None:
                    self.callbackfun.callback(self)
            self.predictor = KernelPairwisePredictor(a, rowind, colind)
            if self.callbackfun is not None:
                self.callbackfun.finished(self)