Exemple #1
0
def dim_reduction_nrmesup(X, P, labels, params):

    K = X.shape[0]
    nc = X.shape[1]

    Sw = np.zeros((nc, nc))
    Sb = np.zeros((nc, nc))
    for i in range(K):
        ci = labels[i]
        for j in range(K):
            Ci, Cj = X[i, :, :], X[j, :, :]
            Sij = np.dot(invsqrtm(Ci), np.dot(Cj, invsqrtm(Ci)))
            if (i != j) & (labels[j] == ci):
                Sw = Sw + powm(logm(Sij), 2)
            if (i != j) & (labels[j] != ci):
                Sb = Sb + powm(logm(Sij), 2)

    M = np.dot(np.linalg.inv(Sw), Sb)
    g, U = np.linalg.eig(M)

    idx = g.argsort()[::-1]
    g = g[idx]
    U = U[:, idx]

    B, p = sp.linalg.polar(U)
    W = B[:, :P]

    return W
Exemple #2
0
 def _fit(self, X):
     Ri = self.reference_old
     Rf = self.reference_new
     A = sqrtm(Ri)
     B = sqrtm(np.dot(invsqrtm(Ri), np.dot(Rf, invsqrtm(Ri))))
     C = invsqrtm(Ri)
     W = np.dot(A, np.dot(B, C))
     self.transporter_ = W
Exemple #3
0
def egrad_function_pair_rie(M, M_tilde, Q):
    M_tilde_invsqrt = invsqrtm(M_tilde)
    M_sqrt = sqrtm(M)
    term_aux = np.dot(Q, np.dot(M, Q.T))
    term_aux = np.dot(M_tilde_invsqrt, np.dot(term_aux, M_tilde_invsqrt))
    return 4 * np.dot(np.dot(M_tilde_invsqrt, logm(term_aux)), np.dot(
        M_sqrt, Q))
Exemple #4
0
def dim_reduction_nrmelandmark(X, P, labels, params):

    K = X.shape[0]
    nc = X.shape[1]

    S = np.zeros((nc, nc))
    M = mean_riemann(X)
    for i in range(K):
        Ci = X[i, :, :]
        Sij = np.dot(invsqrtm(Ci), np.dot(M, invsqrtm(Ci)))
        S = S + powm(logm(Sij), 2)

    l, v = np.linalg.eig(S)
    idx = l.argsort()[::-1]
    l = l[idx]
    v = v[:, idx]

    W = v[:, :P]

    return W
Exemple #5
0
    def _transform(self, X):

        W = self.transporter_
        Ri = self.reference_old
        Rf = self.reference_new
        Nt = X.shape[0]

        # detect which kind of input : tangent vectors or cov matrices
        if self.tangent_old:
            # if tangent vectors are given, transform them back to covs
            # (easier to have tg vectors in the form of symmetric matrices later)
            X = untangent_space(X, Ri)

        # transform covariances to their tangent vectors with respect to Ri
        # (these tangent vectors are in the form of symmetric matrices)
        eta_i = np.zeros(X.shape)
        Ri_sqrt = sqrtm(Ri)
        Ri_invsqrt = invsqrtm(Ri)
        for i in range(Nt):
            Li = logm(np.dot(Ri_invsqrt, np.dot(X[i], Ri_invsqrt)))
            eta_i[i, :, :] = np.dot(Ri_sqrt, np.dot(Li, Ri_sqrt))

        # multiply the tangent vectors by the transport matrix W
        eta_f = np.zeros(X.shape)
        for i in range(Nt):
            eta_f[i, :, :] = np.dot(W, np.dot(eta_i[i], W.T))

        # transform tangent vectors to covariance matrices with respect to Rf
        Xnew = np.zeros(X.shape)
        Rf_sqrt = sqrtm(Rf)
        Rf_invsqrt = invsqrtm(Rf)
        for i in range(Nt):
            Ef = expm(np.dot(Rf_invsqrt, np.dot(eta_f[i], Rf_invsqrt)))
            Xnew[i, :, :] = np.dot(Rf_sqrt, np.dot(Ef, Rf_sqrt))

        # transform back to tangent vectors (flat form, not sym matrix) if needed
        if self.tangent_new:
            Xnew = tangent_space(Xnew, Rf)

        return Xnew
Exemple #6
0
def dim_reduction_nrmeuns(X, P, labels, params):

    K = X.shape[0]
    nc = X.shape[1]

    S = np.zeros((nc, nc))

    for i in range(K):
        for j in range(K):
            if i != j:
                Ci, Cj = X[i, :, :], X[j, :, :]
                Sij = np.dot(invsqrtm(Ci), np.dot(Cj, invsqrtm(Ci)))
                S = S + powm(logm(Sij), 2)

    l, v = np.linalg.eig(S)
    idx = l.argsort()[::-1]
    l = l[idx]
    v = v[:, idx]

    W = v[:, :P]

    return W
Exemple #7
0
 def transform(self, X):
     """
     Detect and remove dropped.
     """
     out = []
     for x in X:
         if np.sum(x) != 0:
             cov = np.cov(x)
             W = invsqrtm(cov)
             tmp = np.dot(W.T, x)
         else:
             tmp = x
         out.append(tmp)
     return np.array(out)
def mean_riemann_custom(covmats, mean_args):
    """
        A custom version of pyriemann.utils.mean.mean_riemann to handle singular matrices
        and I/O with regards to reducing samples classes.

        For function doc refer to the doc of pyriemann.utils.mean.mean_riemann.
    """

    # Taking arguments
    tol, maxiter, init, sample_weight = mean_args

    # init
    sample_weight = _get_sample_weight(sample_weight, covmats)
    Nt, Ne, Ne = covmats.shape
    if init is None:
        C = np.mean(covmats, axis=0)
    else:
        C = init
    k = 0
    nu = 1.0
    tau = np.finfo(np.float64).max
    crit = np.finfo(np.float64).max

    # stop when J<10^-9 or max iteration = 50
    while (crit > tol) and (k < maxiter) and (nu > tol):
        k = k + 1
        C12 = sqrtm(C)
        Cm12 = invsqrtm(C)
        J = np.zeros((Ne, Ne))

        for index in range(Nt):
            tmp = np.dot(np.dot(Cm12, covmats[index, :, :]), Cm12)
            with warnings.catch_warnings():
                warnings.filterwarnings('error')
                try:
                    J += sample_weight[index] * logm(tmp)
                except RuntimeWarning:
                    pass

        crit = np.linalg.norm(J, ord='fro')
        h = nu * crit
        C = np.dot(np.dot(C12, expm(nu * J)), C12)
        if h < tau:
            nu = 0.95 * nu
            tau = h
        else:
            nu = 0.5 * nu

    return C
def mean_riemann(covmats,
                 tol=10e-9,
                 maxiter=50,
                 init=None,
                 u_prime=lambda x: 1):

    Nt, Ne, Ne = covmats.shape
    if init is None:
        C = np.mean(covmats, axis=0)
    else:
        C = init
    k = 0
    nu = 1.0
    tau = np.finfo(np.float64).max
    crit = np.finfo(np.float64).max
    # stop when J<10^-9 or max iteration = 50
    while (crit > tol) and (k < maxiter) and (nu > tol):
        k = k + 1
        C12 = sqrtm(C)
        Cm12 = invsqrtm(C)
        J = np.zeros((Ne, Ne))

        for i in range(Nt):
            tmp = (Cm12 @ covmats[i, :, :]) @ Cm12
            if type(u_prime(1)) == list:
                J += logm(tmp) * u_prime(
                    distance_riemann(C, covmats[i, :, :])**2)[i] / Nt
            else:
                J += logm(tmp) * u_prime(
                    distance_riemann(C, covmats[i, :, :])**2) / Nt

        crit = np.linalg.norm(J, ord='fro')
        h = nu * crit
        C = np.dot(np.dot(C12, expm(nu * J)), C12)
        if h < tau:
            nu = 0.95 * nu
            tau = h
        else:
            nu = 0.5 * nu

    return C
Exemple #10
0
def power_means(C, p):
    phi = 0.375/np.abs(p)    
    K = len(C)
    n = C[0].shape[0]
    w = np.ones(K)
    w = w/(1.0*len(w))
    G = np.sum([wk*powm(Ck, p) for (wk,Ck) in zip(w,C)], axis=0)
    if p > 0:
        X = invsqrtm(G)    
    else:
        X = sqrtm(G)    
    zeta = 10e-10
    test = 10*zeta
    while test > zeta:
        H = np.sum([wk*powm(np.dot(X, np.dot(powm(Ck, np.sign(p)), X.T)), np.abs(p)) for (wk,Ck) in zip(w,C)], axis=0)   
        X = np.dot(powm(H, -phi), X)
        test = 1.0/np.sqrt(n) * np.linalg.norm(H - np.eye(n))
    if p > 0:
        P = np.dot(np.linalg.inv(X), np.linalg.inv(X.T))    
    else:
        P = np.dot(X.T, X)        
    return P
def exp_riemann(X, Y):
    """ exp_X(Y) = X exp(X^{-1}Y) = X^{1/2} exp(X^{-1/2} Y X^{-1/2}) X^{1/2}"""
    Xsqrt = sqrtm(X)
    Xinvsqrt = invsqrtm(X)
    return Xsqrt @ expm(Xinvsqrt @ Y @ Xinvsqrt) @ Xsqrt
Exemple #12
0
def transform_org2opt(source, target_train, target_test):

    target_opt_train = {}
    target_opt_test = {}

    target_opt_train['labels'] = target_train['labels']
    target_opt_test['labels'] = target_test['labels']

    # get cost matrix
    Cs = source['covs']
    ys = source['labels']
    Ct_train = target_train['covs']
    Ct_test = target_test['covs']
    M = np.zeros((len(Cs), len(Ct_train)))
    for i, Cs_i in enumerate(Cs):
        for j, Ct_j in enumerate(Ct_train):
            M[i, j] = distance_riemann(Cs_i, Ct_j)**2

    # get the transportation plan
    mu_s = distribution_estimation_uniform(Cs)
    mu_t = distribution_estimation_uniform(Ct_train)
    gamma = sinkhorn_lpl1_mm(mu_s, ys, mu_t, M, reg=1.0)

    # transport the target matrices (train)
    Ct_train_transported = np.zeros(Ct_train.shape)
    for j in range(len(Ct_train_transported)):
        Ct_train_transported[j] = mean_riemann(Cs, sample_weight=gamma[:, j])
    target_opt_train['covs'] = Ct_train_transported

    # transport the target matrices (test)
    D = np.zeros((len(Ct_test), len(Ct_train)))
    for k, Ct_k in enumerate(Ct_test):
        for l, Ct_l in enumerate(Ct_train):
            D[k, l] = distance_riemann(Ct_k, Ct_l)**2
    idx = np.argmin(D, axis=1)  # nearest neighbour to each target test matrix

    Ct_test_transported = np.zeros(Ct_test.shape)
    for i in range(len(Ct_test)):
        j = idx[i]

        Ci = Ct_test[i]
        Ri = Ct_train[j]
        Rf = Ct_train_transported[j]

        Ri_sqrt = sqrtm(Ri)
        Ri_invsqrt = invsqrtm(Ri)
        Li = logm(np.dot(Ri_invsqrt, np.dot(Ci, Ri_invsqrt)))
        eta_i = np.dot(Ri_sqrt, np.dot(Li, Ri_sqrt))

        Ri_Rf = geodesic_riemann(Rf, Ri, alpha=0.5)
        Ri_inv = np.linalg.inv(Ri)
        eta_f = np.dot(Ri_inv, np.dot(eta_i, Ri_inv))
        eta_f = np.dot(Ri_Rf, np.dot(eta_f, Ri_Rf))

        Rf_sqrt = sqrtm(Rf)
        Rf_invsqrt = invsqrtm(Rf)
        Ef = expm(np.dot(Rf_invsqrt, np.dot(eta_f, Rf_invsqrt)))
        Ct_test_transported[i] = np.dot(Rf_sqrt, np.dot(Ef, Rf_sqrt))

    target_opt_test['covs'] = Ct_test_transported

    return source, target_opt_train, target_opt_test
Exemple #13
0
def parallel_transport_covariance_matrix(C, R):

    return np.dot(invsqrtm(R), np.dot(C, invsqrtm(R)))
    def fit(self, data):
        '''
		Calculate average covariance matrices and return freatures of training data

		Parameters
		----------
		data: array, shape (n_tr_trial,n_channel,n_samples)
			input training time samples 
		
		Return  
		------
		train_feat: array, shape: if vectorized: (n_tr_trial,(n_temp x n_freq x n_riemann)
								  else 			 (n_tr_trial,n_temp , n_freq , n_riemann)
		'''

        n_tr_trial, n_channel, _ = data.shape
        self.n_channel = n_channel
        self.n_riemann = int((n_channel + 1) * n_channel / 2)

        cov_mat = np.zeros(
            (n_tr_trial, self.n_temp, self.n_freq, n_channel, n_channel))

        # calculate training covariance matrices
        for trial_idx in range(n_tr_trial):

            for temp_idx in range(self.n_temp):
                t_start, t_end = self.temp_windows[
                    temp_idx, 0], self.temp_windows[temp_idx, 1]
                n_samples = t_end - t_start

                for freq_idx in range(self.n_freq):
                    # filter signal
                    data_filter = butter_fir_filter(
                        data[trial_idx, :, t_start:t_end],
                        self.filter_bank[freq_idx])
                    # regularized covariance matrix
                    cov_mat[trial_idx, temp_idx,
                            freq_idx] = 1 / (n_samples - 1) * np.dot(
                                data_filter, np.transpose(data_filter)
                            ) + self.rho / n_samples * np.eye(n_channel)

        # calculate mean covariance matrix
        self.c_ref_invsqrtm = np.zeros((self.n_freq, n_channel, n_channel))

        for freq_idx in range(self.n_freq):

            if self.riem_opt == 'No_Adaptation':
                self.c_ref_invsqrtm[freq_idx] = np.eye(n_channel)
            else:
                # Mean covariance matrix over all trials and temp winds per frequency band
                cov_avg = mean.mean_covariance(cov_mat[:, :, freq_idx].reshape(
                    -1, n_channel, n_channel),
                                               metric=self.mean_metric)
                self.c_ref_invsqrtm[freq_idx] = base.invsqrtm(cov_avg)

        # calculate training features
        train_feat = np.zeros(
            (n_tr_trial, self.n_temp, self.n_freq, self.n_riemann))

        for trial_idx in range(n_tr_trial):
            for temp_idx in range(self.n_temp):
                for freq_idx in range(self.n_freq):

                    train_feat[trial_idx, temp_idx,
                               freq_idx] = self.riem_kernel(
                                   cov_mat[trial_idx, temp_idx, freq_idx],
                                   self.c_ref_invsqrtm[freq_idx])

        if self.vectorized:
            return train_feat.reshape(n_tr_trial, -1)
        else:
            return train_feat
def log_riemann(X, Y):
    """ log_X(Y) = X log(X^{-1}Y) = X^{1/2} log(X^{-1/2} Y X^{-1/2}) X^{1/2}"""
    Xsqrt = sqrtm(X)
    Xinvsqrt = invsqrtm(X)
    return Xsqrt @ logm(Xinvsqrt @ Y @ Xinvsqrt) @ Xsqrt
def score_ensemble_rot(settings, subject_target, ntop):

    dataset = settings['dataset']
    paradigm = settings['paradigm']
    session = settings['session']
    storage = settings['storage']
    filepath = '../results/' + dataset + '/TL_intra-subject_scores.pkl'
    acc_intra_dict = joblib.load(filepath)

    scores = []
    subject_sources = []
    for subject in settings['subject_list']:
        if subject == subject_target:
            continue
        else:
            scores.append(acc_intra_dict[subject])
            subject_sources.append(subject)
    scores = np.array(scores)

    subject_sources = np.array(subject_sources)
    idx_sort = scores.argsort()[::-1]
    scores = scores[idx_sort]
    subject_sources = subject_sources[idx_sort]
    subject_sources_ntop = subject_sources[:ntop]

    # get the geometric means for each subject (each class and also the center)
    filename = '../results/' + dataset + '/subject_means.pkl'
    subj_means = joblib.load(filename)

    # get the data for the target subject
    target_org = GD.get_dataset(dataset, subject_target, session, storage)
    if paradigm == 'MI':
        # things here are only implemented for MI for now
        target_org['covs'] = Covariances(estimator='oas').fit_transform(
            target_org['signals'])
        target_org['labels'] = target_org['labels']

    ncovs = settings['ncovs_list'][0]
    nrzt = 10
    score_rzt = 0.0
    for rzt in range(nrzt):

        # split randomly the target dataset
        target_org_train, target_org_test = get_target_split_motorimagery(
            target_org, ncovs)

        covs_train_target = target_org_train['covs']
        labs_train_target = target_org_train['labels']

        MC_target = mean_riemann(covs_train_target)
        M1_target = mean_riemann(
            covs_train_target[labs_train_target == 'left_hand'])
        M2_target = mean_riemann(
            covs_train_target[labs_train_target == 'right_hand'])
        M1_target_rct = np.dot(invsqrtm(MC_target),
                               np.dot(M1_target, invsqrtm(MC_target)))
        M2_target_rct = np.dot(invsqrtm(MC_target),
                               np.dot(M2_target, invsqrtm(MC_target)))
        covs_train_target = np.stack([M1_target_rct, M2_target_rct])
        labs_train_target = np.array(['left_hand', 'right_hand'])

        clf = []
        for subj_source in subject_sources_ntop:

            MC_source = subj_means[subj_source]['center']
            M1_source = subj_means[subj_source]['left_hand']
            M2_source = subj_means[subj_source]['right_hand']
            M1_source_rct = np.dot(invsqrtm(MC_source),
                                   np.dot(M1_source, invsqrtm(MC_source)))
            M2_source_rct = np.dot(invsqrtm(MC_source),
                                   np.dot(M2_source, invsqrtm(MC_source)))

            M = [M1_target_rct, M2_target_rct]
            Mtilde = [M1_source_rct, M2_source_rct]
            R = manifoptim.get_rotation_matrix(M, Mtilde)
            M1_source_rot = np.dot(R, np.dot(M1_source_rct, R.T))
            M2_source_rot = np.dot(R, np.dot(M2_source_rct, R.T))

            covs_train_source = np.stack([M1_source_rot, M2_source_rot])
            labs_train_source = np.array(['left_hand', 'right_hand'])

            covs_train = np.concatenate([covs_train_source, covs_train_target])
            labs_train = np.concatenate([labs_train_source, labs_train_target])
            clfi = MDM()

            # problems here when using integer instead of floats on the sample_weight
            clfi.fit(covs_train,
                     labs_train,
                     sample_weight=np.array(
                         [200.0, 200.0, 2.0 * ncovs, 2.0 * ncovs]))
            clf.append(clfi)

        covs_test = target_org_test['covs']
        labs_test = target_org_test['labels']

        ypred = []
        for clfi in clf:
            yi = clfi.predict(covs_test)
            ypred.append(yi)
        ypred = np.array(ypred)

        majorvoting = []
        for j in range(ypred.shape[1]):
            ypredj = ypred[:, j]
            values_unique, values_count = np.unique(ypredj, return_counts=True)
            majorvoting.append(values_unique[np.argmax(values_count)])
        majorvoting = np.array(majorvoting)

        score_rzt = score_rzt + np.mean(majorvoting == labs_test)

    score = score_rzt / nrzt

    return score
def test_invsqrtm():
    """Test matrix inverse square root"""
    C = 2*np.eye(3)
    Ctrue = (1.0/np.sqrt(2))*np.eye(3)
    assert_array_almost_equal(invsqrtm(C),Ctrue)
Exemple #18
0
def test_invsqrtm():
    """Test matrix inverse square root"""
    C = 2 * np.eye(3)
    Ctrue = (1.0 / np.sqrt(2)) * np.eye(3)
    assert_array_almost_equal(invsqrtm(C), Ctrue)
def score_pooling_rct(settings, subject_target, ntop):

    dataset = settings['dataset']
    paradigm = settings['paradigm']
    session = settings['session']
    storage = settings['storage']
    filepath = '../results/' + dataset + '/TL_intra-subject_scores.pkl'
    acc_intra_dict = joblib.load(filepath)

    scores = []
    subject_sources = []
    for subject in settings['subject_list']:
        if subject == subject_target:
            continue
        else:
            scores.append(acc_intra_dict[subject])
            subject_sources.append(subject)
    scores = np.array(scores)

    subject_sources = np.array(subject_sources)
    idx_sort = scores.argsort()[::-1]
    scores = scores[idx_sort]
    subject_sources = subject_sources[idx_sort]
    subject_sources_ntop = subject_sources[:ntop]

    # get the geometric means for each subject (each class and also the center)
    filename = '../results/' + dataset + '/subject_means.pkl'
    subj_means = joblib.load(filename)

    # get the data for the target subject
    target_org = GD.get_dataset(dataset, subject_target, session, storage)
    if paradigm == 'MI':
        # things here are only implemented for MI for now
        target_org['covs'] = Covariances(estimator='oas').fit_transform(
            target_org['signals'])
        target_org['labels'] = target_org['labels']

    ncovs = settings['ncovs_list'][0]
    score_rzt = 0.0
    nrzt = 10
    for rzt in range(nrzt):

        # split randomly the target dataset
        target_org_train, target_org_test = get_target_split_motorimagery(
            target_org, ncovs)

        # get the data from the sources and pool it all together
        class_mean_1 = []
        class_mean_2 = []
        for subj_source in subject_sources_ntop:
            MC_source = subj_means[subj_source]['center']
            M1_source = subj_means[subj_source]['left_hand']
            M2_source = subj_means[subj_source]['right_hand']
            M1_source_rct = np.dot(invsqrtm(MC_source),
                                   np.dot(M1_source, invsqrtm(MC_source)))
            class_mean_1.append(M1_source_rct)
            M2_source_rct = np.dot(invsqrtm(MC_source),
                                   np.dot(M2_source, invsqrtm(MC_source)))
            class_mean_2.append(M2_source_rct)
        class_mean_1_source = np.stack(class_mean_1)
        class_mean_2_source = np.stack(class_mean_2)
        covs_train_source = np.concatenate(
            [class_mean_1_source, class_mean_2_source])
        labs_train_source = np.concatenate([
            len(class_mean_1_source) * ['left_hand'],
            len(class_mean_2_source) * ['right_hand']
        ])

        # re-center data for the target
        covs_train_target = target_org['covs']
        MC_target = mean_riemann(covs_train_target)
        labs_train_target = target_org['labels']
        class_mean_1_target = mean_riemann(
            covs_train_target[labs_train_target == 'left_hand'])
        class_mean_1_target = np.dot(
            invsqrtm(MC_target),
            np.dot(class_mean_1_target, invsqrtm(MC_target)))
        class_mean_2_target = mean_riemann(
            covs_train_target[labs_train_target == 'right_hand'])
        class_mean_2_target = np.dot(
            invsqrtm(MC_target),
            np.dot(class_mean_2_target, invsqrtm(MC_target)))

        covs_train_target = np.stack(
            [class_mean_1_target, class_mean_2_target])
        labs_train_target = np.array(['left_hand', 'right_hand'])

        covs_train = np.concatenate([covs_train_source, covs_train_target])
        labs_train = np.concatenate([labs_train_source, labs_train_target])

        covs_test = target_org_test['covs']
        labs_test = target_org_test['labels']

        # do the classification
        clf = MDM()
        clf.fit(covs_train, labs_train)
        score_rzt = score_rzt + clf.score(covs_test, labs_test)

    score = score_rzt / nrzt

    return score