def test_cov2corr(): from brainiak.utils.utils import cov2corr import numpy as np cov = np.array([[4,3,0],[3,9,0],[0,0,1]]) corr = cov2corr(cov) assert np.isclose(corr, np.array([[1,0.5,0],[0.5,1,0],[0,0,1]])).all(),\ "Converting from covariance matrix to correlation incorrect"
def test_brsa_rudimentary(seeded_rng): """this test is super loose""" # this is Mingbo's synth example from the paper U = gen_U_nips2016_example() n_T = 150 n_V = 250 n_nureg = 5 spacecov_true = np.eye(n_V) timecov_true = np.diag(np.abs(norm.rvs(size=(n_T)))) tr, sz = gen_brsa_data_matnorm_model( U, n_T=n_T, n_V=n_V, n_nureg=n_nureg, space_cov=spacecov_true, time_cov=timecov_true, ) spacecov_model = CovIdentity(size=n_V) timecov_model = CovDiagonal(size=n_T) model_matnorm = MNRSA(time_cov=timecov_model, space_cov=spacecov_model) model_matnorm.fit(tr["Y"], tr["X"], naive_init=False) RMSE = np.mean((model_matnorm.C_ - cov2corr(tr["U"]))**2)**0.5 assert RMSE < 0.1 model_matnorm = MNRSA(time_cov=timecov_model, space_cov=spacecov_model) model_matnorm.fit(tr["Y"], tr["X"], naive_init=True) RMSE = np.mean((model_matnorm.C_ - cov2corr(tr["U"]))**2)**0.5 assert RMSE < 0.1
def run_experiment(par, input_path, outfile_path): mat = loadmat('%s/data_for_experiment.mat' % input_path) design = mat['design'] # if we have diff design by subj: if design.ndim == 3: design = design[par['subj_num']] data = mat['fmri'][0][par['subj_num']] fname = "%s/results_%s_s%i_%inureg.mat" % (outfile_path, par['method'], par['subj_num'], par['n_nureg']) if Path(fname).exists(): return if par['method'] == "naive": print("Running Naive RSA on subject %i!" % par['subj_num']) data = stats.zscore(data, axis=1, ddof=1) m = LinearRegression(fit_intercept=False) m.fit(design, data.T) C = np.corrcoef(m.coef_.T) U = np.cov(m.coef_.T) elif par['method'] == 'brsa': print("Running BRSA on subject %i!" % par['subj_num']) data = stats.zscore(data, axis=1, ddof=1) # for brsa: 1% number of voxels (min 10) n_nureg = np.max([data.shape[0] // 100, 10]) m = BRSA(n_nureg=n_nureg) m.fit(X=data.T, design=design) U = m.U_ C = cov2corr(m.U_) elif par['method'] == 'mnrsa': print("Running MNRSA on subject %i!" % par['subj_num']) # For mnrsa, zscore the whole thing but not by voxel # so that different voxels get to have different variances # but we don't blow out numerically data = stats.zscore(data, axis=None, ddof=1) n_V, n_T = data.shape spacecov_model = CovDiagonal(size=n_V) timecov_model = CovAR1(size=n_T) # n_nureg = design.shape[1] // 3 n_nureg = par['n_nureg'] model = MatnormBRSA(time_noise_cov=timecov_model, space_noise_cov=spacecov_model, optimizer='L-BFGS-B', n_nureg=n_nureg) model.fit(data.T, design) U = model.U_ C = model.C_ savemat(fname, { 'C': C, 'U': U, 'method': par['method'], 'subject': par['subj_num'] }) return
def fit(self, X, y, naive_init=True): """ Estimate dimension reduction and cognitive model parameters Parameters ---------- X: 2d array Brain data matrix (TRs by voxels). Y in the math y: 2d array or vector Behavior data matrix (TRs by behavioral obsevations). X in the math max_iter: int, default=1000 Maximum number of iterations to run step: int, default=100 Number of steps between optimizer output restart: bool, default=True If this is true, optimizer is restarted (e.g. for a new dataset). Otherwise optimizer will continue from where it is now (for example for running more iterations if the initial number was not enough). """ # In the method signature we follow sklearn discriminative API # where brain is X and behavior is y. Internally we are # generative so we flip this here X, Y = y, X self.n_c = X.shape[1] if naive_init: # initialize from naive RSA m = LinearRegression(fit_intercept=False) m.fit(X=X, y=Y) self.naive_U_ = np.cov(m.coef_.T) naiveRSA_L = np.linalg.cholesky(self.naive_U_) self.L_flat = tf.Variable(flatten_cholesky_unique(naiveRSA_L), name="L_flat", dtype="float64") else: chol_flat_size = (self.n_c * (self.n_c + 1)) // 2 self.L_flat = tf.Variable( tf.random.normal([chol_flat_size], dtype="float64"), name="L_flat", dtype="float64", ) self.train_variables.extend([self.L_flat]) def lossfn(theta): return -self.logp(X, Y) val_and_grad = make_val_and_grad(lossfn, self.train_variables) x0 = pack_trainable_vars(self.train_variables) opt_results = minimize(fun=val_and_grad, x0=x0, jac=True, method=self.optMethod, **self.optCtrl) unpacked_theta = unpack_trainable_vars(opt_results.x, self.train_variables) for var, val in zip(self.train_variables, unpacked_theta): var.assign(val) self.U_ = self.L.numpy().dot(self.L.numpy().T) self.C_ = cov2corr(self.U_)