def test_expectH(self): M = 51 J = 25 N = 325 D = 3 TR = 1. Thrf = 25. dt = .5 data = self.data_simu Gamma = np.identity(N) Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64) XGamma = np.zeros((M, D, N), dtype=np.float64) XX = np.zeros((M, N, D), dtype=np.int32) Y = data.bold P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] m_H = np.array(m_h) sigma_epsilone = np.ones(J) Sigma_H = np.ones((D, D), dtype=float) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.zeros((M, M, J), np.float64) scale = 1 order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2 * order) sigmaH = 0.1 UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH)
def test_max_sigma_noise(self): M = 51 N = 325 J = 25 TR = 1. Thrf = 25. dt = .5 data = self.data_simu X = OrderedDict([]) Y = data.bold onsets = data.get_joined_onsets() durations = data.paradigm.stimDurations P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) sigma_epsilone = np.ones(J) Gamma = np.identity(N) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.zeros((M, M, J), np.float64) m_H = np.array(m_h).astype(np.float64) D = len(m_H) Sigma_H = np.ones((D, D), dtype=np.float64) zerosMM = np.zeros((M, M), dtype=np.float64) _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N, D, TR, dt) sigma_eps = vt.maximization_noise_var(occurence_matrix, m_H, Sigma_H, m_A, Sigma_A, Gamma, Y, N)
def test_expectA(self): M = 51 K = 2 J = 25 N = 325 D = 3 TR = 1. Thrf = 25. dt = .5 data = self.data_simu Y = data.bold Onsets = data.get_joined_onsets() Gamma = np.identity(N) XX = np.zeros((M, N, D), dtype=np.int32) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] sigma_epsilone = np.ones(J) m_H = np.array(m_h) Sigma_H = np.ones((D, D), dtype=float) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.zeros((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) mu_M = np.zeros((M, K), dtype=np.float64) sigma_M = np.ones((M, K), dtype=np.float64) q_Z = np.zeros((M, K, J), dtype=np.float64) UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K)
def test_computeFit(self): X = OrderedDict([]) M = 51 N = 325 J = 25 Thrf = 25. dt = .5 TT, m_h = getCanoHRF(Thrf, dt) m_A = np.zeros((J, M), dtype=np.float64) m_H = np.array(m_h).astype(np.float64) stimIndSignal = vt.computeFit(m_H, m_A, X, J, N)
def test_max_sigmaH(self): D = 3 Thrf = 25. dt = .5 TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] m_H = np.array(m_h).astype(np.float64) Sigma_H = np.ones((D, D), dtype=np.float64) order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2*order) sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H)
def test_computeFit(self): X = OrderedDict([]) #for condition,Ons in Onsets.iteritems(): # X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) M = 51 N = 325 J = 25 Thrf=25. dt=.5 TT,m_h = getCanoHRF(Thrf,dt) m_A = np.zeros((J,M),dtype=np.float64) m_H = np.array(m_h).astype(np.float64) stimIndSignal = vt.computeFit(m_H, m_A, X, J, N)
def InitMatrixAndVectors(self, POI): """ initialize to zeros: X, y, P, l, h, InvR, Sigma initialize to ones: TauM, rb (<-scalar) requires: I / Ni / K / M / Qi """ logger.info('InitMatrixAndVectors ...') # HRFs (h) initialization: self.h[m][k] -> k^{th} HRF estimation value # for the condition m (oversampled time) # Warning: since the first and the last values of the HRFs = 0, # the nb of HRFs coefs allocated is K-1 self.h = numpy.zeros((self.M, self.K - 1), dtype=np.float32) hcano = getCanoHRF(dt=self.DeltaT, duration=self.K * self.DeltaT)[1] self.h[:] = hcano[1:self.K] logger.info('self.h:') logger.info(self.h) for i in xrange(self.I): self.P[i][:, :] = 0. # drifts coefs ('l') initialization: self.l[i][q] -> q^th coefficient for the the orthormal basis for session i # for i in xrange(self.I): # self.l[i,:] = 0. self.l[:, :, POI] = 0. # inverse of R self.InvR[:, :] = 0. # Sigma -> block matix => self.Sigma[m*SBS:(m+1)*SBS,n*SBS:(n+1)*SBS]] # -> (m,n)^th block of Sigma (variance a posteriori) SBS = self.K - 1 # Sigma Block Size self.Sigma = numpy.zeros( (self.M * SBS, self.M * SBS), dtype=np.float32) self.InvSigma = numpy.zeros( (self.M * SBS, self.M * SBS), dtype=np.float32) # TauM initialization: TauM[m] -> specific dynamics for condition m self.TauM = numpy.zeros(self.M, dtype=np.float32) + self.taum_init self.OldTauM = numpy.ones(self.M, dtype=np.float32) / 100. # rb initialization: self.rb[i] -> noise variance for i^th session self.rb = numpy.ones(self.I, dtype=np.float32) self.Old_rb = numpy.ones(self.I, dtype=np.float32)
def InitMatrixAndVectors(self, POI): """ initialize to zeros: X, y, P, l, h, InvR, Sigma initialize to ones: TauM, rb (<-scalar) requires: I / Ni / K / M / Qi """ logger.info('InitMatrixAndVectors ...') # HRFs (h) initialization: self.h[m][k] -> k^{th} HRF estimation value # for the condition m (oversampled time) # Warning: since the first and the last values of the HRFs = 0, # the nb of HRFs coefs allocated is K-1 self.h = numpy.zeros((self.M, self.K - 1), dtype=np.float32) hcano = getCanoHRF(dt=self.DeltaT, duration=self.K * self.DeltaT)[1] self.h[:] = hcano[1:self.K] logger.info('self.h:') logger.info(self.h) for i in xrange(self.I): self.P[i][:, :] = 0. # drifts coefs ('l') initialization: self.l[i][q] -> q^th coefficient for the the orthormal basis for session i # for i in xrange(self.I): # self.l[i,:] = 0. self.l[:, :, POI] = 0. # inverse of R self.InvR[:, :] = 0. # Sigma -> block matix => self.Sigma[m*SBS:(m+1)*SBS,n*SBS:(n+1)*SBS]] # -> (m,n)^th block of Sigma (variance a posteriori) SBS = self.K - 1 # Sigma Block Size self.Sigma = numpy.zeros((self.M * SBS, self.M * SBS), dtype=np.float32) self.InvSigma = numpy.zeros((self.M * SBS, self.M * SBS), dtype=np.float32) # TauM initialization: TauM[m] -> specific dynamics for condition m self.TauM = numpy.zeros(self.M, dtype=np.float32) + self.taum_init self.OldTauM = numpy.ones(self.M, dtype=np.float32) / 100. # rb initialization: self.rb[i] -> noise variance for i^th session self.rb = numpy.ones(self.I, dtype=np.float32) self.Old_rb = numpy.ones(self.I, dtype=np.float32)
def test_max_L(self): M = 51 N = 325 J = 25 TR = 1. Thrf=25. dt=.5 TT,m_h = getCanoHRF(Thrf,dt) m_A = np.zeros((J,M),dtype=np.float64) m_H = np.array(m_h).astype(np.float64) data = self.data_simu Y = data.bold X = OrderedDict([]) P = vt.PolyMat( N , 4 , TR) L = vt.polyFit(Y, TR, 4,P) zerosP = np.zeros((P.shape[0]),dtype=np.float64) L = vt.maximization_L(Y,m_A,X,m_H,L,P,zerosP)
def test_free_energy(self): """ Test of vem tool to compute free energy """ M = 51 D = 3 N = 325 J = 25 K = 2 TR = 1. Thrf=25. dt=.5 data = self.data_simu Y = data.bold graph = data.get_graph() P = vt.PolyMat( N , 4 , TR) L = vt.polyFit(Y, TR, 4,P) y_tilde = Y - np.dot(P,L) TT,m_h = getCanoHRF(Thrf,dt) order = 2 D2 = vt.buildFiniteDiffMatrix(order,D) R = np.dot(D2,D2) / pow(dt,2*order) invR = np.linalg.inv(R) Det_invR = np.linalg.det(invR) q_Z = np.zeros((M,K,J),dtype=np.float64) maxNeighbours = max([len(nl) for nl in graph]) neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32) Beta = np.ones((M),dtype=np.float64) sigma_epsilone = np.ones(J) XX = np.zeros((M,N,D),dtype=np.int32) Gamma = np.identity(N) Det_Gamma = np.linalg.det(Gamma) XGamma = np.zeros((M,D,N),dtype=np.float64) m_A = np.zeros((J,M),dtype=np.float64) Sigma_A = np.zeros((M,M,J),np.float64) mu_M = np.zeros((M,K),dtype=np.float64) sigma_M = np.ones((M,K),dtype=np.float64) m_H = np.array(m_h).astype(np.float64) Sigma_H = np.ones((D,D),dtype=np.float64) p_Wtilde = np.zeros((M,K),dtype=np.float64) p_Wtilde1 = np.zeros((M,K),dtype=np.float64) p_Wtilde[:,1] = 1 FreeEnergy = vt.Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M, m_H,Sigma_H,R,Det_invR,0.0,p_Wtilde, 0.0,0.0,q_Z,neighboursIndexes, maxNeighbours,Beta,sigma_epsilone, XX,Gamma,Det_Gamma,XGamma, J,M,D,N,2,100,"CompMod")
def test_free_energy(self): """ Test of vem tool to compute free energy """ M = 51 D = 3 N = 325 J = 25 K = 2 TR = 1. Thrf = 25. dt = .5 gamma_h = 1000 data = self.data_simu Y = data.bold graph = data.get_graph() onsets = data.paradigm.get_joined_onsets() durations = data.paradigm.stimDurations P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) y_tilde = Y - np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2*order) invR = np.linalg.inv(R) Det_invR = np.linalg.det(invR) q_Z = 0.5 * np.ones((M, K, J), dtype=np.float64) neighbours_indexes = vt.create_neighbours(graph) Beta = np.ones((M), dtype=np.float64) sigma_epsilone = np.ones(J) _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N, D, TR, dt) Gamma = np.identity(N) Det_Gamma = np.linalg.det(Gamma) XGamma = np.zeros((M, D, N), dtype=np.float64) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.zeros((M, M, J), np.float64) mu_M = np.zeros((M, K), dtype=np.float64) sigma_M = np.ones((M, K), dtype=np.float64) m_H = np.array(m_h[:D]).astype(np.float64) Sigma_H = np.ones((D, D), dtype=np.float64) free_energy = vt.free_energy_computation(m_A, Sigma_A, m_H, Sigma_H, D, q_Z, y_tilde, occurence_matrix, sigma_epsilone, Gamma, M, J, N, K, mu_M, sigma_M, neighbours_indexes, Beta, Sigma_H, np.linalg.inv(R), R, Det_Gamma, gamma_h)
def plot_estimation_results(fig_dir, poi, jde_roi, cond, plot_label, glm_fir_output_dir, rfir_output_dir, jde_output_dir, ymin=-1.55, ymax=1.05, plot_fontsize=25): ## HRF plots fn = op.join(glm_fir_output_dir, 'glm_fir_hrf.nii.gz') fir = xndarray.load(fn).sub_cuboid(condition=cond, **poi) #fir /= (fir**2).sum()**.5 fir /= fir.max() fn = op.join(rfir_output_dir, 'rfir_ehrf.nii.gz') rfir = xndarray.load(fn).sub_cuboid(condition=cond, **poi) #rfir /= (rfir**2).sum()**.5 rfir /= rfir.max() fn = op.join(jde_output_dir, 'jde_mcmc_hrf_pm.nii.gz') jde = xndarray.load(fn).sub_cuboid(ROI=jde_roi) jde /= jde.max() plt.figure() pargs = {'linewidth' : 2.7} plot_cub_as_curve(fir, show_axis_labels=False, plot_kwargs=pargs) plot_cub_as_curve(rfir, show_axis_labels=False, plot_kwargs=pargs) plot_cub_as_curve(jde, show_axis_labels=False, plot_kwargs=pargs) from pyhrf.boldsynth.hrf import getCanoHRF time_points, hcano = getCanoHRF() hcano /= hcano.max() plt.plot(time_points, hcano, 'k.-',linewidth=1.5) set_ticks_fontsize(plot_fontsize) plt.xlim(0,25) plt.ylim(ymin, ymax) plt.gca().xaxis.grid(True, 'major', linestyle='--', linewidth=1.2, color='gray') hrf_fig_fn = op.join(fig_dir, 'real_data_hrfs_%s.png' %plot_label) print 'hrf_fig_fn:', hrf_fig_fn plt.savefig(hrf_fig_fn) autocrop(hrf_fig_fn)
def test_max_L(self): M = 51 N = 325 J = 25 D = 3 TR = 1. Thrf = 25. dt = .5 TT, m_h = getCanoHRF(Thrf, dt) m_A = np.zeros((J, M), dtype=np.float64) m_H = np.array(m_h).astype(np.float64) data = self.data_simu Y = data.bold XX = np.zeros((M, N, D), dtype=np.int32) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) Ndrift = L.shape[0] zerosP = np.zeros((P.shape[0]), dtype=np.float64) UtilsC.maximization_L( Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
def test_max_L(self): M = 51 N = 325 J = 25 D = 3 TR = 1. Thrf = 25. dt = .5 TT, m_h = getCanoHRF(Thrf, dt) m_A = np.zeros((J, M), dtype=np.float64) m_H = np.array(m_h).astype(np.float64) data = self.data_simu Y = data.bold XX = np.zeros((M, N, D), dtype=np.int32) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) Ndrift = L.shape[0] zerosP = np.zeros((P.shape[0]), dtype=np.float64) UtilsC.maximization_L(Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
def test_max_L(self): M = 51 N = 325 J = 25 TR = 1. Thrf = 25. dt = .5 TT, m_h = getCanoHRF(Thrf, dt) m_A = np.zeros((J, M), dtype=np.float64) m_H = np.array(m_h).astype(np.float64) data = self.data_simu onsets = data.paradigm.get_joined_onsets() durations = data.paradigm.get_joined_durations() Y = data.bold X = OrderedDict([]) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) zerosP = np.zeros((P.shape[0]), dtype=np.float64) _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N, len(m_H), TR, dt) L = vt.maximization_drift_coeffs(Y, m_A, occurence_matrix, m_H, np.identity(N), P)
def test_expectA(self): M = 51 K = 2 J = 25 N = 325 D = 3 TR = 1. Thrf = 25. dt = .5 data = self.data_simu Y = data.bold Onsets = data.get_joined_onsets() durations = data.paradigm.stimDurations Gamma = np.identity(N) X = OrderedDict([]) for condition, Ons in Onsets.iteritems(): X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] sigma_epsilone = np.ones(J) m_H = np.array(m_h) Sigma_H = np.ones((D, D), dtype=float) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.ones((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01*np.identity(M) mu_M = np.zeros((M, K), dtype=np.float64) sigma_M = np.ones((M, K), dtype=np.float64) q_Z = 0.5 * np.ones((M, K, J), dtype=np.float64) zerosJMD = np.zeros((J, M, D), dtype=np.float64) _, occurence_matrix, _ = vt.create_conditions(Onsets, durations, M, N, D, TR, dt) m_A, Sigma_A = vt.nrls_expectation(m_H, m_A, occurence_matrix, Gamma, q_Z, mu_M, sigma_M, M, y_tilde, Sigma_A, Sigma_H, sigma_epsilone)
def test_expectH(self): M = 51 K = 2 J = 25 N = 325 D = 3 TR = 1. Thrf = 25. dt = .5 data = self.data_simu Gamma = np.identity(N) X = OrderedDict([]) Y = data.bold onsets = data.get_joined_onsets() durations = data.paradigm.stimDurations P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] m_H = np.array(m_h) sigma_epsilone = np.ones(J) Sigma_H = np.ones((D, D), dtype=float) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.zeros((M, M, J), np.float64) scale = 1 zerosDD = np.zeros((D, D), dtype=np.float64) zerosD = np.zeros((D), dtype=np.float64) zerosND = np.zeros((N, D), dtype=np.float64) order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2*order) sigmaH = 0.1 _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N, D, TR, dt) m_H, Sigma_H = vt.hrf_expectation(Sigma_A, m_A, occurence_matrix, Gamma, R, sigmaH, J, y_tilde, sigma_epsilone)
def trait(self): areas = ['ra'] labelFields = {} cNames = ['inactiv', 'activ'] height = self.data.getheight() width = self.data.getwidth() spConf = RegularLatticeMapping((height, width, 1)) graph = graph_from_lattice(ones((height, width, 1), dtype=int)) Y = self.data.post_lecture() J = Y.shape[0] l = int(sqrt(J)) FlagZ = 1 q_Z0 = zeros((self.scen.M, self.scen.K, J), dtype=float64) if not FlagZ: q_Z0 = q_Z FlagH = 1 TT, m_h = getCanoHRF(self.scen.Thrf - self.scen.dt, self.scen.dt) hrf0 = hrf0 = array(m_h).astype(float64) Sigma_H0 = eye(hrf0.shape[0]) if not FlagH: hrf0 = h_H Sigma_H0 = Sigma_H return Y, graph, hrf0, Sigma_H0, q_Z0, width, height, FlagZ, FlagH
def test_max_sigma_noise(self): M = 51 D = 3 N = 325 J = 25 TR = 1. Thrf=25. dt=.5 data = self.data_simu X = OrderedDict([]) Y = data.bold P = vt.PolyMat( N , 4 , TR) L = vt.polyFit(Y, TR, 4,P) PL = np.dot(P,L) TT,m_h = getCanoHRF(Thrf,dt) sigma_epsilone = np.ones(J) m_A = np.zeros((J,M),dtype=np.float64) Sigma_A = np.zeros((M,M,J),np.float64) m_H = np.array(m_h).astype(np.float64) Sigma_H = np.ones((D,D),dtype=np.float64) zerosMM = np.zeros((M,M),dtype=np.float64) sigma_eps = vt.maximization_sigma_noise(Y,X,m_A,m_H,Sigma_H,Sigma_A, PL,sigma_epsilone,M,zerosMM)
def test_max_sigma_noise(self): M = 51 D = 3 N = 325 J = 25 TR = 1. Thrf = 25. dt = .5 Gamma = np.identity(N) data = self.data_simu XX = np.zeros((M, N, D), dtype=np.int32) Y = data.bold P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) TT, m_h = getCanoHRF(Thrf, dt) sigma_epsilone = np.ones(J) m_A = np.zeros((J, M), dtype=np.float64) Sigma_A = np.zeros((M, M, J), np.float64) m_H = np.array(m_h).astype(np.float64) Sigma_H = np.ones((D, D), dtype=np.float64) UtilsC.maximization_sigma_noise(Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N)
def test_expectH(self): M = 51 K = 2 J = 25 N = 325 D = 3 TR = 1. Thrf=25. dt=.5 data = self.data_simu Gamma = np.identity(N) X = OrderedDict([]) Y = data.bold P = vt.PolyMat( N , 4 , TR) L = vt.polyFit(Y, TR, 4,P) PL = np.dot(P,L) y_tilde = Y - np.dot(P,L) TT,m_h = getCanoHRF(Thrf,dt) m_h = m_h[:D] m_H = np.array(m_h) sigma_epsilone = np.ones(J) Sigma_H = np.ones((D,D),dtype=float) m_A = np.zeros((J,M),dtype=np.float64) Sigma_A = np.zeros((M,M,J),np.float64) scale=1 zerosDD = np.zeros((D,D),dtype=np.float64) zerosD = np.zeros((D),dtype=np.float64) zerosND = np.zeros((N,D),dtype=np.float64) order = 2 D2 = vt.buildFiniteDiffMatrix(order,D) R = np.dot(D2,D2) / pow(dt,2*order) sigmaH = 0.1 Sigma_H, m_H = vt.expectation_H(Y,Sigma_A,m_A,X,Gamma,PL,D,R, sigmaH,J,N,y_tilde,zerosND, sigma_epsilone,scale,zerosDD, zerosD)
def test_matrix(self): Thrf = 25. dt = .5 TT, m_h = getCanoHRF(Thrf, dt) m_H = np.array(m_h) m = vt.mult(m_H, m_H)
def Main_vbjde_Python_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.1, NitMax=-1, NitMin=1, estimateBeta=False, PLOT=False): logger.info("EM started ...") np.random.seed(6537546) ########################################################################## # INITIALIZATIONS # Initialize parameters if NitMax < 0: NitMax = 100 gamma = 7.5 gradientStep = 0.005 MaxItGrad = 120 #Thresh = 1e-5 Thresh_FreeEnergy = 1e-5 # Initialize sizes vectors D = int(np.ceil(Thrf / dt)) M = len(Onsets) N = Y.shape[0] J = Y.shape[1] l = int(np.sqrt(J)) sigma_epsilone = np.ones(J) # Neighbours maxNeighbours = max([len(nl) for nl in graph]) neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32) neighboursIndexes -= 1 for i in xrange(J): neighboursIndexes[i, :len(graph[i])] = graph[i] # Conditions X = OrderedDict([]) for condition, Ons in Onsets.iteritems(): X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) XX = np.zeros((M, N, D), dtype=np.int32) nc = 0 for condition, Ons in Onsets.iteritems(): XX[nc, :, :] = X[condition] nc += 1 # Sigma and mu mu_M = np.zeros((M, K), dtype=np.float64) sigma_M = 0.5 * np.ones((M, K), dtype=np.float64) sigma_M0 = 0.5 * np.ones((M, K), dtype=np.float64) for k in xrange(1, K): mu_M[:, k] = 2.0 # Covariance matrix order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2 * order) Gamma = np.identity(N) q_Z = np.zeros((M, K, J), dtype=np.float64) # for k in xrange(0,K): q_Z[:, 1, :] = 1 q_Z1 = np.zeros((M, K, J), dtype=np.float64) Z_tilde = q_Z.copy() Sigma_A = np.zeros((M, M, J), np.float64) m_A = np.zeros((J, M), dtype=np.float64) TT, m_h = getCanoHRF(Thrf - dt, dt) # TODO: check for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_M[m, k], np.sqrt(sigma_M[m, k])) * Z_tilde[m, k, j] m_H = np.array(m_h).astype(np.float64) m_H1 = np.array(m_h) Sigma_H = np.ones((D, D), dtype=np.float64) Beta = beta * np.ones((M), dtype=np.float64) zerosDD = np.zeros((D, D), dtype=np.float64) zerosD = np.zeros((D), dtype=np.float64) zerosND = np.zeros((N, D), dtype=np.float64) zerosMM = np.zeros((M, M), dtype=np.float64) zerosJMD = np.zeros((J, M, D), dtype=np.float64) zerosK = np.zeros(K) P = vt.PolyMat(N, 4, TR) zerosP = np.zeros((P.shape[0]), dtype=np.float64) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - PL sigmaH1 = sigmaH Crit_H = 1 Crit_Z = 1 Crit_A = 1 cA = [] cH = [] cZ = [] Ndrift = L.shape[0] Crit_FreeEnergy = 1 t1 = time.time() ########################################################################## # VBJDE num. iter. minimum ni = 0 while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or ((Crit_H > Thresh) and (Crit_Z > Thresh) and (Crit_A > Thresh))) and (ni < NitMax))): logger.info("------------------------------ Iteration n° " + str(ni + 1) + " ------------------------------") ##################### # EXPECTATION ##################### # A logger.info("E A step ...") Sigma_A, m_A = vt.expectation_A( Y, Sigma_H, m_H, m_A, X, Gamma, PL, sigma_M, q_Z, mu_M, D, N, J, M, K, y_tilde, Sigma_A, sigma_epsilone, zerosJMD) m_A1 = m_A # crit A DIFF = np.abs(np.reshape(m_A, (M * J)) - np.reshape(m_A1, (M * J))) Crit_A = sum(DIFF) / len(np.where(DIFF != 0)) cA += [Crit_A] # H logger.info("E H step ...") Sigma_H, m_H = vt.expectation_H( Y, Sigma_A, m_A, X, Gamma, PL, D, R, sigmaH, J, N, y_tilde, zerosND, sigma_epsilone, scale, zerosDD, zerosD) m_H[0] = 0 m_H[-1] = 0 m_H1 = m_H # crit H Crit_H = np.abs(np.mean(m_H - m_H1) / np.mean(m_H)) cH += [Crit_H] # Z logger.info("E Z step ...") q_Z, Z_tilde = vt.expectation_Z( Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, graph, M, J, K, zerosK) # crit Z DIFF = np.abs( np.reshape(q_Z, (M * K * J)) - np.reshape(q_Z1, (M * K * J))) Crit_Z = sum(DIFF) / len(np.where(DIFF != 0)) cZ += [Crit_Z] q_Z1 = q_Z # Plotting HRF if PLOT and ni >= 0: import matplotlib.pyplot as plt plt.figure(M + 1) plt.plot(m_H) plt.hold(True) #################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateSigmaH: logger.info("M sigma_H step ...") sigmaH = (np.dot(vt.mult(m_H, m_H) + Sigma_H, R)).trace() sigmaH /= D # (mu,sigma) logger.info("M (mu,sigma) step ...") mu_M, sigma_M = vt.maximization_mu_sigma( mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A) # Drift L L = vt.maximization_L(Y, m_A, X, m_H, L, P, zerosP) PL = np.dot(P, L) y_tilde = Y - PL # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): Beta[m] = vt.maximization_beta( Beta[m], q_Z, Z_tilde, J, K, m, graph, gamma, neighboursIndexes, maxNeighbours) logger.info("End estimating beta") # logger.info(Beta) # Sigma noise logger.info("M sigma noise step ...") sigma_epsilone = vt.maximization_sigma_noise( Y, X, m_A, m_H, Sigma_H, Sigma_A, PL, sigma_epsilone, M, zerosMM) #### Computing Free Energy #### """ if ni > 0: FreeEnergy1 = FreeEnergy FreeEnergy = Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,m_H,Sigma_H,R,Det_invR,sigmaH,p_Wtilde,tau1,tau2,q_Z,neighboursIndexes,maxNeighbours,Beta,sigma_epsilone,XX,Gamma,Det_Gamma,XGamma,J,D,M,N,K,S,"CompMod") if ni > 0: Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1 FreeEnergy_Iter += [FreeEnergy] cFE += [Crit_FreeEnergy] """ # Update index ni += 1 t2 = time.time() ########################################################################## # PLOTS and SNR computation """FreeEnergyArray = np.zeros((ni),dtype=np.float64) for i in xrange(ni): FreeEnergyArray[i] = FreeEnergy_Iter[i] SUM_q_Z_array = np.zeros((M,ni),dtype=np.float64) mu1_array = np.zeros((M,ni),dtype=np.float64) h_norm_array = np.zeros((ni),dtype=np.float64) for m in xrange(M): for i in xrange(ni): SUM_q_Z_array[m,i] = SUM_q_Z[m][i] mu1_array[m,i] = mu1[m][i] h_norm_array[i] = h_norm[i] sigma_M = np.sqrt(np.sqrt(sigma_M)) """ Norm = np.linalg.norm(m_H) m_H /= Norm m_A *= Norm mu_M *= Norm sigma_M *= Norm sigma_M = np.sqrt(sigma_M) if PLOT and 0: import matplotlib.pyplot as plt import matplotlib font = {'size': 15} matplotlib.rc('font', **font) plt.savefig('./HRF_Iter_CompMod.png') plt.hold(False) plt.figure(2) plt.plot(cAH[1:-1], 'lightblue') plt.hold(True) plt.plot(cFE[1:-1], 'm') plt.hold(False) #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') ) plt.legend(('CAH', 'CFE')) plt.grid(True) plt.savefig('./Crit_CompMod.png') plt.figure(3) plt.plot(FreeEnergyArray) plt.grid(True) plt.savefig('./FreeEnergy_CompMod.png') plt.figure(4) for m in xrange(M): plt.plot(SUM_q_Z_array[m]) plt.hold(True) plt.hold(False) plt.savefig('./Sum_q_Z_Iter_CompMod.png') plt.figure(5) for m in xrange(M): plt.plot(mu1_array[m]) plt.hold(True) plt.hold(False) plt.savefig('./mu1_Iter_CompMod.png') plt.figure(6) plt.plot(h_norm_array) plt.savefig('./HRF_Norm_CompMod.png') Data_save = xndarray(h_norm_array, ['Iteration']) Data_save.save('./HRF_Norm_Comp.nii') CompTime = t2 - t1 cTimeMean = CompTime / ni logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str( int(CompTime // 60)), str(int(CompTime % 60))) # print "Computational time = " + str(int( CompTime//60 ) ) + " min " + # str(int(CompTime%60)) + " s" logger.info('mu_M: %f', mu_M) logger.info('sigma_M: %f', sigma_M) logger.info("sigma_H = %s" + str(sigmaH)) logger.info("Beta = %s" + str(Beta)) StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N) SNR = 20 * \ np.log( np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL)) SNR /= np.log(10.) logger.info('SNR comp = %f', SNR) return m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL
def Main_vbjde_Extension_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.05, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, contrasts=[], computeContrast=False, gamma_h=0, estimateHRF=True, TrueHrfFlag=False, HrfFilename='hrf.nii', estimateLabels=True, LabelsFilename='labels.nii', MFapprox=False, InitVar=0.5, InitMean=2.0, MiniVEMFlag=False, NbItMiniVem=5): # VBJDE Function for BOLD with contraints logger.info("Fast EM with C extension started ...") np.random.seed(6537546) ########################################################################## # INITIALIZATIONS # Initialize parameters tau1 = 0.0 tau2 = 0.0 S = 100 Init_sigmaH = sigmaH Nb2Norm = 1 NormFlag = False if NitMax < 0: NitMax = 100 gamma = 7.5 #gamma_h = 1000 gradientStep = 0.003 MaxItGrad = 200 Thresh = 1e-5 Thresh_FreeEnergy = 1e-5 estimateLabels = True # WARNING!! They should be estimated # Initialize sizes vectors D = int(np.ceil(Thrf / dt)) + 1 # D = int(np.ceil(Thrf/dt)) M = len(Onsets) N = Y.shape[0] J = Y.shape[1] l = int(np.sqrt(J)) condition_names = [] # Neighbours maxNeighbours = max([len(nl) for nl in graph]) neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32) neighboursIndexes -= 1 for i in xrange(J): neighboursIndexes[i, :len(graph[i])] = graph[i] # Conditions X = OrderedDict([]) for condition, Ons in Onsets.iteritems(): X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) condition_names += [condition] XX = np.zeros((M, N, D), dtype=np.int32) nc = 0 for condition, Ons in Onsets.iteritems(): XX[nc, :, :] = X[condition] nc += 1 # Covariance matrix order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2 * order) invR = np.linalg.inv(R) Det_invR = np.linalg.det(invR) Gamma = np.identity(N) Det_Gamma = np.linalg.det(Gamma) p_Wtilde = np.zeros((M, K), dtype=np.float64) p_Wtilde1 = np.zeros((M, K), dtype=np.float64) p_Wtilde[:, 1] = 1 Crit_H = 1 Crit_Z = 1 Crit_A = 1 Crit_AH = 1 AH = np.zeros((J, M, D), dtype=np.float64) AH1 = np.zeros((J, M, D), dtype=np.float64) Crit_FreeEnergy = 1 cA = [] cH = [] cZ = [] cAH = [] FreeEnergy_Iter = [] cTime = [] cFE = [] SUM_q_Z = [[] for m in xrange(M)] mu1 = [[] for m in xrange(M)] h_norm = [] h_norm2 = [] CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64) CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64) Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64) XGamma = np.zeros((M, D, N), dtype=np.float64) m1 = 0 for k1 in X: # Loop over the M conditions m2 = 0 for k2 in X: Q_barnCond[m1, m2, :, :] = np.dot( np.dot(X[k1].transpose(), Gamma), X[k2]) m2 += 1 XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma) m1 += 1 if MiniVEMFlag: logger.info("MiniVEM to choose the best initialisation...") """InitVar, InitMean, gamma_h = MiniVEM_CompMod(Thrf,TR,dt,beta,Y,K, gamma,gradientStep, MaxItGrad,D,M,N,J,S, maxNeighbours, neighboursIndexes, XX,X,R,Det_invR,Gamma, Det_Gamma, scale,Q_barnCond,XGamma, NbItMiniVem, sigmaH,estimateHRF)""" InitVar, InitMean, gamma_h = vt.MiniVEM_CompMod(Thrf, TR, dt, beta, Y, K, gamma, gradientStep, MaxItGrad, D, M, N, J, S, maxNeighbours, neighboursIndexes, XX, X, R, Det_invR, Gamma, Det_Gamma, p_Wtilde, scale, Q_barnCond, XGamma, tau1, tau2, NbItMiniVem, sigmaH, estimateHRF) sigmaH = Init_sigmaH sigma_epsilone = np.ones(J) logger.info( "Labels are initialized by setting active probabilities to ones ...") q_Z = np.zeros((M, K, J), dtype=np.float64) q_Z[:, 1, :] = 1 q_Z1 = np.zeros((M, K, J), dtype=np.float64) Z_tilde = q_Z.copy() # TT,m_h = getCanoHRF(Thrf-dt,dt) #TODO: check TT, m_h = getCanoHRF(Thrf, dt) # TODO: check m_h = m_h[:D] m_H = np.array(m_h).astype(np.float64) m_H1 = np.array(m_h) sigmaH1 = sigmaH if estimateHRF: Sigma_H = np.ones((D, D), dtype=np.float64) else: Sigma_H = np.zeros((D, D), dtype=np.float64) Beta = beta * np.ones((M), dtype=np.float64) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - PL Ndrift = L.shape[0] sigma_M = np.ones((M, K), dtype=np.float64) sigma_M[:, 0] = 0.5 sigma_M[:, 1] = 0.6 mu_M = np.zeros((M, K), dtype=np.float64) for k in xrange(1, K): mu_M[:, k] = InitMean Sigma_A = np.zeros((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) m_A = np.zeros((J, M), dtype=np.float64) m_A1 = np.zeros((J, M), dtype=np.float64) for j in xrange(0, J): for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_M[m, k], np.sqrt(sigma_M[m, k])) * q_Z[m, k, j] m_A1 = m_A t1 = time.time() ########################################################################## # VBJDE num. iter. minimum ni = 0 while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or (Crit_AH > Thresh)) and (ni < NitMax))): logger.info("------------------------------ Iteration n° " + str(ni + 1) + " ------------------------------") ##################### # EXPECTATION ##################### # A logger.info("E A step ...") UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K) val = np.reshape(m_A, (M * J)) val[np.where((val <= 1e-50) & (val > 0.0))] = 0.0 val[np.where((val >= -1e-50) & (val < 0.0))] = 0.0 # crit. A DIFF = np.reshape(m_A - m_A1, (M * J)) # To avoid numerical problems DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0 # To avoid numerical problems DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0 Crit_A = ( np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2 cA += [Crit_A] m_A1[:, :] = m_A[:, :] # HRF h if estimateHRF: ################################ # HRF ESTIMATION ################################ UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH) import cvxpy as cvx m, n = Sigma_H.shape Sigma_H_inv = np.linalg.inv(Sigma_H) zeros_H = np.zeros_like(m_H[:, np.newaxis]) # Construct the problem. PRIMAL h = cvx.Variable(n) expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv) objective = cvx.Minimize(expression) #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1] constraints = [ h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1] prob = cvx.Problem(objective, constraints) result = prob.solve(verbose=0, solver=cvx.CVXOPT) # Now we update the mean of h m_H_old = m_H Sigma_H_old = Sigma_H m_H = np.squeeze(np.array((h.value))) Sigma_H = np.zeros_like(Sigma_H) h_norm += [np.linalg.norm(m_H)] # print 'h_norm = ', h_norm # Plotting HRF if PLOT and ni >= 0: import matplotlib.pyplot as plt plt.figure(M + 1) plt.plot(m_H) plt.hold(True) else: if TrueHrfFlag: #TrueVal, head = read_volume(HrfFilename) TrueVal, head = read_volume(HrfFilename)[:, 0, 0, 0] print TrueVal print TrueVal.shape m_H = TrueVal # crit. h Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2 cH += [Crit_H] m_H1[:] = m_H[:] # crit. AH for d in xrange(0, D): AH[:, :, d] = m_A[:, :] * m_H[d] DIFF = np.reshape(AH - AH1, (M * J * D)) # To avoid numerical problems DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0 # To avoid numerical problems DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0 if np.linalg.norm(np.reshape(AH1, (M * J * D))) == 0: Crit_AH = 1000000000. else: Crit_AH = ( np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(AH1, (M * J * D)))) ** 2 cAH += [Crit_AH] AH1[:, :, :] = AH[:, :, :] # Z labels if estimateLabels: logger.info("E Z step ...") # WARNING!!! ParsiMod gives better results, but we need the other # one. if MFapprox: UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, neighboursIndexes.astype( np.int32), M, J, K, maxNeighbours) if not MFapprox: UtilsC.expectation_Z_ParsiMod_RVM_and_CompMod( Sigma_A, m_A, sigma_M, Beta, mu_M, q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours) else: logger.info("Using True Z ...") TrueZ = read_volume(LabelsFilename) for m in xrange(M): q_Z[m, 1, :] = np.reshape(TrueZ[0][:, :, :, m], J) q_Z[m, 0, :] = 1 - q_Z[m, 1, :] # crit. Z val = np.reshape(q_Z, (M * K * J)) val[np.where((val <= 1e-50) & (val > 0.0))] = 0.0 DIFF = np.reshape(q_Z - q_Z1, (M * K * J)) # To avoid numerical problems DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0 # To avoid numerical problems DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0 if np.linalg.norm(np.reshape(q_Z1, (M * K * J))) == 0: Crit_Z = 1000000000. else: Crit_Z = ( np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(q_Z1, (M * K * J)))) ** 2 cZ += [Crit_Z] q_Z1 = q_Z ##################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateHRF: if estimateSigmaH: logger.info("M sigma_H step ...") if gamma_h > 0: sigmaH = vt.maximization_sigmaH_prior( D, Sigma_H_old, R, m_H_old, gamma_h) else: sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H) logger.info('sigmaH = %s', str(sigmaH)) # (mu,sigma) logger.info("M (mu,sigma) step ...") mu_M, sigma_M = vt.maximization_mu_sigma( mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A) for m in xrange(M): SUM_q_Z[m] += [sum(q_Z[m, 1, :])] mu1[m] += [mu_M[m, 1]] # Drift L UtilsC.maximization_L( Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N) PL = np.dot(P, L) y_tilde = Y - PL # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): if MFapprox: Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype( np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep) if not MFapprox: #Beta[m] = UtilsC.maximization_beta(beta,q_Z[m,:,:].astype(np.float64),q_Z[m,:,:].astype(np.float64),J,K,neighboursIndexes.astype(int32),gamma,maxNeighbours,MaxItGrad,gradientStep) Beta[m] = UtilsC.maximization_beta_CB(beta, q_Z[m, :, :].astype( np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep) logger.info("End estimating beta") logger.info(Beta) # Sigma noise logger.info("M sigma noise step ...") UtilsC.maximization_sigma_noise( Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N) #### Computing Free Energy #### if ni > 0: FreeEnergy1 = FreeEnergy """FreeEnergy = vt.Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M, m_H,Sigma_H,R,Det_invR,sigmaH, p_Wtilde,q_Z,neighboursIndexes, maxNeighbours,Beta,sigma_epsilone, XX,Gamma,Det_Gamma,XGamma,J,D,M, N,K,S,"CompMod")""" FreeEnergy = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_M, sigma_M, m_H, Sigma_H, R, Det_invR, sigmaH, p_Wtilde, tau1, tau2, q_Z, neighboursIndexes, maxNeighbours, Beta, sigma_epsilone, XX, Gamma, Det_Gamma, XGamma, J, D, M, N, K, S, "CompMod") if ni > 0: Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1 FreeEnergy_Iter += [FreeEnergy] cFE += [Crit_FreeEnergy] # Update index ni += 1 t02 = time.time() cTime += [t02 - t1] t2 = time.time() ########################################################################## # PLOTS and SNR computation FreeEnergyArray = np.zeros((ni), dtype=np.float64) for i in xrange(ni): FreeEnergyArray[i] = FreeEnergy_Iter[i] SUM_q_Z_array = np.zeros((M, ni), dtype=np.float64) mu1_array = np.zeros((M, ni), dtype=np.float64) h_norm_array = np.zeros((ni), dtype=np.float64) for m in xrange(M): for i in xrange(ni): SUM_q_Z_array[m, i] = SUM_q_Z[m][i] mu1_array[m, i] = mu1[m][i] h_norm_array[i] = h_norm[i] if PLOT and 0: import matplotlib.pyplot as plt import matplotlib font = {'size': 15} matplotlib.rc('font', **font) plt.savefig('./HRF_Iter_CompMod.png') plt.hold(False) plt.figure(2) plt.plot(cAH[1:-1], 'lightblue') plt.hold(True) plt.plot(cFE[1:-1], 'm') plt.hold(False) #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') ) plt.legend(('CAH', 'CFE')) plt.grid(True) plt.savefig('./Crit_CompMod.png') plt.figure(3) plt.plot(FreeEnergyArray) plt.grid(True) plt.savefig('./FreeEnergy_CompMod.png') plt.figure(4) for m in xrange(M): plt.plot(SUM_q_Z_array[m]) plt.hold(True) plt.hold(False) #plt.legend( ('m=0','m=1', 'm=2', 'm=3') ) #plt.legend( ('m=0','m=1') ) plt.savefig('./Sum_q_Z_Iter_CompMod.png') plt.figure(5) for m in xrange(M): plt.plot(mu1_array[m]) plt.hold(True) plt.hold(False) plt.savefig('./mu1_Iter_CompMod.png') plt.figure(6) plt.plot(h_norm_array) plt.savefig('./HRF_Norm_CompMod.png') Data_save = xndarray(h_norm_array, ['Iteration']) Data_save.save('./HRF_Norm_Comp.nii') CompTime = t2 - t1 cTimeMean = CompTime / ni sigma_M = np.sqrt(np.sqrt(sigma_M)) logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str( int(CompTime // 60)), str(int(CompTime % 60))) # print "Computational time = " + str(int( CompTime//60 ) ) + " min " + str(int(CompTime%60)) + " s" # print "sigma_H = " + str(sigmaH) logger.info('mu_M: %f', mu_M) logger.info('sigma_M: %f', sigma_M) logger.info("sigma_H = %s" + str(sigmaH)) logger.info("Beta = %s" + str(Beta)) StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N) SNR = 20 * \ np.log( np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL)) SNR /= np.log(10.) logger.info("SNR = %d", SNR) return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal, FreeEnergyArray
def Main_vbjde_c_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, estimateSigmaG=True, sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, idx_first_tag=0, simulation=None, estimateH=True, estimateG=True, estimateA=True, estimateC=True, estimateZ=True, M_step=True, estimateNoise=True, estimateMP=True, estimateLA=True): """ Version modified by Lofti from Christine's version """ logger.info("Fast EM with C extension started ... " "Here is the stable version !") np.random.seed(6537546) #Initialize parameters #gamma_h = 7.5 #gamma_g = 7.5 D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets) N, J = Y.shape[0], Y.shape[1] if NitMax < 0: NitMax = 100 gamma = 7.5 gradientStep = 0.003 MaxItGrad = 200 Thresh = 1e-5 # Neighbours maxNeighbours, neighboursIndexes = EM.create_neighbours(graph, J) # Conditions X, XX = EM.create_conditions(Onsets, M, N, D, TR, dt) # Covariance matrix R = EM.covariance_matrix(2, D, dt) # Noise matrix Gamma = np.identity(N) # Noise initialization sigma_eps = np.ones(J) Crit_AH, Crit_CG = 1, 1 Crit_H, Crit_G, Crit_Z, Crit_A, Crit_C = 1, 1, 1, 1, 1 AH = np.zeros((J, M, D), dtype=np.float64) AH1 = np.zeros((J, M, D), dtype=np.float64) CG = np.zeros((J, M, D), dtype=np.float64) CG1 = np.zeros((J, M, D), dtype=np.float64) cTime = [] cAH, cCG = [], [] cA, cC, cH, cG, cZ = [], [], [], [], [] h_norm, g_norm = [], [] #Labels logger.info("Labels are initialized by setting active probabilities " "to ones ...") q_Z = np.zeros((M, K, J), dtype=np.float64) q_Z[:, 1, :] = 1 q_Z1 = np.zeros((M, K, J), dtype=np.float64) Z_tilde = copy.deepcopy(q_Z) # H and G TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] H = np.array(m_h).astype(np.float64) H1 = copy.deepcopy(H) Sigma_H = np.zeros((D, D), dtype=np.float64) G = copy.deepcopy(H) G1 = copy.deepcopy(H) Sigma_G = copy.deepcopy(Sigma_H) #m_H = np.array(m_h).astype(np.float64) #m_H1 = np.array(m_h) # others Beta = beta * np.ones((M), dtype=np.float64) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) Ndrift = L.shape[0] PL = np.dot(P, L) alpha = np.zeros((J), dtype=np.float64) w = np.ones((N)) w[idx_first_tag::2] = -1 w = - w W = np.diag(w) wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :]) y_tilde = Y - PL - wa # Parameters Gaussian mixtures sigma_Ma = np.ones((M, K), dtype=np.float64) sigma_Ma[:, 0] = 0.5 sigma_Ma[:, 1] = 0.6 mu_Ma = np.zeros((M, K), dtype=np.float64) for k in xrange(1, K): mu_Ma[:, k] = 1 sigma_Mc = copy.deepcopy(sigma_Ma) mu_Mc = copy.deepcopy(mu_Ma) # Params RLs Sigma_A = np.zeros((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) m_A = np.zeros((J, M), dtype=np.float64) m_A1 = np.zeros((J, M), dtype=np.float64) for j in xrange(0, J): for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_Ma[m, k], \ np.sqrt(sigma_Ma[m, k])) * q_Z[m, k, j] m_A1 = m_A Sigma_C = copy.deepcopy(Sigma_A) m_C1 = m_C = copy.deepcopy(m_A) Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64) XGamma = np.zeros((M, D, N), dtype=np.float64) XWGamma = np.zeros((M, D, N), dtype=np.float64) for m1, k1 in enumerate(X): # Loop over the M conditions for m2, k2 in enumerate(X): Q_barnCond[m1, m2, :, :] = np.dot(np.dot(X[k1].T, \ Gamma), X[k2]) XGamma[m1, :, :] = np.dot(X[k1].T, Gamma) XWGamma[m1, :, :] = np.dot(np.dot(X[k1].T, W), Gamma) sigma_eps = np.ones(J) # simulated values if not estimateH: H = H1 = simulation['primary_brf'] sigmaH = 20. if not estimateG: G = G1 = simulation['primary_prf'] sigmaG = 40. if not estimateA: A = simulation['brls'].T print 'shape BRLs: ', A.shape m_A = A if not estimateC: C = simulation['prls'].T print 'shape PRLs: ', C.shape m_C = C if not estimateZ: Z = np.reshape(simulation['labels_vol'], [2, 1, 400]) Z = np.append(Z, np.ones_like(Z), axis=1) print np.reshape(Z[0, 0, :], [20, 20]) if not estimateLA: alpha = np.mean(simulation['perf_baseline'], 0) L = simulation['drift_coeffs'] PL = np.dot(P, L) wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :]) y_tilde = Y - PL - wa if not estimateNoise: sigma_eps = np.mean(simulation['noise'], 0) if not estimateMP: mu_Ma = np.array([[0, 2.2], [0, 2.2]]) sigma_Ma = np.array([[.3, .3], [.3, .3]]) mu_Mc = np.array([[0, 1.6], [0, 1.6]]) sigma_Mc = np.array([[.3, .3], [.3, .3]]) t1 = time.time() ########################################################################## ############################################# VBJDE num. iter. minimum ni = 0 while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (ni < NitMax))): logger.info("------------------------------ Iteration n° " + \ str(ni + 1) + " ------------------------------") ##################### # EXPECTATION ##################### # A if estimateA: logger.info("E A step ...") UtilsC.expectation_A(q_Z, mu_Mc, sigma_Mc, PL, sigma_eps, Gamma, Sigma_H, Y, y_tilde, m_A, H, Sigma_A, XX.astype(np.int32), J, D, M, N, K) # crit. A DIFF = np.reshape(m_A - m_A1, (M * J)) Crit_A = (np.linalg.norm(DIFF) / \ np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2 cA += [Crit_A] m_A1[:, :] = m_A[:, :] # C if estimateC: logger.info("E C step ...") UtilsC.expectation_C(q_Z, mu_Mc, sigma_Mc, PL, sigma_eps, Gamma, Sigma_H, Y, y_tilde, m_A, H, Sigma_A, XX.astype(np.int32), J, D, M, N, K) # crit. C DIFF = np.reshape(m_C - m_C1, (M * J)) Crit_C = (np.linalg.norm(DIFF) / \ np.linalg.norm(np.reshape(m_C1, (M * J)))) ** 2 cC += [Crit_C] m_C1[:, :] = m_C[:, :] # HRF h if estimateH: logger.info("E H step ...") UtilsC.expectation_H(XGamma, Q_barnCond, sigma_eps, Gamma, R, Sigma_H, Y, y_tilde, m_A, H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH) #H = EM.constraint_norm1(m_H, Sigma_H) H = H / np.linalg.norm(H) print 'BRF ERROR = ', EM.error(H, simulation['primary_brf']) h_norm = np.append(h_norm, np.linalg.norm(H)) print 'h_norm = ', h_norm # crit. h Crit_H = (np.linalg.norm(H - H1) / np.linalg.norm(H1)) ** 2 cH += [Crit_H] H1[:] = H[:] # PRF g if estimateG: logger.info("E G step ...") UtilsC.expectation_G(XGamma, Q_barnCond, sigma_eps, Gamma, R, Sigma_H, Y, y_tilde, m_A, H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH) G = EM.constraint_norm1(G, Sigma_G) print 'PRF ERROR = ', EM.error(G, simulation['primary_prf']) g_norm = np.append(g_norm, np.linalg.norm(G)) print 'g_norm = ', g_norm # crit. g Crit_G = (np.linalg.norm(G - G1) / np.linalg.norm(G1)) ** 2 cG += [Crit_G] G1[:] = G[:] # crit. AH for d in xrange(0, D): AH[:, :, d] = m_A[:, :] * H[d] DIFF = np.reshape(AH - AH1, (M * J * D)) Crit_AH = (np.linalg.norm(DIFF) / \ (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2 cAH += [Crit_AH] AH1[:, :, :] = AH[:, :, :] # crit. CG for d in xrange(0, D): CG[:, :, d] = m_C[:, :] * G[d] DIFF = np.reshape(CG - CG1, (M * J * D)) Crit_CG = (np.linalg.norm(DIFF) / \ (np.linalg.norm(np.reshape(CG1, (M * J * D))) + eps)) ** 2 cCG += [Crit_CG] CG1[:, :, :] = CG[:, :, :] # Z labels if estimateZ: logger.info("E Z step ...") UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours) # crit. Z DIFF = np.reshape(q_Z - q_Z1, (M * K * J)) Crit_Z = (np.linalg.norm(DIFF) / \ (np.linalg.norm(np.reshape(q_Z1, (M * K * J))) + eps)) ** 2 cZ += [Crit_Z] q_Z1[:, :, :] = q_Z[:, :, :] ##################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateSigmaH: logger.info("M sigma_H step ...") if gamma_h > 0: sigmaH = EM.maximization_sigma_prior(D, Sigma_H, R, H, gamma_h) else: sigmaH = EM.maximization_sigma(D, Sigma_H, R, H) logger.info('sigmaH = %s', str(sigmaH)) # PRF: Sigma_g if estimateSigmaG: logger.info("M sigma_G step ...") if gamma_g > 0: sigmaG = vt.maximization_sigma_prior(D, Sigma_G, R, G, gamma_g) else: sigmaG = vt.maximization_sigma(D, Sigma_G, R, G) logger.info('sigmaG = %s', str(sigmaG)) # (mu_a,sigma_a) if estimateMP: logger.info("M (mu_a,sigma_a) step ...") mu_Ma, sigma_Ma = vt.maximization_mu_sigma(mu_Ma, sigma_Ma, q_Z, m_A, K, M, Sigma_A) # (mu_c,sigma_c) logger.info("M (mu_c,sigma_c) step ...") mu_Mc, sigma_Mc = vt.maximization_mu_sigma(mu_Mc, sigma_Mc, q_Z, m_A, K, M, Sigma_A) # Drift L if estimateLA: UtilsC.maximization_L(Y, m_A, H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N) PL = np.dot(P, L) y_tilde = Y - PL # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): Beta[m] = UtilsC.maximization_beta(beta, \ q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype(np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep) logger.info("End estimating beta") logger.info(Beta) # Sigma noise if estimateNoise: logger.info("M sigma noise step ...") UtilsC.maximization_sigma_noise(Gamma, PL, sigma_eps, Sigma_H, Y, m_A, H, Sigma_A, XX.astype(np.int32), J, D, M, N) t02 = time.time() cTime += [t02 - t1] t2 = time.time() ########################################################################### ########################################### PLOTS and SNR computation CompTime = t2 - t1 cTimeMean = CompTime / ni if 0: Norm = np.linalg.norm(H) H /= Norm Sigma_H /= Norm ** 2 sigmaH /= Norm ** 2 m_A *= Norm Sigma_A *= Norm ** 2 mu_Ma *= Norm sigma_Ma *= Norm ** 2 sigma_Ma = np.sqrt(np.sqrt(sigma_Ma)) Norm = np.linalg.norm(G) G /= Norm Sigma_G /= Norm ** 2 sigmaG /= Norm ** 2 m_C *= Norm Sigma_C *= Norm ** 2 mu_Mc *= Norm sigma_Mc *= Norm ** 2 sigma_Mc = np.sqrt(np.sqrt(sigma_Mc)) logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str(np.int(CompTime // 60)), str(np.int(CompTime % 60))) StimulusInducedSignal = vt.computeFit(H, m_A, X, J, N) SNR = 20 * np.log(np.linalg.norm(Y) / \ np.linalg.norm(Y - StimulusInducedSignal - PL)) SNR /= np.log(10.) logger.info('mu_Ma: %f', mu_Ma) logger.info('sigma_Ma: %f', sigma_Ma) logger.info("sigma_H = %s" + str(sigmaH)) logger.info("Beta = %s" + str(Beta)) logger.info('SNR comp = %f', SNR) return ni, m_A, H, q_Z, sigma_eps, mu_Ma, sigma_Ma, Beta, L, PL, \ cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], \ cTimeMean, Sigma_A, StimulusInducedSignal
def Main_vbjde_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, estimateSigmaG=True, sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, idx_first_tag=0, simulation=None, estimateH=True, estimateG=True, estimateA=True, estimateC=True, estimateZ=True, estimateNoise=True, estimateMP=True, estimateLA=True): """ Version modified by Lofti from Christine's version """ logger.info("EM for ASL!") np.random.seed(6537546) # Initialization gamma_h = 1000000000 #7.5 gamma_g = 1000000000 #7.5 gamma = 0.0000000001 beta = 100 Thresh = 1e-5 D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets) N, J = Y.shape[0], Y.shape[1] Crit_AH, Crit_CG = 1, 1 AH = np.zeros((J, M, D), dtype=np.float64) AH1 = np.zeros((J, M, D), dtype=np.float64) CG = np.zeros((J, M, D), dtype=np.float64) CG1 = np.zeros((J, M, D), dtype=np.float64) cTime = [] cZ = [] cAH = [] cCG = [] h_norm = [] g_norm = [] SUM_q_Z = [[] for m in xrange(M)] mua1 = [[] for m in xrange(M)] muc1 = [[] for m in xrange(M)] # Neighbours maxNeighbours, neighboursIndexes = EM.create_neighbours(graph, J) # Conditions X, XX = EM.create_conditions(Onsets, M, N, D, TR, dt) # Covariance matrix R = EM.covariance_matrix(2, D, dt) # Noise matrix Gamma = np.identity(N) # Noise initialization sigma_eps = np.ones(J) #Labels logger.info("Labels are initialized by setting active probabilities " "to ones ...") q_Z = np.zeros((M, K, J), dtype=np.float64) q_Z[:, 1, :] = 1 q_Z1 = copy.deepcopy(q_Z) Z_tilde = copy.deepcopy(q_Z) # H and G TT, m_h = getCanoHRF(Thrf, dt) m_h = m_h[:D] H = np.array(m_h).astype(np.float64) Ht = copy.deepcopy(H) Sigma_H = np.zeros((D, D), dtype=np.float64) G = copy.deepcopy(H) Gt = copy.deepcopy(H) Sigma_G = copy.deepcopy(Sigma_H) # others Beta = beta * np.ones((M), dtype=np.float64) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) alpha = np.zeros((J), dtype=np.float64) w = np.ones((N)) w[idx_first_tag::2] = -1 w = - w W = np.diag(w) wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :]) y_tilde = Y - PL - wa # Parameters Gaussian mixtures sigma_Ma = np.ones((M, K), dtype=np.float64) sigma_Ma[:, 0] = 0.5 sigma_Ma[:, 1] = 0.6 mu_Ma = np.zeros((M, K), dtype=np.float64) for k in xrange(1, K): mu_Ma[:, k] = 1 sigma_Mc = copy.deepcopy(sigma_Ma) mu_Mc = copy.deepcopy(mu_Ma) # Params RLs Sigma_A = np.zeros((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) m_A = np.zeros((J, M), dtype=np.float64) for j in xrange(0, J): for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_Ma[m, k], \ np.sqrt(sigma_Ma[m, k])) * q_Z[m, k, j] Sigma_C = copy.deepcopy(Sigma_A) m_C = copy.deepcopy(m_A) if simulation is not None: #print simulation # simulated values if not estimateH: H = Ht = simulation['brf'][:, 0] sigmaH = 20. if not estimateG: G = Gt = simulation['prf'][:, 0] sigmaG = 40. A = simulation['brls'].T if not estimateA: m_A = A C = simulation['prls'].T if not estimateC: m_C = C Z = simulation['labels'] Z = np.append(Z[:, np.newaxis, :], Z[:, np.newaxis, :], axis=1) #Z[:, 1, :] = 1 if not estimateZ: q_Z = copy.deepcopy(Z) Z_tilde = copy.deepcopy(Z) if not estimateLA: alpha = np.mean(simulation['perf_baseline'], 0) L = simulation['drift_coeffs'] PL = np.dot(P, L) wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :]) y_tilde = Y - PL - wa if not estimateNoise: sigma_eps = np.var(simulation['noise'], 0) if not estimateMP: #print simulation['condition_defs'][0] mu_Ma = np.array([[0, 2.2], [0, 2.2]]) sigma_Ma = np.array([[.3, .3], [.3, .3]]) mu_Mc = np.array([[0, 1.6], [0, 1.6]]) sigma_Mc = np.array([[.3, .3], [.3, .3]]) #print simulation['condition_defs'][0] #print simulation['condition_defs'][0] #sigmaH = 0.0001 #sigmaG = 0.0001 ########################################################################### ############################################# VBJDE t1 = time.time() ni = 0 while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (Crit_CG > Thresh) \ and (ni < NitMax))): logger.info("-------- Iteration n° " + str(ni + 1) + " ---------") ##################### # EXPECTATION ##################### # HRF H logger.info("E H step ...") if estimateH: logger.info("estimation") #sigmaH = 0.0001 print sigmaH Ht, Sigma_H = EM.expectation_H(Sigma_A, m_A, m_C, G, X, W, Gamma, D, J, N, y_tilde, sigma_eps, scale, R, sigmaH) H = EM.constraint_norm1_b(Ht, Sigma_H) #H = Ht / np.linalg.norm(Ht) print 'BRF ERROR = ', EM.error(H, simulation['brf'][:, 0]) h_norm = np.append(h_norm, np.linalg.norm(H)) print 'h_norm = ', h_norm # PRF G logger.info("E G step ...") if estimateG: logger.info("estimation") Gt, Sigma_G = EM.expectation_G(Sigma_C, m_C, m_A, H, X, W, Gamma, D, J, N, y_tilde, sigma_eps, scale, R, sigmaG) G = EM.constraint_norm1_b(Gt, Sigma_G, positivity=True, perfusion=alpha) #G = Gt / np.linalg.norm(Gt) print 'PRF ERROR = ', EM.error(G, simulation['prf'][:, 0]) g_norm = np.append(g_norm, np.linalg.norm(G)) print 'g_norm = ', g_norm # A logger.info("E A step ...") if estimateA: logger.info("estimation") m_A, Sigma_A = EM.expectation_A(H, m_A, G, m_C, W, X, Gamma, q_Z, mu_Ma, sigma_Ma, D, J, M, K, y_tilde, Sigma_A, sigma_eps) print 'BRLS ERROR = ', EM.error(m_A, A) # C logger.info("E C step ...") if estimateC: logger.info("estimation") m_C, Sigma_C = EM.expectation_C(G, m_C, H, m_A, W, X, Gamma, q_Z, mu_Mc, sigma_Mc, D, J, M, K, y_tilde, Sigma_C, sigma_eps) #print 'true values: ', C #print 'estimated values: ', m_C print 'PRLS ERROR = ', EM.error(m_C, C) # Q labels logger.info("E Z step ...") if estimateZ: logger.info("estimation") q_Z, Z_tilde = EM.expectation_Z(Sigma_A, m_A, Sigma_C, m_C, sigma_Ma, mu_Ma, sigma_Mc, mu_Mc, Beta, Z_tilde, q_Z, graph, M, J, K) #print 'LABELS ERROR = ', EM.error(q_Z, Z) # crit. Z Crit_Z = (np.linalg.norm((q_Z - q_Z1).flatten()) / \ (np.linalg.norm(q_Z1).flatten() + eps)) ** 2 cZ += [Crit_Z] q_Z1 = q_Z # crit. AH and CG for d in xrange(0, D): AH[:, :, d] = m_A[:, :] * H[d] CG[:, :, d] = (m_C[:, :] * G[d]) Crit_AH = (np.linalg.norm(np.reshape(AH - AH1, (M * J * D))) / \ (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2 cAH += [Crit_AH] AH1 = AH Crit_CG = (np.linalg.norm(np.reshape(CG - CG1, (M * J * D))) / \ (np.linalg.norm(np.reshape(CG1, (M * J * D))) + eps)) ** 2 cCG += [Crit_CG] CG1 = CG if PLOT and ni >= 0: # Plotting HRF and PRF import matplotlib.pyplot as plt plt.figure(M + 1) plt.plot(H) plt.hold(True) plt.figure(M + 2) plt.plot(G) plt.hold(True) ##################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateSigmaH: logger.info("M sigma_H step ...") print gamma_h sigmaH = EM.maximization_sigma_prior(D, R, H, gamma_h) logger.info('sigmaH = ' + str(sigmaH)) # PRF: Sigma_g if estimateSigmaG: logger.info("M sigma_G step ...") sigmaG = EM.maximization_sigma_prior(D, R, G, gamma_g) logger.info('sigmaG = ' + str(sigmaG)) # (mu,sigma) if estimateMP: logger.info("M (mu,sigma) a and c step ...") Mu_Ma, sigma_Ma = EM.maximization_mu_sigma(mu_Ma, sigma_Ma, q_Z, m_A, K, M, Sigma_A) mu_Mc, sigma_Mc = EM.maximization_mu_sigma(mu_Mc, sigma_Mc, q_Z, m_C, K, M, Sigma_C) # Drift L, alpha if estimateLA: L, alpha = EM.maximization_L_alpha(Y, m_A, m_C, X, W, w, H, \ G, L, P, alpha) print 'ALPHA ERROR = ', EM.error(alpha, np.mean(\ simulation['perf_baseline'], 0)) print 'DRIFT ERROR = ', EM.error(L, simulation['drift_coeffs']) #alpha = np.zeros_like(np.mean(simulation['perf_baseline'], 0)) PL = np.dot(P, L) wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :]) y_tilde = Y - PL - wa # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): Beta[m] = EM.maximization_beta(Beta[m], q_Z, Z_tilde, J, K, m, graph, gamma, neighboursIndexes, maxNeighbours) print Beta logger.info("End estimating beta") logger.info(Beta) # Sigma noise if estimateNoise: logger.info("M sigma noise step ...") sigma_eps = EM.maximization_sigma_noise(Y, X, m_A, Sigma_A, H, m_C, Sigma_C, G, W, M, N, J, y_tilde, sigma_eps) print 'NOISE ERROR = ', EM.error(sigma_eps, np.var(simulation['noise'], 0)) #print ' - est var noise: ', sigma_eps #print ' - sim var noise: ', np.var(simulation['noise'], 0) for m in xrange(M): SUM_q_Z[m] += [sum(q_Z[m, 1, :])] mua1[m] += [mu_Ma[m, 1]] muc1[m] += [mu_Mc[m, 1]] ni += 1 t02 = time.time() cTime += [t02 - t1] t2 = time.time() CompTime = t2 - t1 cTimeMean = CompTime / ni ########################################################################### ########################################## PLOTS and SNR computation SUM_q_Z_array = np.zeros((M, ni), dtype=np.float64) mua1_array = np.zeros((M, ni), dtype=np.float64) muc1_array = np.zeros((M, ni), dtype=np.float64) #h_norm_array = np.zeros((ni), dtype=np.float64) for m in xrange(M): for i in xrange(ni): SUM_q_Z_array[m, i] = SUM_q_Z[m][i] mua1_array[m, i] = mua1[m][i] muc1_array[m, i] = muc1[m][i] #h_norm_array[i] = h_norm[i] if PLOT: font = {'size': 15} import matplotlib import matplotlib.pyplot as plt matplotlib.rc('font', **font) plt.figure(M + 1) plt.savefig('./BRF_Iter_ASL.png') plt.figure(M + 2) plt.savefig('./PRF_Iter_ASL.png') plt.hold(False) plt.figure(2) plt.plot(cAH[1:-1], 'lightblue') plt.hold(True) plt.plot(cCG[1:-1], 'm') plt.hold(False) plt.legend(('CAH', 'CCG')) plt.grid(True) plt.savefig('./Crit_ASL.png') plt.figure(4) for m in xrange(M): plt.plot(SUM_q_Z_array[m]) plt.hold(True) plt.hold(False) plt.savefig('./Sum_q_Z_Iter_ASL.png') """plt.figure(5) for m in xrange(M): plt.plot(mua1_array[m]) plt.hold(True) plt.plot(muc1_array[m]) plt.hold(False) plt.legend(('mu_a', 'mu_c')) plt.savefig('./mu1_Iter_ASL.png') plt.figure(6) plt.plot(h_norm_array) plt.savefig('./HRF_Norm_ASL.png')""" logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str(np.int(CompTime // 60)), str(np.int(CompTime % 60))) StimulusInducedSignal = EM.computeFit(H, m_A, G, m_C, W, X, J, N) SNR = 20 * (np.log(np.linalg.norm(Y) / \ np.linalg.norm(Y - StimulusInducedSignal - PL))) / np.log(10.) logger.info('mu_Ma: %f', mu_Ma) logger.info('sigma_Ma: %f', sigma_Ma) logger.info("sigma_H = %s" + str(sigmaH)) logger.info('mu_Mc: %f', mu_Mc) logger.info('sigma_Mc: %f', sigma_Mc) logger.info("sigma_G = %s" + str(sigmaG)) logger.info("Beta = %s" + str(Beta)) logger.info('SNR comp = %f', SNR) return ni, m_A, H, m_C, G, q_Z, sigma_eps, cZ[2:],\ cTime, cTimeMean, mu_Ma, sigma_Ma, mu_Mc, sigma_Mc, Beta, L, PL, \ Sigma_A, Sigma_C, StimulusInducedSignal
def Main_vbjde(graph,Y,Onsets,Thrf,K,TR,beta,dt,hrf,NitMax = -1, hrf = None): if NitMax < 0: NitMax = 100 D = int(numpy.ceil(Thrf/dt)) M = len(Onsets) N = Y.shape[0] J = Y.shape[1] l = int(sqrt(J)) sigma_epsilone = numpy.ones(J) X = {} for condition,Ons in Onsets.iteritems(): X[condition] = compute_mat_X_2(N, TR, D, dt, Ons) mu_M = numpy.zeros((M,K),dtype=float) sigma_M = 0.5 * numpy.ones((M,K),dtype=float) mu_M0 = numpy.zeros((M,K),dtype=float) sigma_M0 = numpy.zeros((M,K),dtype=float) for k in xrange(0,K): mu_M[:,0] = 2.0 mu_M0[:,:] = mu_M[:,:] sigma_M0[:,:] = sigma_M[:,:] #sigmaH = numpy.ones((J),dtype=float) #sigmaH1 = numpy.ones((J),dtype=float) sigmaH = 0.1 sigmaH1 = 0.1 order = 2 D2 = buildFiniteDiffMatrix(order,D) R = numpy.dot(D2,D2) / pow(dt,2*order) Gamma = numpy.identity(N) q_Z = numpy.zeros((M,K,J),dtype=float) for k in xrange(0,K): q_Z[:,1,:] = 1 q_Z1 = q_Z.copy() Z_tilde = q_Z.copy() Sigma_A = numpy.zeros((M,M,J),float) m_A = numpy.zeros((J,M),dtype=float) m_H = numpy.zeros((D,J),dtype=float) m_H1 = numpy.zeros((D,J),dtype=float) m_H2 = numpy.zeros((D,J),dtype=float) TT,m_h = getCanoHRF(Thrf-dt,dt) for j in xrange(0,J): Sigma_A[:,:,j] = 0.01*numpy.identity(M) for m in xrange(0,M): for k in xrange(0,K): m_A[j,m] += normal(mu_M[m,k], numpy.sqrt(sigma_M[m,k]))*Z_tilde[m,k,j] m_H[:,j] = numpy.array(m_h) m_H1[:,j] = numpy.array(m_h) #m_H = numpy.array(m_h) #m_H1 = numpy.array(m_h) Sigma_H = numpy.ones((D,D,J),dtype=float) #Sigma_H = 0.1 * numpy.identity(D) Beta = beta * numpy.ones((M),dtype=float) m_A1 = numpy.zeros((J,M),dtype=float) m_A1[:,:] = m_A[:,:] Crit_H = [0] Crit_Z = [0] Crit_sigmaH = [0] Hist_sigmaH = [] ni = 0 Y_bar_tilde = numpy.zeros((D),dtype=float) zerosND = numpy.zeros((N,D),dtype=float) X_tilde = numpy.zeros((Y.shape[1],M,D),dtype=float) Q_bar = numpy.zeros(R.shape) P = PolyMat( N , 4 , TR) L = polyFit(Y, TR, 4,P) PL = numpy.dot(P,L) y_tilde = Y - PL t1 = time.time() Norm = numpy.zeros((J),dtype=float) while (( (ni < 15) or (Crit_sigmaH[-1] > 5e-3) or (Crit_H[-1] > 5e-3) or (Crit_Z[-1] > 5e-3))) \ and (ni < NitMax): print "------------------------------ Iteration n° " + str(ni+1) + " ------------------------------" pyhrf.verbose(2,"------------------------------ Iteration n° " + str(ni+1) + " ------------------------------") pyhrf.verbose(3, "E A step ...") Sigma_A, m_A = expectation_A(Y,Sigma_H,m_H,m_A,X,Gamma,PL,sigma_M,q_Z,mu_M,D,N,J,M,K,y_tilde,Sigma_A,sigma_epsilone) pyhrf.verbose(3,"E H step ...") Sigma_H, m_H = expectation_H(Y,Sigma_A,m_A,X,Gamma,PL,D,R,sigmaH,J,N,y_tilde,zerosND,sigma_epsilone,Sigma_H,m_H) Crit_H += [abs(numpy.mean(m_H - m_H1) / numpy.mean(m_H))] m_H1[:,:] = m_H[:,:] m_H2[:,:] = m_H[:,:] pyhrf.verbose(3,"E Z step ...") q_Z,Z_tilde = expectation_Z(Sigma_A,m_A,sigma_M,Beta,Z_tilde,mu_M,q_Z,graph,M,J,K) DIFF = abs(numpy.reshape(q_Z,(M*K*J)) - numpy.reshape(q_Z1,(M*K*J))) Crit_Z += [numpy.mean(DIFF) / (DIFF != 0).sum()] q_Z1[:,:] = q_Z[:,:] pyhrf.verbose(3,"M (mu,sigma) step ...") mu_M , sigma_M = maximization_mu_sigma(mu_M,sigma_M,q_Z,m_A,K,M) pyhrf.verbose(3,"M sigma_H step ...") #print "M sigma_H step ..." sigmaH = maximization_sigmaH(m_H,R,J,D,Sigma_H,sigmaH) #print sigmaH #sigmaH = numpy.dot(numpy.dot(m_H.transpose(),R) , m_H ) #+ (numpy.dot(Sigma_H,R)).trace() Crit_sigmaH += [abs((sigmaH - sigmaH1) / sigmaH)] Hist_sigmaH += [sigmaH] sigmaH1 = sigmaH pyhrf.verbose(3,"M L step ...") L = maximization_L(Y,m_A,X,m_H,L,P) PL = numpy.dot(P,L) y_tilde = Y - PL pyhrf.verbose(3,"M sigma_epsilone step ...") sigma_epsilone = maximization_sigma_noise(Y,X,m_A,m_H,Sigma_H,Sigma_A,PL,sigma_epsilone,M) for i in xrange(0,J): Norm[i] = norm(m_H[:,i]) m_H2[:,i] /= Norm[i] if ( (ni+1)% 1) == 0: pyplot.clf() figure(1) plot(m_H[:,10],'r') hold(True) plot(hrf/norm(hrf),'b') legend( ('Est','Ref') ) title(str(sigmaH)) hold(False) draw() show() for m in range(0,M): for k in range(0,K): z1 = q_Z[m,k,:]; z2 = reshape(z1,(l,l)); figure(2).add_subplot(M,K,1 + m*K + k) imshow(z2) title("m = " + str(m) +"k = " + str(k)) draw() show() ni +=1 t2 = time.time() CompTime = t2 - t1 for i in xrange(0,J): Norm[i] = norm(m_H[:,i]) m_H[:,i] /= Norm[i] m_A[i,:] *= Norm[i] pyhrf.verbose(1, "Computational time = " + str(int( CompTime//60 ) ) + " min " + str(int(CompTime%60)) + " s") return m_A, m_H, q_Z , sigma_epsilone, sigmaH
def Main_vbjde_physio(graph, Y, Onsets, durations, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, estimateSigmaG=True, sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, contrasts=[], computeContrast=False, idx_first_tag=0, simulation=None, sigmaMu=None, estimateH=True, estimateG=True, estimateA=True, estimateC=True, estimateZ=True, estimateNoise=True, estimateMP=True, estimateLA=True, use_hyperprior=False, positivity=False, constraint=False, phy_params=PHY_PARAMS_KHALIDOV11, prior='omega', zc=False): logger.info("EM for ASL!") np.random.seed(6537540) logger.info("data shape: ") logger.info(Y.shape) Thresh = 1e-5 D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets) #D, M = np.int(np.ceil(Thrf / dt)), len(Onsets) N, J = Y.shape[0], Y.shape[1] Crit_AH, Crit_CG, cTime, rerror, FE = 1, 1, [], [], [] EP, EPlh, Ent = [],[],[] Crit_H, Crit_G, Crit_Z, Crit_A, Crit_C = 1, 1, 1, 1, 1 cAH, cCG, AH1, CG1 = [], [], [], [] cA, cC, cH, cG, cZ = [], [], [], [], [] h_norm, g_norm = [], [] SUM_q_Z = [[] for m in xrange(M)] mua1 = [[] for m in xrange(M)] muc1 = [[] for m in xrange(M)] # Beta data MaxItGrad = 200 gradientStep = 0.005 gamma = 7.5 maxNeighbours, neighboursIndexes = vt.create_neighbours(graph, J) # Control-tag w = np.ones((N)) w[idx_first_tag + 1::2] = -1 W = np.diag(w) # Conditions X, XX, condition_names = vt.create_conditions_block(Onsets, durations, M, N, D, TR, dt) #X, XX, condition_names = vt.create_conditions(Onsets, M, N, D, TR, dt) if zc: XX = XX[:, :, 1:-1] # XX shape (S, M, N, D) D = D - 2 AH1, CG1 = np.zeros((J, M, D)), np.zeros((J, M, D)) # Covariance matrix #R = vt.covariance_matrix(2, D, dt) _, R_inv = genGaussianSmoothHRF(False, D, dt, 1., 2) R = np.linalg.inv(R_inv) # Noise matrix Gamma = np.identity(N) # Noise initialization sigma_eps = np.ones(J) # Labels logger.info("Labels are initialized by setting active probabilities " "to ones ...") q_Z = np.ones((M, K, J), dtype=np.float64) / 2. #q_Z = np.zeros((M, K, J), dtype=np.float64) #q_Z[:, 1, :] = 1 q_Z1 = copy.deepcopy(q_Z) Z_tilde = copy.deepcopy(q_Z) # H and G TT, m_h = getCanoHRF(Thrf, dt) H = np.array(m_h[1:D+1]).astype(np.float64) H /= np.linalg.norm(H) G = copy.deepcopy(H) Hb = create_physio_brf(phy_params, response_dt=dt, response_duration=Thrf) Hb /= np.linalg.norm(Hb) Gb = create_physio_prf(phy_params, response_dt=dt, response_duration=Thrf) Gb /= np.linalg.norm(Gb) if prior=='balloon': H = Hb.copy() G = Gb.copy() Mu = Hb.copy() H1 = copy.deepcopy(H) Sigma_H = np.zeros((D, D), dtype=np.float64) G1 = copy.deepcopy(G) Sigma_G = copy.deepcopy(Sigma_H) normOh = False normg = False if prior=='hierarchical' or prior=='omega': Omega = linear_rf_operator(len(H), phy_params, dt, calculating_brf=False) if prior=='omega': Omega0 = Omega.copy() OmegaH = np.dot(Omega, H) G = np.dot(Omega, H) if normOh or normg: Omega /= np.linalg.norm(OmegaH) OmegaH /=np.linalg.norm(OmegaH) G /= np.linalg.norm(G) # Initialize model parameters Beta = beta * np.ones((M), dtype=np.float64) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) alpha = np.zeros((J), dtype=np.float64) WP = np.append(w[:, np.newaxis], P, axis=1) AL = np.append(alpha[np.newaxis, :], L, axis=0) y_tilde = Y - WP.dot(AL) # Parameters Gaussian mixtures mu_Ma = np.append(np.zeros((M, 1)), np.ones((M, 1)), axis=1).astype(np.float64) mu_Mc = mu_Ma.copy() sigma_Ma = np.ones((M, K), dtype=np.float64) * 0.3 sigma_Mc = sigma_Ma.copy() # Params RLs m_A = np.zeros((J, M), dtype=np.float64) for j in xrange(0, J): m_A[j, :] = (np.random.normal(mu_Ma, np.sqrt(sigma_Ma)) * q_Z[:, :, j]).sum(axis=1).T m_A1 = m_A.copy() Sigma_A = np.ones((M, M, J)) * np.identity(M)[:, :, np.newaxis] m_C = m_A.copy() m_C1 = m_C.copy() Sigma_C = Sigma_A.copy() # Precomputations WX = W.dot(XX).transpose(1, 0, 2) Gamma_X = np.tensordot(Gamma, XX, axes=(1, 1)) X_Gamma_X = np.tensordot(XX.T, Gamma_X, axes=(1, 0)) # shape (D, M, M, D) Gamma_WX = np.tensordot(Gamma, WX, axes=(1, 1)) XW_Gamma_WX = np.tensordot(WX.T, Gamma_WX, axes=(1, 0)) # shape (D, M, M, D) Gamma_WP = Gamma.dot(WP) WP_Gamma_WP = WP.T.dot(Gamma_WP) sigma_eps_m = np.maximum(sigma_eps, eps) cov_noise = sigma_eps_m[:, np.newaxis, np.newaxis] ########################################################################### ############################################# VBJDE t1 = time.time() ni = 0 #while ((ni < NitMin + 1) or (((Crit_AH > Thresh) or (Crit_CG > Thresh)) \ # and (ni < NitMax))): #while ((ni < NitMin + 1) or (((Crit_AH > Thresh)) \ # and (ni < NitMax))): while ((ni < NitMin + 1) or (((Crit_FE > Thresh * np.ones_like(Crit_FE)).any()) \ and (ni < NitMax))): logger.info("-------- Iteration n° " + str(ni + 1) + " --------") if PLOT and ni >= 0: # Plotting HRF and PRF logger.info("Plotting HRF and PRF for current iteration") vt.plot_response_functions_it(ni, NitMin, M, H, G, Mu, prior) # Managing types of prior priorH_cov_term = np.zeros_like(R_inv) priorG_cov_term = np.zeros_like(R_inv) matrix_covH = R_inv.copy() matrix_covG = R_inv.copy() if prior=='balloon': logger.info(" prior balloon") #matrix_covH = np.eye(R_inv.shape[0], R_inv.shape[1]) #matrix_covG = np.eye(R_inv.shape[0], R_inv.shape[1]) priorH_mean_term = np.dot(matrix_covH / sigmaH, Hb) priorG_mean_term = np.dot(matrix_covG / sigmaG, Gb) elif prior=='omega': logger.info(" prior omega") #matrix_covG = np.eye(R_inv.shape[0], R_inv.shape[1]) priorH_mean_term = np.dot(np.dot(Omega.T, matrix_covG / sigmaG), G) priorH_cov_term = np.dot(np.dot(Omega.T, matrix_covG / sigmaG), Omega) priorG_mean_term = np.dot(matrix_covG / sigmaG, OmegaH) elif prior=='hierarchical': logger.info(" prior hierarchical") matrix_covH = np.eye(R_inv.shape[0], R_inv.shape[1]) matrix_covG = np.eye(R_inv.shape[0], R_inv.shape[1]) priorH_mean_term = Mu / sigmaH priorG_mean_term = np.dot(Omega, Mu / sigmaG) else: logger.info(" NO prior") priorH_mean_term = np.zeros_like(H) priorG_mean_term = np.zeros_like(G) ##################### # EXPECTATION ##################### # HRF H if estimateH: logger.info("E H step ...") Ht, Sigma_H = vt.expectation_H_asl(Sigma_A, m_A, m_C, G, XX, W, Gamma, Gamma_X, X_Gamma_X, J, y_tilde, cov_noise, matrix_covH, sigmaH, priorH_mean_term, priorH_cov_term) if constraint: if not np.linalg.norm(Ht)==1: logger.info(" constraint l2-norm = 1") H = vt.constraint_norm1_b(Ht, Sigma_H) #H = Ht / np.linalg.norm(Ht) else: logger.info(" l2-norm already 1!!!!!") H = Ht.copy() Sigma_H = np.zeros_like(Sigma_H) else: H = Ht.copy() h_norm = np.append(h_norm, np.linalg.norm(H)) print 'h_norm = ', h_norm Crit_H = (np.linalg.norm(H - H1) / np.linalg.norm(H1)) ** 2 cH += [Crit_H] H1[:] = H[:] if prior=='omega': OmegaH = np.dot(Omega0, H) Omega = Omega0 if normOh: Omega /= np.linalg.norm(OmegaH) OmegaH /= np.linalg.norm(OmegaH) if ni > 0: free_energyH = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyH < free_energy: logger.info("free energy has decreased after E-H step from %f to %f", free_energy, free_energyH) # A if estimateA: logger.info("E A step ...") m_A, Sigma_A = vt.expectation_A_asl(H, G, m_C, W, XX, Gamma, Gamma_X, q_Z, mu_Ma, sigma_Ma, J, y_tilde, Sigma_H, sigma_eps_m) cA += [(np.linalg.norm(m_A - m_A1) / np.linalg.norm(m_A1)) ** 2] m_A1[:, :] = m_A[:, :] if ni > 0: free_energyA = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyA < free_energyH: logger.info("free energy has decreased after E-A step from %f to %f", free_energyH, free_energyA) # PRF G if estimateG: logger.info("E G step ...") Gt, Sigma_G = vt.expectation_G_asl(Sigma_C, m_C, m_A, H, XX, W, WX, Gamma, Gamma_WX, XW_Gamma_WX, J, y_tilde, cov_noise, matrix_covG, sigmaG, priorG_mean_term, priorG_cov_term) if constraint and normg: if not np.linalg.norm(Gt)==1: logger.info(" constraint l2-norm = 1") G = vt.constraint_norm1_b(Gt, Sigma_G, positivity=positivity) #G = Gt / np.linalg.norm(Gt) else: logger.info(" l2-norm already 1!!!!!") G = Gt.copy() Sigma_G = np.zeros_like(Sigma_G) else: G = Gt.copy() g_norm = np.append(g_norm, np.linalg.norm(G)) print 'g_norm = ', g_norm cG += [(np.linalg.norm(G - G1) / np.linalg.norm(G1)) ** 2] G1[:] = G[:] if ni > 0: free_energyG = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyG < free_energyA: logger.info("free energy has decreased after E-G step from %f to %f", free_energyA, free_energyG) # C if estimateC: logger.info("E C step ...") m_C, Sigma_C = vt.expectation_C_asl(G, H, m_A, W, XX, Gamma, Gamma_X, q_Z, mu_Mc, sigma_Mc, J, y_tilde, Sigma_G, sigma_eps_m) cC += [(np.linalg.norm(m_C - m_C1) / np.linalg.norm(m_C1)) ** 2] m_C1[:, :] = m_C[:, :] if ni > 0: free_energyC = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyC < free_energyG: logger.info("free energy has decreased after E-C step from %f to %f", free_energyG, free_energyC) # Q labels if estimateZ: logger.info("E Q step ...") q_Z, Z_tilde = vt.expectation_Q_asl(Sigma_A, m_A, Sigma_C, m_C, sigma_Ma, mu_Ma, sigma_Mc, mu_Mc, Beta, Z_tilde, q_Z, neighboursIndexes, graph, M, J, K) #q_Z0, Z_tilde0 = vt.expectation_Q_async(Sigma_A, m_A, Sigma_C, m_C, # sigma_Ma, mu_Ma, sigma_Mc, mu_Mc, # Beta, Z_tilde, q_Z, neighboursIndexes, graph, M, J, K) #print 'synchronous vs asynchronous: ', np.abs(q_Z - q_Z0).sum() cZ += [(np.linalg.norm(q_Z - q_Z1) / (np.linalg.norm(q_Z1) + eps)) ** 2] q_Z1 = q_Z if ni > 0: free_energyQ = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyQ < free_energyC: logger.info("free energy has decreased after E-Q step from %f to %f", free_energyC, free_energyQ) # crit. AH and CG logger.info("crit. AH and CG") AH = m_A[:, :, np.newaxis] * H[np.newaxis, np.newaxis, :] CG = m_C[:, :, np.newaxis] * G[np.newaxis, np.newaxis, :] Crit_AH = (np.linalg.norm(AH - AH1) / (np.linalg.norm(AH1) + eps)) ** 2 cAH += [Crit_AH] AH1 = AH.copy() Crit_CG = (np.linalg.norm(CG - CG1) / (np.linalg.norm(CG1) + eps)) ** 2 cCG += [Crit_CG] CG1 = CG.copy() logger.info("Crit_AH = " + str(Crit_AH)) logger.info("Crit_CG = " + str(Crit_CG)) ##################### # MAXIMIZATION ##################### if prior=='balloon': logger.info(" prior balloon") AuxH = H - Hb AuxG = G - Gb elif prior=='omega': logger.info(" prior omega") AuxH = H.copy() AuxG = G - np.dot(Omega, H) #/np.linalg.norm(np.dot(Omega, H)) elif prior=='hierarchical': logger.info(" prior hierarchical") AuxH = H - Mu AuxG = G - np.dot(Omega, Mu) else: logger.info(" NO prior") AuxH = H.copy() AuxG = G.copy() # Variance HRF: sigmaH if estimateSigmaH: logger.info("M sigma_H step ...") sigmaH = vt.maximization_sigma_asl(D, Sigma_H, matrix_covH, AuxH, use_hyperprior, gamma_h) logger.info('sigmaH = ' + str(sigmaH)) if ni > 0: free_energyVh = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyVh < free_energyQ: logger.info("free energy has decreased after v_h computation from %f to %f", free_energyQ, free_energyVh) # Variance PRF: sigmaG if estimateSigmaG: logger.info("M sigma_G step ...") sigmaG = vt.maximization_sigma_asl(D, Sigma_G, matrix_covG, AuxG, use_hyperprior, gamma_g) logger.info('sigmaG = ' + str(sigmaG)) if ni > 0: free_energyVg = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyVg < free_energyVh: logger.info("free energy has decreased after v_g computation from %f to %f", free_energyVh, free_energyVg) # Mu: True HRF in the hierarchical prior case if prior=='hierarchical': logger.info("M sigma_G step ...") Mu = vt.maximization_Mu_asl(H, G, matrix_covH, matrix_covG, sigmaH, sigmaG, sigmaMu, Omega, R_inv) logger.info('sigmaG = ' + str(sigmaG)) if ni > 0: free_energyMu = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyMu < free_energyVg: logger.info("free energy has decreased after v_g computation from %f to %f", free_energyVg, free_energyMu) # (mu,sigma) if estimateMP: logger.info("M (mu,sigma) a and c step ...") mu_Ma, sigma_Ma = vt.maximization_mu_sigma_asl(q_Z, m_A, Sigma_A) mu_Mc, sigma_Mc = vt.maximization_mu_sigma_asl(q_Z, m_C, Sigma_C) if ni > 0: free_energyMP = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyMP < free_energyVg: logger.info("free energy has decreased after GMM parameters computation from %f to %f", free_energyVg, free_energyMP) # Drift L, alpha if estimateLA: logger.info("M L, alpha step ...") AL = vt.maximization_LA_asl(Y, m_A, m_C, XX, WP, W, WP_Gamma_WP, H, G, Gamma) y_tilde = Y - WP.dot(AL) if ni > 0: free_energyLA = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyLA < free_energyMP: logger.info("free energy has decreased after drifts computation from %f to %f", free_energyMP, free_energyLA) # Beta if estimateBeta: logger.info("M beta step ...") """ Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2) Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3) Beta = vt.maximization_beta_m2(Beta.copy(), q_Z, Qtilde_sumneighbour, Qtilde, neighboursIndexes, maxNeighbours, gamma, MaxItGrad, gradientStep) """ Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2) Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3) for m in xrange(0, M): Beta[m] = vt.maximization_beta_m2_scipy_asl(Beta[m].copy(), q_Z[m, :, :], Qtilde_sumneighbour[m, :, :], Qtilde[m, :, :], neighboursIndexes, maxNeighbours, gamma, MaxItGrad, gradientStep) logger.info(Beta) if ni > 0: free_energyB = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX) if free_energyB < free_energyLA: logger.info("free energy has decreased after Beta computation from %f to %f", \ free_energyLA, free_energyB) if 0: plt.close('all') for m in xrange(0, M): range_b = np.arange(-10., 20., 0.1) beta_plotting = np.zeros_like(range_b) for ib, b in enumerate(range_b): beta_plotting[ib] = vt.beta_function(b, q_Z[m, :, :], Qtilde_sumneighbour[m, :, :], neighboursIndexes, gamma) #print beta_plotting plt.figure(1) plt.hold('on') plt.plot(range_b, beta_plotting) plt.show() # Sigma noise if estimateNoise: logger.info("M sigma noise step ...") sigma_eps = vt.maximization_sigma_noise_asl(XX, m_A, Sigma_A, H, m_C, Sigma_C, \ G, Sigma_H, Sigma_G, W, y_tilde, Gamma, \ Gamma_X, Gamma_WX, N) if PLOT: for m in xrange(M): SUM_q_Z[m] += [q_Z[m, 1, :].sum()] mua1[m] += [mu_Ma[m, 1]] muc1[m] += [mu_Mc[m, 1]] free_energy = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps, XX, W, J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX, plot=True) if ni > 0: if free_energy < free_energyB: logger.info("free energy has decreased after Noise computation from %f to %f", free_energyB, free_energy) if ni > 0: if free_energy < FE[-1]: logger.info("WARNING! free energy has decreased in this iteration from %f to %f", FE[-1], free_energy) FE += [free_energy] #EP += [EPt] #EPlh += [EPt_lh] #Ent += [Entropy] if ni > NitMin: #Crit_FE = np.abs((FE[-1] - FE[-2]) / FE[-2]) FE0 = np.array(FE) Crit_FE = np.abs((FE0[-5:] - FE0[-6:-1]) / FE0[-6:-1]) print Crit_FE print (Crit_FE > Thresh * np.ones_like(Crit_FE)).any() else: Crit_FE = 100 ni += 1 cTime += [time.time() - t1] logger.info("Computing reconstruction error") StimulusInducedSignal = vt.computeFit_asl(H, m_A, G, m_C, W, XX) rerror = np.append(rerror, \ np.mean(((Y - StimulusInducedSignal) ** 2).sum(axis=0)) \ / np.mean((Y ** 2).sum(axis=0))) CompTime = time.time() - t1 # Normalize if not done already if not constraint or not normg: logger.info("l2-norm of H and G to 1 if not constraint") Hnorm = np.linalg.norm(H) H /= Hnorm Sigma_H /= Hnorm**2 m_A *= Hnorm Gnorm = np.linalg.norm(G) G /= Gnorm Sigma_G /= Gnorm**2 m_C *= Gnorm if zc: H = np.concatenate(([0], H, [0])) G = np.concatenate(([0], G, [0])) ## Compute contrast maps and variance if computeContrast and len(contrasts) > 0: logger.info("Computing contrasts ... ") CONTRAST_A, CONTRASTVAR_A, \ CONTRAST_C, CONTRASTVAR_C = vt.compute_contrasts(condition_names, contrasts, m_A, m_C, Sigma_A, Sigma_C, M, J) else: CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C = 0, 0, 0, 0 ########################################################################### ########################################## PLOTS and SNR computation if PLOT: logger.info("plotting...") print 'FE = ', FE vt.plot_convergence(ni, M, cA, cC, cH, cG, cAH, cCG, SUM_q_Z, mua1, muc1, FE) logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str(np.int(CompTime // 60)), str(np.int(CompTime % 60))) logger.info("Iteration time = %s min %s s", str(np.int((CompTime // ni) // 60)), str(np.int((CompTime / ni) % 60))) logger.info("perfusion baseline mean = %f", np.mean(AL[0, :])) logger.info("perfusion baseline var = %f", np.var(AL[0, :])) logger.info("drifts mean = %f", np.mean(AL[1:, :])) logger.info("drifts var = %f", np.var(AL[1:, :])) logger.info("noise mean = %f", np.mean(sigma_eps)) logger.info("noise var = %f", np.var(sigma_eps)) SNR10 = 20 * (np.log10(np.linalg.norm(Y) / \ np.linalg.norm(Y - StimulusInducedSignal - WP.dot(AL)))) logger.info("SNR = %d", SNR10) return ni, m_A, H, m_C, G, Z_tilde, sigma_eps, \ mu_Ma, sigma_Ma, mu_Mc, sigma_Mc, Beta, AL[1:, :], np.dot(P, AL[1:, :]), \ AL[0, :], Sigma_A, Sigma_C, Sigma_H, Sigma_G, rerror, \ CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C, \ cA[:], cH[2:], cC[2:], cG[2:], cZ[2:], cAH[2:], cCG[2:], \ cTime, FE #, EP, EPlh, Ent
def Main_vbjde_Python_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.1, NitMax=-1, NitMin=1, estimateBeta=False, PLOT=False): logger.info("EM started ...") np.random.seed(6537546) ########################################################################## # INITIALIZATIONS # Initialize parameters if NitMax < 0: NitMax = 100 gamma = 7.5 gradientStep = 0.005 MaxItGrad = 120 #Thresh = 1e-5 Thresh_FreeEnergy = 1e-5 # Initialize sizes vectors D = int(np.ceil(Thrf / dt)) M = len(Onsets) N = Y.shape[0] J = Y.shape[1] l = int(np.sqrt(J)) sigma_epsilone = np.ones(J) # Neighbours maxNeighbours = max([len(nl) for nl in graph]) neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32) neighboursIndexes -= 1 for i in xrange(J): neighboursIndexes[i, :len(graph[i])] = graph[i] # Conditions X = OrderedDict([]) for condition, Ons in Onsets.iteritems(): X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) XX = np.zeros((M, N, D), dtype=np.int32) nc = 0 for condition, Ons in Onsets.iteritems(): XX[nc, :, :] = X[condition] nc += 1 # Sigma and mu mu_M = np.zeros((M, K), dtype=np.float64) sigma_M = 0.5 * np.ones((M, K), dtype=np.float64) sigma_M0 = 0.5 * np.ones((M, K), dtype=np.float64) for k in xrange(1, K): mu_M[:, k] = 2.0 # Covariance matrix order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2 * order) Gamma = np.identity(N) q_Z = np.zeros((M, K, J), dtype=np.float64) # for k in xrange(0,K): q_Z[:, 1, :] = 1 q_Z1 = np.zeros((M, K, J), dtype=np.float64) Z_tilde = q_Z.copy() Sigma_A = np.zeros((M, M, J), np.float64) m_A = np.zeros((J, M), dtype=np.float64) TT, m_h = getCanoHRF(Thrf - dt, dt) # TODO: check for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_M[m, k], np.sqrt(sigma_M[m, k])) * Z_tilde[m, k, j] m_H = np.array(m_h).astype(np.float64) m_H1 = np.array(m_h) Sigma_H = np.ones((D, D), dtype=np.float64) Beta = beta * np.ones((M), dtype=np.float64) zerosDD = np.zeros((D, D), dtype=np.float64) zerosD = np.zeros((D), dtype=np.float64) zerosND = np.zeros((N, D), dtype=np.float64) zerosMM = np.zeros((M, M), dtype=np.float64) zerosJMD = np.zeros((J, M, D), dtype=np.float64) zerosK = np.zeros(K) P = vt.PolyMat(N, 4, TR) zerosP = np.zeros((P.shape[0]), dtype=np.float64) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - PL sigmaH1 = sigmaH Crit_H = 1 Crit_Z = 1 Crit_A = 1 cA = [] cH = [] cZ = [] Ndrift = L.shape[0] Crit_FreeEnergy = 1 t1 = time.time() ########################################################################## # VBJDE num. iter. minimum ni = 0 while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or ((Crit_H > Thresh) and (Crit_Z > Thresh) and (Crit_A > Thresh))) and (ni < NitMax))): logger.info("------------------------------ Iteration n° " + str(ni + 1) + " ------------------------------") ##################### # EXPECTATION ##################### # A logger.info("E A step ...") Sigma_A, m_A = vt.expectation_A( Y, Sigma_H, m_H, m_A, X, Gamma, PL, sigma_M, q_Z, mu_M, D, N, J, M, K, y_tilde, Sigma_A, sigma_epsilone, zerosJMD) m_A1 = m_A # crit A DIFF = np.abs(np.reshape(m_A, (M * J)) - np.reshape(m_A1, (M * J))) Crit_A = sum(DIFF) / len(np.where(DIFF != 0)) cA += [Crit_A] # H logger.info("E H step ...") Sigma_H, m_H = vt.expectation_H( Y, Sigma_A, m_A, X, Gamma, PL, D, R, sigmaH, J, N, y_tilde, zerosND, sigma_epsilone, scale, zerosDD, zerosD) m_H[0] = 0 m_H[-1] = 0 m_H1 = m_H # crit H Crit_H = np.abs(np.mean(m_H - m_H1) / np.mean(m_H)) cH += [Crit_H] # Z logger.info("E Z step ...") q_Z, Z_tilde = vt.expectation_Z( Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, graph, M, J, K, zerosK) # crit Z DIFF = np.abs( np.reshape(q_Z, (M * K * J)) - np.reshape(q_Z1, (M * K * J))) Crit_Z = sum(DIFF) / len(np.where(DIFF != 0)) cZ += [Crit_Z] q_Z1 = q_Z # Plotting HRF if PLOT and ni >= 0: import matplotlib.pyplot as plt plt.figure(M + 1) plt.plot(m_H) plt.hold(True) #################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateSigmaH: logger.info("M sigma_H step ...") sigmaH = (np.dot(vt.mult(m_H, m_H) + Sigma_H, R)).trace() sigmaH /= D # (mu,sigma) logger.info("M (mu,sigma) step ...") mu_M, sigma_M = vt.maximization_mu_sigma( mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A) # Drift L L = vt.maximization_L(Y, m_A, X, m_H, L, P, zerosP) PL = np.dot(P, L) y_tilde = Y - PL # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): Beta[m] = vt.maximization_beta( Beta[m], q_Z, Z_tilde, J, K, m, graph, gamma, neighboursIndexes, maxNeighbours) logger.info("End estimating beta") # logger.info(Beta) # Sigma noise logger.info("M sigma noise step ...") sigma_epsilone = vt.maximization_sigma_noise( Y, X, m_A, m_H, Sigma_H, Sigma_A, PL, sigma_epsilone, M, zerosMM) #### Computing Free Energy #### """ if ni > 0: FreeEnergy1 = FreeEnergy FreeEnergy = Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,m_H,Sigma_H,R,Det_invR,sigmaH,p_Wtilde,tau1,tau2,q_Z,neighboursIndexes,maxNeighbours,Beta,sigma_epsilone,XX,Gamma,Det_Gamma,XGamma,J,D,M,N,K,S,"CompMod") if ni > 0: Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1 FreeEnergy_Iter += [FreeEnergy] cFE += [Crit_FreeEnergy] """ # Update index ni += 1 t2 = time.time() ########################################################################## # PLOTS and SNR computation """FreeEnergyArray = np.zeros((ni),dtype=np.float64) for i in xrange(ni): FreeEnergyArray[i] = FreeEnergy_Iter[i] SUM_q_Z_array = np.zeros((M,ni),dtype=np.float64) mu1_array = np.zeros((M,ni),dtype=np.float64) h_norm_array = np.zeros((ni),dtype=np.float64) for m in xrange(M): for i in xrange(ni): SUM_q_Z_array[m,i] = SUM_q_Z[m][i] mu1_array[m,i] = mu1[m][i] h_norm_array[i] = h_norm[i] sigma_M = np.sqrt(np.sqrt(sigma_M)) """ Norm = np.linalg.norm(m_H) m_H /= Norm m_A *= Norm mu_M *= Norm sigma_M *= Norm sigma_M = np.sqrt(sigma_M) if PLOT and 0: import matplotlib.pyplot as plt import matplotlib font = {'size': 15} matplotlib.rc('font', **font) plt.savefig('./HRF_Iter_CompMod.png') plt.hold(False) plt.figure(2) plt.plot(cAH[1:-1], 'lightblue') plt.hold(True) plt.plot(cFE[1:-1], 'm') plt.hold(False) #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') ) plt.legend(('CAH', 'CFE')) plt.grid(True) plt.savefig('./Crit_CompMod.png') plt.figure(3) plt.plot(FreeEnergyArray) plt.grid(True) plt.savefig('./FreeEnergy_CompMod.png') plt.figure(4) for m in xrange(M): plt.plot(SUM_q_Z_array[m]) plt.hold(True) plt.hold(False) plt.savefig('./Sum_q_Z_Iter_CompMod.png') plt.figure(5) for m in xrange(M): plt.plot(mu1_array[m]) plt.hold(True) plt.hold(False) plt.savefig('./mu1_Iter_CompMod.png') plt.figure(6) plt.plot(h_norm_array) plt.savefig('./HRF_Norm_CompMod.png') Data_save = xndarray(h_norm_array, ['Iteration']) Data_save.save('./HRF_Norm_Comp.nii') CompTime = t2 - t1 cTimeMean = CompTime / ni logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str( int(CompTime // 60)), str(int(CompTime % 60))) # print "Computational time = " + str(int( CompTime//60 ) ) + " min " + # str(int(CompTime%60)) + " s" logger.info('mu_M: %f', mu_M) logger.info('sigma_M: %f', sigma_M) logger.info("sigma_H = %s" + str(sigmaH)) logger.info("Beta = %s" + str(Beta)) StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N) SNR = 20 * \ np.log( np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL)) SNR /= np.log(10.) print 'SNR comp =', SNR return m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL
def Main_vbjde_Extension_constrained_stable(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.05, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, contrasts=[], computeContrast=False, gamma_h=0): """ Version modified by Lofti from Christine's version """ logger.info( "Fast EM with C extension started ... Here is the stable version !") np.random.seed(6537546) # Initialize parameters S = 100 if NitMax < 0: NitMax = 100 gamma = 7.5 # 7.5 gradientStep = 0.003 MaxItGrad = 200 Thresh = 1e-5 # Initialize sizes vectors D = np.int(np.ceil(Thrf / dt)) + 1 M = len(Onsets) N = Y.shape[0] J = Y.shape[1] l = np.int(np.sqrt(J)) condition_names = [] # Neighbours maxNeighbours = max([len(nl) for nl in graph]) neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32) neighboursIndexes -= 1 for i in xrange(J): neighboursIndexes[i, :len(graph[i])] = graph[i] # Conditions X = OrderedDict([]) for condition, Ons in Onsets.iteritems(): X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) condition_names += [condition] XX = np.zeros((M, N, D), dtype=np.int32) nc = 0 for condition, Ons in Onsets.iteritems(): XX[nc, :, :] = X[condition] nc += 1 # Covariance matrix order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2 * order) invR = np.linalg.inv(R) Det_invR = np.linalg.det(invR) Gamma = np.identity(N) Det_Gamma = np.linalg.det(Gamma) Crit_H = 1 Crit_Z = 1 Crit_A = 1 Crit_AH = 1 AH = np.zeros((J, M, D), dtype=np.float64) AH1 = np.zeros((J, M, D), dtype=np.float64) Crit_FreeEnergy = 1 cTime = [] cA = [] cH = [] cZ = [] cAH = [] CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64) CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64) Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64) XGamma = np.zeros((M, D, N), dtype=np.float64) m1 = 0 for k1 in X: # Loop over the M conditions m2 = 0 for k2 in X: Q_barnCond[m1, m2, :, :] = np.dot( np.dot(X[k1].transpose(), Gamma), X[k2]) m2 += 1 XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma) m1 += 1 sigma_epsilone = np.ones(J) logger.info( "Labels are initialized by setting active probabilities to ones ...") q_Z = np.zeros((M, K, J), dtype=np.float64) q_Z[:, 1, :] = 1 q_Z1 = np.zeros((M, K, J), dtype=np.float64) Z_tilde = q_Z.copy() TT, m_h = getCanoHRF(Thrf, dt) # TODO: check m_h = m_h[:D] m_H = np.array(m_h).astype(np.float64) m_H1 = np.array(m_h) sigmaH1 = sigmaH Sigma_H = np.ones((D, D), dtype=np.float64) Beta = beta * np.ones((M), dtype=np.float64) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - PL Ndrift = L.shape[0] sigma_M = np.ones((M, K), dtype=np.float64) sigma_M[:, 0] = 0.5 sigma_M[:, 1] = 0.6 mu_M = np.zeros((M, K), dtype=np.float64) for k in xrange(1, K): mu_M[:, k] = 1 # InitMean Sigma_A = np.zeros((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) m_A = np.zeros((J, M), dtype=np.float64) m_A1 = np.zeros((J, M), dtype=np.float64) for j in xrange(0, J): for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_M[m, k], np.sqrt(sigma_M[m, k])) * q_Z[m, k, j] m_A1 = m_A t1 = time.time() ########################################################################## # VBJDE num. iter. minimum ni = 0 while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (ni < NitMax))): logger.info("------------------------------ Iteration n° " + str(ni + 1) + " ------------------------------") ##################### # EXPECTATION ##################### # A logger.info("E A step ...") UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K) # crit. A DIFF = np.reshape(m_A - m_A1, (M * J)) Crit_A = ( np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2 cA += [Crit_A] m_A1[:, :] = m_A[:, :] # HRF h UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH) #m_H[0] = 0 #m_H[-1] = 0 # Constrain with optimization strategy import cvxpy as cvx m, n = Sigma_H.shape Sigma_H_inv = np.linalg.inv(Sigma_H) zeros_H = np.zeros_like(m_H[:, np.newaxis]) # Construct the problem. PRIMAL h = cvx.Variable(n) expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv) objective = cvx.Minimize(expression) #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1] constraints = [h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1] prob = cvx.Problem(objective, constraints) result = prob.solve(verbose=0, solver=cvx.CVXOPT) # Now we update the mean of h m_H_old = m_H Sigma_H_old = Sigma_H m_H = np.squeeze(np.array((h.value))) Sigma_H = np.zeros_like(Sigma_H) # and the norm h_norm += [np.linalg.norm(m_H)] # crit. h Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2 cH += [Crit_H] m_H1[:] = m_H[:] # crit. AH for d in xrange(0, D): AH[:, :, d] = m_A[:, :] * m_H[d] DIFF = np.reshape(AH - AH1, (M * J * D)) Crit_AH = (np.linalg.norm( DIFF) / (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2 cAH += [Crit_AH] AH1[:, :, :] = AH[:, :, :] # Z labels logger.info("E Z step ...") UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours) # crit. Z DIFF = np.reshape(q_Z - q_Z1, (M * K * J)) Crit_Z = (np.linalg.norm(DIFF) / (np.linalg.norm(np.reshape(q_Z1, (M * K * J))) + eps)) ** 2 cZ += [Crit_Z] q_Z1[:, :, :] = q_Z[:, :, :] ##################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateSigmaH: logger.info("M sigma_H step ...") if gamma_h > 0: sigmaH = vt.maximization_sigmaH_prior( D, Sigma_H, R, m_H, gamma_h) else: sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H) logger.info('sigmaH = %s', str(sigmaH)) # (mu,sigma) logger.info("M (mu,sigma) step ...") mu_M, sigma_M = vt.maximization_mu_sigma( mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A) # Drift L UtilsC.maximization_L( Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N) PL = np.dot(P, L) y_tilde = Y - PL # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype( np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep) logger.info("End estimating beta") logger.info(Beta) # Sigma noise logger.info("M sigma noise step ...") UtilsC.maximization_sigma_noise( Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N) t02 = time.time() cTime += [t02 - t1] t2 = time.time() ########################################################################## # PLOTS and SNR computation if PLOT and 0: font = {'size': 15} matplotlib.rc('font', **font) savefig('./HRF_Iter_CompMod.png') hold(False) figure(2) plot(cAH[1:-1], 'lightblue') hold(True) plot(cFE[1:-1], 'm') hold(False) legend(('CAH', 'CFE')) grid(True) savefig('./Crit_CompMod.png') figure(3) plot(FreeEnergyArray) grid(True) savefig('./FreeEnergy_CompMod.png') figure(4) for m in xrange(M): plot(SUM_q_Z_array[m]) hold(True) hold(False) savefig('./Sum_q_Z_Iter_CompMod.png') figure(5) for m in xrange(M): plot(mu1_array[m]) hold(True) hold(False) savefig('./mu1_Iter_CompMod.png') figure(6) plot(h_norm_array) savefig('./HRF_Norm_CompMod.png') Data_save = xndarray(h_norm_array, ['Iteration']) Data_save.save('./HRF_Norm_Comp.nii') CompTime = t2 - t1 cTimeMean = CompTime / ni """ Norm = np.linalg.norm(m_H) m_H /= Norm Sigma_H /= Norm**2 sigmaH /= Norm**2 m_A *= Norm Sigma_A *= Norm**2 mu_M *= Norm sigma_M *= Norm**2 sigma_M = np.sqrt(np.sqrt(sigma_M)) """ logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str( np.int(CompTime // 60)), str(np.int(CompTime % 60))) logger.info('mu_M: %f', mu_M) logger.info('sigma_M: %f', sigma_M) logger.info("sigma_H = %s", str(sigmaH)) logger.info("Beta = %s", str(Beta)) StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N) SNR = 20 * \ np.log( np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL)) SNR /= np.log(10.) print 'SNR comp =', SNR return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal
def jde_vem_bold(graph, bold_data, onsets, durations, hrf_duration, nb_classes, tr, beta, dt, estimate_sigma_h=True, sigma_h=0.05, it_max=-1, it_min=0, estimate_beta=True, contrasts=None, compute_contrasts=False, hrf_hyperprior=0, estimate_hrf=True, constrained=False, zero_constraint=True, drifts_type="poly", seed=6537546): """This is the main function that computes the VEM analysis on BOLD data. This function uses optimized python functions. Parameters ---------- graph : ndarray of lists represents the neighbours indexes of each voxels index bold_data : ndarray, shape (nb_scans, nb_voxels) raw data onsets : dict dictionnary of onsets durations : # TODO # TODO hrf_duration : float hrf total time duration (in s) nb_classes : int the number of classes to classify the nrls. This parameter is provided for development purposes as most of the algorithm implies two classes tr : float time of repetition beta : float the initial value of beta dt : float hrf temporal precision estimate_sigma_h : bool, optional toggle estimation of sigma H sigma_h : float, optional initial or fixed value of sigma H it_max : int, optional maximal computed iteration number it_min : int, optional minimal computed iteration number estimate_beta : bool, optional toggle the estimation of beta contrasts : OrderedDict, optional dict of contrasts to compute compute_contrasts : bool, optional if True, compute the contrasts defined in contrasts hrf_hyperprior : float # TODO estimate_hrf : bool, optional if True, estimate the HRF for each parcel, if False use the canonical HRF constrained : bool, optional if True, add a constrains the l2 norm of the HRF to 1 drifts_type : str, optional set the drifts basis type used. Can be "poly" for polynomial or "cos" for cosine seed : int, optional seed used by numpy to initialize random generator number Returns ------- loop : int number of iterations before convergence nrls_mean : ndarray, shape (nb_voxels, nb_conditions) Neural response level mean value hrf_mean : ndarray, shape (hrf_len,) Hemodynamic response function mean value hrf_covar : ndarray, shape (hrf_len, hrf_len) Covariance matrix of the HRF labels_proba : ndarray, shape (nb_conditions, nb_classes, nb_voxels) probability of voxels being in one class noise_var : ndarray, shape (nb_voxels,) estimated noise variance nrls_class_mean : ndarray, shape (nb_conditions, nb_classes) estimated mean value of the gaussians of the classes nrls_class_var : ndarray, shape (nb_conditions, nb_classes) estimated variance of the gaussians of the classes beta : ndarray, shape (nb_conditions,) estimated beta drift_coeffs : ndarray, shape (# TODO) estimated coefficient of the drifts drift : ndarray, shape (# TODO) estimated drifts contrasts_mean : ndarray, shape (nb_voxels, len(contrasts)) Contrasts computed from NRLs contrasts_var : ndarray, shape (nb_voxels, len(contrasts)) Variance of the contrasts compute_time : list computation time of each iteration compute_time_mean : float computation mean time over iterations nrls_covar : ndarray, shape (nb_conditions, nb_conditions, nb_voxels) # TODO stimulus_induced_signal : ndarray, shape (nb_scans, nb_voxels) # TODO mahalanobis_zero : float Mahalanobis distance between estimated hrf_mean and the null vector mahalanobis_cano : float Mahalanobis distance between estimated hrf_mean and the canonical HRF mahalanobis_diff : float difference between mahalanobis_cano and mahalanobis_diff mahalanobis_prod : float product of mahalanobis_cano and mahalanobis_diff ppm_a_nrl : ndarray, shape (nb_voxels,) The posterior probability map using an alpha ppm_g_nrl : ndarray, shape (nb_voxels,) # TODO ppm_a_contrasts : ndarray, shape (nb_voxels,) # TODO ppm_g_contrasts : ndarray, shape (nb_voxels,) # TODO variation_coeff : float coefficient of variation of the HRF free_energy : list # TODO Notes ----- See `A novel definition of the multivariate coefficient of variation <http://onlinelibrary.wiley.com/doi/10.1002/bimj.201000030/abstract>`_ article for more information about the coefficient of variation. """ logger.info("VEM started.") if not contrasts: contrasts = OrderedDict() np.random.seed(seed) nb_2_norm = 1 normalizing = False regularizing = False if it_max <= 0: it_max = 100 gamma = 7.5 thresh_free_energy = 1e-4 # Initialize sizes vectors hrf_len = np.int(np.ceil(hrf_duration / dt)) + 1 nb_conditions = len(onsets) nb_scans = bold_data.shape[0] nb_voxels = bold_data.shape[1] X, occurence_matrix, condition_names = vt.create_conditions( onsets, durations, nb_conditions, nb_scans, hrf_len, tr, dt ) neighbours_indexes = vt.create_neighbours(graph) order = 2 if regularizing: regularization = np.ones(hrf_len) regularization[hrf_len//3:hrf_len//2] = 2 regularization[hrf_len//2:2*hrf_len//3] = 5 regularization[2*hrf_len//3:3*hrf_len//4] = 7 regularization[3*hrf_len//4:] = 10 # regularization[hrf_len//2:] = 10 else: regularization = None d2 = vt.buildFiniteDiffMatrix(order, hrf_len, regularization) hrf_regu_prior_inv = d2.T.dot(d2) / pow(dt, 2 * order) if estimate_hrf and zero_constraint: hrf_len = hrf_len - 2 hrf_regu_prior_inv = hrf_regu_prior_inv[1:-1, 1:-1] occurence_matrix = occurence_matrix[:, :, 1:-1] noise_struct = np.identity(nb_scans) free_energy = [1.] free_energy_crit = [1.] compute_time = [] noise_var = np.ones(nb_voxels) labels_proba = np.zeros((nb_conditions, nb_classes, nb_voxels), dtype=np.float64) logger.info("Labels are initialized by setting everything to {}".format(1./nb_classes)) labels_proba[:, :, :] = 1./nb_classes m_h = getCanoHRF(hrf_duration, dt)[1][:hrf_len] hrf_mean = np.array(m_h).astype(np.float64) if estimate_hrf: hrf_covar = np.identity(hrf_len, dtype=np.float64) else: hrf_covar = np.zeros((hrf_len, hrf_len), dtype=np.float64) beta = beta * np.ones((nb_conditions), dtype=np.float64) beta_list = [] beta_list.append(beta.copy()) if drifts_type == "poly": drift_basis = vt.poly_drifts_basis(nb_scans, 4, tr) elif drifts_type == "cos": drift_basis = vt.cosine_drifts_basis(nb_scans, 64, tr) drift_coeffs = vt.drifts_coeffs_fit(bold_data, drift_basis) drift = drift_basis.dot(drift_coeffs) bold_data_drift = bold_data - drift # Parameters Gaussian mixtures nrls_class_mean = 2 * np.ones((nb_conditions, nb_classes)) nrls_class_mean[:, 0] = 0 nrls_class_var = 0.3 * np.ones((nb_conditions, nb_classes), dtype=np.float64) nrls_mean = (np.random.normal( nrls_class_mean, nrls_class_var)[:, :, np.newaxis] * labels_proba).sum(axis=1).T nrls_covar = (np.identity(nb_conditions)[:, :, np.newaxis] + np.zeros((1, 1, nb_voxels))) start_time = time.time() loop = 0 while (loop <= it_min or ((np.asarray(free_energy_crit[-5:]) > thresh_free_energy).any() and loop < it_max)): logger.info("{:-^80}".format(" Iteration n°"+str(loop+1)+" ")) logger.info("Expectation A step...") logger.debug("Before: nrls_mean = %s, nrls_covar = %s", nrls_mean, nrls_covar) nrls_mean, nrls_covar = vt.nrls_expectation( hrf_mean, nrls_mean, occurence_matrix, noise_struct, labels_proba, nrls_class_mean, nrls_class_var, nb_conditions, bold_data_drift, nrls_covar, hrf_covar, noise_var) logger.debug("After: nrls_mean = %s, nrls_covar = %s", nrls_mean, nrls_covar) logger.info("Expectation Z step...") logger.debug("Before: labels_proba = %s, labels_proba = %s", labels_proba, labels_proba) labels_proba = vt.labels_expectation( nrls_covar, nrls_mean, nrls_class_var, nrls_class_mean, beta, labels_proba, neighbours_indexes, nb_conditions, nb_classes, nb_voxels, parallel=True) logger.debug("After: labels_proba = %s, labels_proba = %s", labels_proba, labels_proba) if estimate_hrf: logger.info("Expectation H step...") logger.debug("Before: hrf_mean = %s, hrf_covar = %s", hrf_mean, hrf_covar) hrf_mean, hrf_covar = vt.hrf_expectation( nrls_covar, nrls_mean, occurence_matrix, noise_struct, hrf_regu_prior_inv, sigma_h, nb_voxels, bold_data_drift, noise_var) if constrained: hrf_mean = vt.norm1_constraint(hrf_mean, hrf_covar) hrf_covar[:] = 0 logger.debug("After: hrf_mean = %s, hrf_covar = %s", hrf_mean, hrf_covar) # Normalizing H at each nb_2_norm iterations: if not constrained and normalizing: # Normalizing is done before sigma_h, nrls_class_mean and nrls_class_var estimation # we should not include them in the normalisation step if (loop + 1) % nb_2_norm == 0: hrf_norm = np.linalg.norm(hrf_mean) hrf_mean /= hrf_norm hrf_covar /= hrf_norm ** 2 nrls_mean *= hrf_norm nrls_covar *= hrf_norm ** 2 if estimate_hrf and estimate_sigma_h: logger.info("Maximization sigma_H step...") logger.debug("Before: sigma_h = %s", sigma_h) if hrf_hyperprior > 0: sigma_h = vt.maximization_sigmaH_prior(hrf_len, hrf_covar, hrf_regu_prior_inv, hrf_mean, hrf_hyperprior) else: sigma_h = vt.maximization_sigmaH(hrf_len, hrf_covar, hrf_regu_prior_inv, hrf_mean) logger.debug("After: sigma_h = %s", sigma_h) logger.info("Maximization (mu,sigma) step...") logger.debug("Before: nrls_class_mean = %s, nrls_class_var = %s", nrls_class_mean, nrls_class_var) nrls_class_mean, nrls_class_var = vt.maximization_class_proba( labels_proba, nrls_mean, nrls_covar ) logger.debug("After: nrls_class_mean = %s, nrls_class_var = %s", nrls_class_mean, nrls_class_var) logger.info("Maximization L step...") logger.debug("Before: drift_coeffs = %s", drift_coeffs) drift_coeffs = vt.maximization_drift_coeffs( bold_data, nrls_mean, occurence_matrix, hrf_mean, noise_struct, drift_basis ) logger.debug("After: drift_coeffs = %s", drift_coeffs) drift = drift_basis.dot(drift_coeffs) bold_data_drift = bold_data - drift if estimate_beta: logger.info("Maximization beta step...") for cond_nb in xrange(0, nb_conditions): beta[cond_nb], success = vt.beta_maximization( beta[cond_nb]*np.ones((1,)), labels_proba[cond_nb, :, :], neighbours_indexes, gamma ) beta_list.append(beta.copy()) logger.debug("beta = %s", str(beta)) logger.info("Maximization sigma noise step...") noise_var = vt.maximization_noise_var( occurence_matrix, hrf_mean, hrf_covar, nrls_mean, nrls_covar, noise_struct, bold_data_drift, nb_scans ) #### Computing Free Energy #### free_energy.append(vt.free_energy_computation( nrls_mean, nrls_covar, hrf_mean, hrf_covar, hrf_len, labels_proba, bold_data_drift, occurence_matrix, noise_var, noise_struct, nb_conditions, nb_voxels, nb_scans, nb_classes, nrls_class_mean, nrls_class_var, neighbours_indexes, beta, sigma_h, np.linalg.inv(hrf_regu_prior_inv), hrf_regu_prior_inv, gamma, hrf_hyperprior )) free_energy_crit.append(abs((free_energy[-2] - free_energy[-1]) / free_energy[-2])) logger.info("Convergence criteria: %f (Threshold = %f)", free_energy_crit[-1], thresh_free_energy) loop += 1 compute_time.append(time.time() - start_time) compute_time_mean = compute_time[-1] / loop mahalanobis_zero = np.nan mahalanobis_cano = np.nan mahalanobis_diff = np.nan mahalanobis_prod = np.nan variation_coeff = np.nan if estimate_hrf and not constrained and not normalizing: hrf_norm = np.linalg.norm(hrf_mean) hrf_mean /= hrf_norm hrf_covar /= hrf_norm ** 2 sigma_h /= hrf_norm ** 2 nrls_mean *= hrf_norm nrls_covar *= hrf_norm ** 2 nrls_class_mean *= hrf_norm nrls_class_var *= hrf_norm ** 2 mahalanobis_zero = mahalanobis(hrf_mean, np.zeros_like(hrf_mean), np.linalg.inv(hrf_covar)) mahalanobis_cano = mahalanobis(hrf_mean, m_h, np.linalg.inv(hrf_covar)) mahalanobis_diff = mahalanobis_cano - mahalanobis_zero mahalanobis_prod = mahalanobis_cano * mahalanobis_zero variation_coeff = np.sqrt((hrf_mean.T.dot(hrf_covar).dot(hrf_mean)) /(hrf_mean.T.dot(hrf_mean))**2) if estimate_hrf and zero_constraint: hrf_mean = np.concatenate(([0], hrf_mean, [0])) # when using the zero constraint the hrf covariance is fill with # arbitrary zeros around the matrix, this is maybe a bad idea if we need # it for later computation... hrf_covar = np.concatenate( (np.zeros((hrf_covar.shape[0], 1)), hrf_covar, np.zeros((hrf_covar.shape[0], 1))), axis=1 ) hrf_covar = np.concatenate( (np.zeros((1, hrf_covar.shape[1])), hrf_covar, np.zeros((1, hrf_covar.shape[1]))), axis=0 ) if estimate_hrf: (delay_of_response, delay_of_undershoot, dispersion_of_response, dispersion_of_undershoot, ratio_resp_under, delay) = vt.fit_hrf_two_gammas( hrf_mean, dt, hrf_duration ) else: (delay_of_response, delay_of_undershoot, dispersion_of_response, dispersion_of_undershoot, ratio_resp_under, delay) = (None, None, None, None, None, None) ppm_a_nrl, ppm_g_nrl = vt.ppms_computation( nrls_mean, np.diagonal(nrls_covar), nrls_class_mean, nrls_class_var, threshold_a="intersect" ) #+++++++++++++++++++++++ calculate contrast maps and variance +++++++++++++++++++++++# nb_contrasts = len(contrasts) if compute_contrasts and nb_contrasts > 0: logger.info('Computing contrasts ...') (contrasts_mean, contrasts_var, contrasts_class_mean, contrasts_class_var) = vt.contrasts_mean_var_classes( contrasts, condition_names, nrls_mean, nrls_covar, nrls_class_mean, nrls_class_var, nb_contrasts, nb_classes, nb_voxels ) ppm_a_contrasts, ppm_g_contrasts = vt.ppms_computation( contrasts_mean, contrasts_var, contrasts_class_mean, contrasts_class_var ) logger.info('Done computing contrasts.') else: (contrasts_mean, contrasts_var, contrasts_class_mean, contrasts_class_var, ppm_a_contrasts, ppm_g_contrasts) = (None, None, None, None, None, None) #+++++++++++++++++++++++ calculate contrast maps and variance +++++++++++++++++++++++# logger.info("Nb iterations to reach criterion: %d", loop) logger.info("Computational time = %s min %s s", *(str(int(x)) for x in divmod(compute_time[-1], 60))) logger.debug('nrls_class_mean: %s', nrls_class_mean) logger.debug('nrls_class_var: %s', nrls_class_var) logger.debug("sigma_H = %s", str(sigma_h)) logger.debug("beta = %s", str(beta)) stimulus_induced_signal = vt.computeFit(hrf_mean, nrls_mean, X, nb_voxels, nb_scans) snr = 20 * np.log( np.linalg.norm(bold_data.astype(np.float)) / np.linalg.norm((bold_data - stimulus_induced_signal - drift).astype(np.float)) ) snr /= np.log(10.) logger.info('snr comp = %f', snr) # ,FreeEnergyArray return (loop, nrls_mean, hrf_mean, hrf_covar, labels_proba, noise_var, nrls_class_mean, nrls_class_var, beta, drift_coeffs, drift, contrasts_mean, contrasts_var, compute_time[2:], compute_time_mean, nrls_covar, stimulus_induced_signal, mahalanobis_zero, mahalanobis_cano, mahalanobis_diff, mahalanobis_prod, ppm_a_nrl, ppm_g_nrl, ppm_a_contrasts, ppm_g_contrasts, variation_coeff, free_energy[1:], free_energy_crit[1:], beta_list[1:], delay_of_response, delay_of_undershoot, dispersion_of_response, dispersion_of_undershoot, ratio_resp_under, delay)
def Main_vbjde_Extension_constrained_stable(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.05, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, contrasts=[], computeContrast=False, gamma_h=0): """ Version modified by Lofti from Christine's version """ logger.info( "Fast EM with C extension started ... Here is the stable version !") np.random.seed(6537546) # Initialize parameters S = 100 if NitMax < 0: NitMax = 100 gamma = 7.5 # 7.5 gradientStep = 0.003 MaxItGrad = 200 Thresh = 1e-5 # Initialize sizes vectors D = np.int(np.ceil(Thrf / dt)) + 1 M = len(Onsets) N = Y.shape[0] J = Y.shape[1] l = np.int(np.sqrt(J)) condition_names = [] # Neighbours maxNeighbours = max([len(nl) for nl in graph]) neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32) neighboursIndexes -= 1 for i in xrange(J): neighboursIndexes[i, :len(graph[i])] = graph[i] # Conditions X = OrderedDict([]) for condition, Ons in Onsets.iteritems(): X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons) condition_names += [condition] XX = np.zeros((M, N, D), dtype=np.int32) nc = 0 for condition, Ons in Onsets.iteritems(): XX[nc, :, :] = X[condition] nc += 1 # Covariance matrix order = 2 D2 = vt.buildFiniteDiffMatrix(order, D) R = np.dot(D2, D2) / pow(dt, 2 * order) invR = np.linalg.inv(R) Det_invR = np.linalg.det(invR) Gamma = np.identity(N) Det_Gamma = np.linalg.det(Gamma) Crit_H = 1 Crit_Z = 1 Crit_A = 1 Crit_AH = 1 AH = np.zeros((J, M, D), dtype=np.float64) AH1 = np.zeros((J, M, D), dtype=np.float64) Crit_FreeEnergy = 1 cTime = [] cA = [] cH = [] cZ = [] cAH = [] CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64) CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64) Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64) XGamma = np.zeros((M, D, N), dtype=np.float64) m1 = 0 for k1 in X: # Loop over the M conditions m2 = 0 for k2 in X: Q_barnCond[m1, m2, :, :] = np.dot( np.dot(X[k1].transpose(), Gamma), X[k2]) m2 += 1 XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma) m1 += 1 sigma_epsilone = np.ones(J) logger.info( "Labels are initialized by setting active probabilities to ones ...") q_Z = np.zeros((M, K, J), dtype=np.float64) q_Z[:, 1, :] = 1 q_Z1 = np.zeros((M, K, J), dtype=np.float64) Z_tilde = q_Z.copy() TT, m_h = getCanoHRF(Thrf, dt) # TODO: check m_h = m_h[:D] m_H = np.array(m_h).astype(np.float64) m_H1 = np.array(m_h) sigmaH1 = sigmaH Sigma_H = np.ones((D, D), dtype=np.float64) Beta = beta * np.ones((M), dtype=np.float64) P = vt.PolyMat(N, 4, TR) L = vt.polyFit(Y, TR, 4, P) PL = np.dot(P, L) y_tilde = Y - PL Ndrift = L.shape[0] sigma_M = np.ones((M, K), dtype=np.float64) sigma_M[:, 0] = 0.5 sigma_M[:, 1] = 0.6 mu_M = np.zeros((M, K), dtype=np.float64) for k in xrange(1, K): mu_M[:, k] = 1 # InitMean Sigma_A = np.zeros((M, M, J), np.float64) for j in xrange(0, J): Sigma_A[:, :, j] = 0.01 * np.identity(M) m_A = np.zeros((J, M), dtype=np.float64) m_A1 = np.zeros((J, M), dtype=np.float64) for j in xrange(0, J): for m in xrange(0, M): for k in xrange(0, K): m_A[j, m] += np.random.normal(mu_M[m, k], np.sqrt(sigma_M[m, k])) * q_Z[m, k, j] m_A1 = m_A t1 = time.time() ########################################################################## # VBJDE num. iter. minimum ni = 0 while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (ni < NitMax))): logger.info("------------------------------ Iteration n° " + str(ni + 1) + " ------------------------------") ##################### # EXPECTATION ##################### # A logger.info("E A step ...") UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K) # crit. A DIFF = np.reshape(m_A - m_A1, (M * J)) Crit_A = ( np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2 cA += [Crit_A] m_A1[:, :] = m_A[:, :] # HRF h UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH) #m_H[0] = 0 #m_H[-1] = 0 # Constrain with optimization strategy import cvxpy as cvx m, n = Sigma_H.shape Sigma_H_inv = np.linalg.inv(Sigma_H) zeros_H = np.zeros_like(m_H[:, np.newaxis]) # Construct the problem. PRIMAL h = cvx.Variable(n) expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv) objective = cvx.Minimize(expression) #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1] constraints = [h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1] prob = cvx.Problem(objective, constraints) result = prob.solve(verbose=0, solver=cvx.CVXOPT) # Now we update the mean of h m_H_old = m_H Sigma_H_old = Sigma_H m_H = np.squeeze(np.array((h.value))) Sigma_H = np.zeros_like(Sigma_H) # and the norm h_norm += [np.linalg.norm(m_H)] # crit. h Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2 cH += [Crit_H] m_H1[:] = m_H[:] # crit. AH for d in xrange(0, D): AH[:, :, d] = m_A[:, :] * m_H[d] DIFF = np.reshape(AH - AH1, (M * J * D)) Crit_AH = (np.linalg.norm( DIFF) / (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2 cAH += [Crit_AH] AH1[:, :, :] = AH[:, :, :] # Z labels logger.info("E Z step ...") UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours) # crit. Z DIFF = np.reshape(q_Z - q_Z1, (M * K * J)) Crit_Z = (np.linalg.norm(DIFF) / (np.linalg.norm(np.reshape(q_Z1, (M * K * J))) + eps)) ** 2 cZ += [Crit_Z] q_Z1[:, :, :] = q_Z[:, :, :] ##################### # MAXIMIZATION ##################### # HRF: Sigma_h if estimateSigmaH: logger.info("M sigma_H step ...") if gamma_h > 0: sigmaH = vt.maximization_sigmaH_prior( D, Sigma_H, R, m_H, gamma_h) else: sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H) logger.info('sigmaH = %s', str(sigmaH)) # (mu,sigma) logger.info("M (mu,sigma) step ...") mu_M, sigma_M = vt.maximization_mu_sigma( mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A) # Drift L UtilsC.maximization_L( Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N) PL = np.dot(P, L) y_tilde = Y - PL # Beta if estimateBeta: logger.info("estimating beta") for m in xrange(0, M): Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype( np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep) logger.info("End estimating beta") logger.info(Beta) # Sigma noise logger.info("M sigma noise step ...") UtilsC.maximization_sigma_noise( Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N) t02 = time.time() cTime += [t02 - t1] t2 = time.time() ########################################################################## # PLOTS and SNR computation if PLOT and 0: font = {'size': 15} matplotlib.rc('font', **font) savefig('./HRF_Iter_CompMod.png') hold(False) figure(2) plot(cAH[1:-1], 'lightblue') hold(True) plot(cFE[1:-1], 'm') hold(False) legend(('CAH', 'CFE')) grid(True) savefig('./Crit_CompMod.png') figure(3) plot(FreeEnergyArray) grid(True) savefig('./FreeEnergy_CompMod.png') figure(4) for m in xrange(M): plot(SUM_q_Z_array[m]) hold(True) hold(False) savefig('./Sum_q_Z_Iter_CompMod.png') figure(5) for m in xrange(M): plot(mu1_array[m]) hold(True) hold(False) savefig('./mu1_Iter_CompMod.png') figure(6) plot(h_norm_array) savefig('./HRF_Norm_CompMod.png') Data_save = xndarray(h_norm_array, ['Iteration']) Data_save.save('./HRF_Norm_Comp.nii') CompTime = t2 - t1 cTimeMean = CompTime / ni """ Norm = np.linalg.norm(m_H) m_H /= Norm Sigma_H /= Norm**2 sigmaH /= Norm**2 m_A *= Norm Sigma_A *= Norm**2 mu_M *= Norm sigma_M *= Norm**2 sigma_M = np.sqrt(np.sqrt(sigma_M)) """ logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str( np.int(CompTime // 60)), str(np.int(CompTime % 60))) logger.info('mu_M: %f', mu_M) logger.info('sigma_M: %f', sigma_M) logger.info("sigma_H = %s", str(sigmaH)) logger.info("Beta = %s", str(Beta)) StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N) SNR = 20 * \ np.log( np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL)) SNR /= np.log(10.) logger.info('SNR comp = %f', SNR) return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal
def jde_vem_bold(graph, bold_data, onsets, durations, hrf_duration, nb_classes, tr, beta, dt, estimate_sigma_h=True, sigma_h=0.05, it_max=-1, it_min=0, estimate_beta=True, contrasts=None, compute_contrasts=False, hrf_hyperprior=0, estimate_hrf=True, constrained=False, zero_constraint=True, drifts_type="poly", seed=6537546): """This is the main function that computes the VEM analysis on BOLD data. This function uses optimized python functions. Parameters ---------- graph : ndarray of lists represents the neighbours indexes of each voxels index bold_data : ndarray, shape (nb_scans, nb_voxels) raw data onsets : dict dictionnary of onsets durations : # TODO # TODO hrf_duration : float hrf total time duration (in s) nb_classes : int the number of classes to classify the nrls. This parameter is provided for development purposes as most of the algorithm implies two classes tr : float time of repetition beta : float the initial value of beta dt : float hrf temporal precision estimate_sigma_h : bool, optional toggle estimation of sigma H sigma_h : float, optional initial or fixed value of sigma H it_max : int, optional maximal computed iteration number it_min : int, optional minimal computed iteration number estimate_beta : bool, optional toggle the estimation of beta contrasts : OrderedDict, optional dict of contrasts to compute compute_contrasts : bool, optional if True, compute the contrasts defined in contrasts hrf_hyperprior : float # TODO estimate_hrf : bool, optional if True, estimate the HRF for each parcel, if False use the canonical HRF constrained : bool, optional if True, add a constrains the l2 norm of the HRF to 1 zero_constraint : bool, optional if True, add zeros to the beginning and the end of the estimated HRF. drifts_type : str, optional set the drifts basis type used. Can be "poly" for polynomial or "cos" for cosine seed : int, optional seed used by numpy to initialize random generator number Returns ------- loop : int number of iterations before convergence nrls_mean : ndarray, shape (nb_voxels, nb_conditions) Neural response level mean value hrf_mean : ndarray, shape (hrf_len,) Hemodynamic response function mean value hrf_covar : ndarray, shape (hrf_len, hrf_len) Covariance matrix of the HRF labels_proba : ndarray, shape (nb_conditions, nb_classes, nb_voxels) probability of voxels being in one class noise_var : ndarray, shape (nb_voxels,) estimated noise variance nrls_class_mean : ndarray, shape (nb_conditions, nb_classes) estimated mean value of the gaussians of the classes nrls_class_var : ndarray, shape (nb_conditions, nb_classes) estimated variance of the gaussians of the classes beta : ndarray, shape (nb_conditions,) estimated beta drift_coeffs : ndarray, shape (# TODO) estimated coefficient of the drifts drift : ndarray, shape (# TODO) estimated drifts contrasts_mean : ndarray, shape (nb_voxels, len(contrasts)) Contrasts computed from NRLs contrasts_var : ndarray, shape (nb_voxels, len(contrasts)) Variance of the contrasts compute_time : list computation time of each iteration compute_time_mean : float computation mean time over iterations nrls_covar : ndarray, shape (nb_conditions, nb_conditions, nb_voxels) # TODO stimulus_induced_signal : ndarray, shape (nb_scans, nb_voxels) # TODO mahalanobis_zero : float Mahalanobis distance between estimated hrf_mean and the null vector mahalanobis_cano : float Mahalanobis distance between estimated hrf_mean and the canonical HRF mahalanobis_diff : float difference between mahalanobis_cano and mahalanobis_diff mahalanobis_prod : float product of mahalanobis_cano and mahalanobis_diff ppm_a_nrl : ndarray, shape (nb_voxels,) The posterior probability map using an alpha ppm_g_nrl : ndarray, shape (nb_voxels,) # TODO ppm_a_contrasts : ndarray, shape (nb_voxels,) # TODO ppm_g_contrasts : ndarray, shape (nb_voxels,) # TODO variation_coeff : float coefficient of variation of the HRF free_energy : list # TODO Notes ----- See `A novel definition of the multivariate coefficient of variation <http://onlinelibrary.wiley.com/doi/10.1002/bimj.201000030/abstract>`_ article for more information about the coefficient of variation. """ logger.info("VEM started.") if not contrasts: contrasts = OrderedDict() np.random.seed(seed) nb_2_norm = 1 normalizing = False regularizing = False if it_max <= 0: it_max = 100 gamma = 7.5 # Initialize sizes vectors hrf_len = np.int(np.ceil(hrf_duration / dt)) + 1 nb_conditions = len(onsets) nb_scans = bold_data.shape[0] nb_voxels = bold_data.shape[1] X, occurence_matrix, condition_names = vt.create_conditions( onsets, durations, nb_conditions, nb_scans, hrf_len, tr, dt) neighbours_indexes = vt.create_neighbours(graph) order = 2 if regularizing: regularization = np.ones(hrf_len) regularization[hrf_len // 3:hrf_len // 2] = 2 regularization[hrf_len // 2:2 * hrf_len // 3] = 5 regularization[2 * hrf_len // 3:3 * hrf_len // 4] = 7 regularization[3 * hrf_len // 4:] = 10 # regularization[hrf_len//2:] = 10 else: regularization = None d2 = vt.buildFiniteDiffMatrix(order, hrf_len, regularization) hrf_regu_prior_inv = d2.T.dot(d2) / pow(dt, 2 * order) if estimate_hrf and zero_constraint: hrf_len = hrf_len - 2 hrf_regu_prior_inv = hrf_regu_prior_inv[1:-1, 1:-1] occurence_matrix = occurence_matrix[:, :, 1:-1] noise_struct = np.identity(nb_scans) noise_var = np.ones(nb_voxels) if nb_classes != 2: logger.warn('The number of classes is different to two.') labels_proba = np.zeros((nb_conditions, nb_classes, nb_voxels), dtype=np.float64) logger.info("Labels are initialized by setting everything to {}".format( 1. / nb_classes)) labels_proba[:, :, :] = 1. / nb_classes m_h = getCanoHRF(hrf_duration, dt)[1][:hrf_len] hrf_mean = np.array(m_h).astype(np.float64) if estimate_hrf: hrf_covar = np.identity(hrf_len, dtype=np.float64) else: hrf_covar = np.zeros((hrf_len, hrf_len), dtype=np.float64) beta = beta * np.ones(nb_conditions, dtype=np.float64) beta_list = [beta.copy()] if drifts_type == "poly": drift_basis = vt.poly_drifts_basis(nb_scans, 4, tr) elif drifts_type == "cos": drift_basis = vt.cosine_drifts_basis(nb_scans, 64, tr) else: raise Exception('drift type "%s" is not supported' % drifts_type) drift_coeffs = vt.drifts_coeffs_fit(bold_data, drift_basis) drift = drift_basis.dot(drift_coeffs) bold_data_drift = bold_data - drift # Parameters Gaussian mixtures nrls_class_mean = 2 * np.ones((nb_conditions, nb_classes)) nrls_class_mean[:, 0] = 0 nrls_class_var = 0.3 * np.ones( (nb_conditions, nb_classes), dtype=np.float64) nrls_mean = ( np.random.normal(nrls_class_mean, nrls_class_var)[:, :, np.newaxis] * labels_proba).sum(axis=1).T nrls_covar = np.identity(nb_conditions)[:, :, np.newaxis] + np.zeros( (1, 1, nb_voxels)) thresh_free_energy = 1e-4 free_energy = [1.] free_energy_crit = [1.] compute_time = [] start_time = time.time() loop = 0 while (loop <= it_min or ((np.asarray(free_energy_crit[-5:]) > thresh_free_energy).any() and loop < it_max)): logger.info("{:-^80}".format(" Iteration n°" + str(loop + 1) + " ")) logger.info("Expectation A step...") logger.debug("Before: nrls_mean = %s, nrls_covar = %s", nrls_mean, nrls_covar) nrls_mean, nrls_covar = vt.nrls_expectation( hrf_mean, nrls_mean, occurence_matrix, noise_struct, labels_proba, nrls_class_mean, nrls_class_var, nb_conditions, bold_data_drift, nrls_covar, hrf_covar, noise_var) logger.debug("After: nrls_mean = %s, nrls_covar = %s", nrls_mean, nrls_covar) logger.info("Expectation Z step...") logger.debug("Before: labels_proba = %s, labels_proba = %s", labels_proba, labels_proba) labels_proba = vt.labels_expectation(nrls_covar, nrls_mean, nrls_class_var, nrls_class_mean, beta, labels_proba, neighbours_indexes, nb_conditions, nb_classes, nb_voxels, parallel=True) logger.debug("After: labels_proba = %s, labels_proba = %s", labels_proba, labels_proba) if estimate_hrf: logger.info("Expectation H step...") logger.debug("Before: hrf_mean = %s, hrf_covar = %s", hrf_mean, hrf_covar) hrf_mean, hrf_covar = vt.hrf_expectation( nrls_covar, nrls_mean, occurence_matrix, noise_struct, hrf_regu_prior_inv, sigma_h, nb_voxels, bold_data_drift, noise_var) if constrained: hrf_mean = vt.norm1_constraint(hrf_mean, hrf_covar) hrf_covar[:] = 0 logger.debug("After: hrf_mean = %s, hrf_covar = %s", hrf_mean, hrf_covar) # Normalizing H at each nb_2_norm iterations: if not constrained and normalizing: # Normalizing is done before sigma_h, nrls_class_mean and nrls_class_var estimation # we should not include them in the normalisation step if (loop + 1) % nb_2_norm == 0: hrf_norm = np.linalg.norm(hrf_mean) hrf_mean /= hrf_norm hrf_covar /= hrf_norm**2 nrls_mean *= hrf_norm nrls_covar *= hrf_norm**2 if estimate_hrf and estimate_sigma_h: logger.info("Maximization sigma_H step...") logger.debug("Before: sigma_h = %s", sigma_h) if hrf_hyperprior > 0: sigma_h = vt.maximization_sigmaH_prior(hrf_len, hrf_covar, hrf_regu_prior_inv, hrf_mean, hrf_hyperprior) else: sigma_h = vt.maximization_sigmaH(hrf_len, hrf_covar, hrf_regu_prior_inv, hrf_mean) logger.debug("After: sigma_h = %s", sigma_h) logger.info("Maximization (mu,sigma) step...") logger.debug("Before: nrls_class_mean = %s, nrls_class_var = %s", nrls_class_mean, nrls_class_var) nrls_class_mean, nrls_class_var = vt.maximization_class_proba( labels_proba, nrls_mean, nrls_covar) logger.debug("After: nrls_class_mean = %s, nrls_class_var = %s", nrls_class_mean, nrls_class_var) logger.info("Maximization L step...") logger.debug("Before: drift_coeffs = %s", drift_coeffs) drift_coeffs = vt.maximization_drift_coeffs(bold_data, nrls_mean, occurence_matrix, hrf_mean, noise_struct, drift_basis) logger.debug("After: drift_coeffs = %s", drift_coeffs) drift = drift_basis.dot(drift_coeffs) bold_data_drift = bold_data - drift if estimate_beta: logger.info("Maximization beta step...") for cond_nb in xrange(0, nb_conditions): beta[cond_nb], success = vt.beta_maximization( beta[cond_nb] * np.ones((1, )), labels_proba[cond_nb, :, :], neighbours_indexes, gamma) beta_list.append(beta.copy()) logger.debug("beta = %s", str(beta)) logger.info("Maximization sigma noise step...") noise_var = vt.maximization_noise_var(occurence_matrix, hrf_mean, hrf_covar, nrls_mean, nrls_covar, noise_struct, bold_data_drift, nb_scans) # Computing Free Energy free_energy.append( vt.free_energy_computation( nrls_mean, nrls_covar, hrf_mean, hrf_covar, hrf_len, labels_proba, bold_data_drift, occurence_matrix, noise_var, noise_struct, nb_conditions, nb_voxels, nb_scans, nb_classes, nrls_class_mean, nrls_class_var, neighbours_indexes, beta, sigma_h, np.linalg.inv(hrf_regu_prior_inv), hrf_regu_prior_inv, gamma, hrf_hyperprior)) free_energy_crit.append( abs((free_energy[-2] - free_energy[-1]) / free_energy[-2])) logger.info("Convergence criteria: %f (Threshold = %f)", free_energy_crit[-1], thresh_free_energy) loop += 1 compute_time.append(time.time() - start_time) compute_time_mean = compute_time[-1] / loop mahalanobis_zero = np.nan mahalanobis_cano = np.nan mahalanobis_diff = np.nan mahalanobis_prod = np.nan variation_coeff = np.nan if estimate_hrf and not constrained and not normalizing: hrf_norm = np.linalg.norm(hrf_mean) hrf_mean /= hrf_norm hrf_covar /= hrf_norm**2 sigma_h /= hrf_norm**2 nrls_mean *= hrf_norm nrls_covar *= hrf_norm**2 nrls_class_mean *= hrf_norm nrls_class_var *= hrf_norm**2 mahalanobis_zero = mahalanobis(hrf_mean, np.zeros_like(hrf_mean), np.linalg.inv(hrf_covar)) mahalanobis_cano = mahalanobis(hrf_mean, m_h, np.linalg.inv(hrf_covar)) mahalanobis_diff = mahalanobis_cano - mahalanobis_zero mahalanobis_prod = mahalanobis_cano * mahalanobis_zero variation_coeff = np.sqrt((hrf_mean.T.dot(hrf_covar).dot(hrf_mean)) / (hrf_mean.T.dot(hrf_mean))**2) if estimate_hrf and zero_constraint: hrf_mean = np.concatenate(([0], hrf_mean, [0])) # when using the zero constraint the hrf covariance is fill with # arbitrary zeros around the matrix, this is maybe a bad idea if we need # it for later computation... hrf_covar = np.concatenate((np.zeros( (hrf_covar.shape[0], 1)), hrf_covar, np.zeros((hrf_covar.shape[0], 1))), axis=1) hrf_covar = np.concatenate((np.zeros( (1, hrf_covar.shape[1])), hrf_covar, np.zeros((1, hrf_covar.shape[1]))), axis=0) if estimate_hrf: (delay_of_response, delay_of_undershoot, dispersion_of_response, dispersion_of_undershoot, ratio_resp_under, delay) = vt.fit_hrf_two_gammas(hrf_mean, dt, hrf_duration) else: (delay_of_response, delay_of_undershoot, dispersion_of_response, dispersion_of_undershoot, ratio_resp_under, delay) = (None, None, None, None, None, None) ppm_a_nrl, ppm_g_nrl = vt.ppms_computation(nrls_mean, np.diagonal(nrls_covar), nrls_class_mean, nrls_class_var, threshold_a="intersect") # Calculate contrast maps and variance nb_contrasts = len(contrasts) if compute_contrasts and nb_contrasts > 0: logger.info('Computing contrasts ...') (contrasts_mean, contrasts_var, contrasts_class_mean, contrasts_class_var) = vt.contrasts_mean_var_classes( contrasts, condition_names, nrls_mean, nrls_covar, nrls_class_mean, nrls_class_var, nb_contrasts, nb_classes, nb_voxels) ppm_a_contrasts, ppm_g_contrasts = vt.ppms_computation( contrasts_mean, contrasts_var, contrasts_class_mean, contrasts_class_var) logger.info('Done computing contrasts.') else: (contrasts_mean, contrasts_var, contrasts_class_mean, contrasts_class_var, ppm_a_contrasts, ppm_g_contrasts) = (None, None, None, None, None, None) logger.info("Number of iterations to reach criterion: %d", loop) logger.info("Computational time = {t[0]:.0f} min {t[1]:.0f} s".format( t=divmod(compute_time[-1], 60))) logger.debug('nrls_class_mean: %s', nrls_class_mean) logger.debug('nrls_class_var: %s', nrls_class_var) logger.debug("sigma_H = %s", str(sigma_h)) logger.debug("beta = %s", str(beta)) stimulus_induced_signal = vt.computeFit(hrf_mean, nrls_mean, X, nb_voxels, nb_scans) snr = 20 * np.log( np.linalg.norm(bold_data.astype(np.float)) / np.linalg.norm( (bold_data_drift - stimulus_induced_signal).astype(np.float))) snr /= np.log(10.) logger.info('SNR comp = %f', snr) return (loop, nrls_mean, hrf_mean, hrf_covar, labels_proba, noise_var, nrls_class_mean, nrls_class_var, beta, drift_coeffs, drift, contrasts_mean, contrasts_var, compute_time[2:], compute_time_mean, nrls_covar, stimulus_induced_signal, mahalanobis_zero, mahalanobis_cano, mahalanobis_diff, mahalanobis_prod, ppm_a_nrl, ppm_g_nrl, ppm_a_contrasts, ppm_g_contrasts, variation_coeff, free_energy[1:], free_energy_crit[1:], beta_list[1:], delay_of_response, delay_of_undershoot, dispersion_of_response, dispersion_of_undershoot, ratio_resp_under, delay)
def create_canonical_hrf(hrf_duration=25.0, dt=0.5): return shrf.getCanoHRF(hrf_duration, dt)[1]
def Main_vbjde_physio(graph, Y, Onsets, durations, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, estimateSigmaG=True, sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0, NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False, contrasts=[], computeContrast=False, idx_first_tag=0, simulation=None, sigmaMu=None, estimateH=True, estimateG=True, estimateA=True, estimateC=True, estimateZ=True, estimateNoise=True, estimateMP=True, estimateLA=True, use_hyperprior=False, positivity=False, constraint=False, phy_params=PHY_PARAMS_KHALIDOV11, prior='omega', zc=False): logger.info("EM for ASL!") np.random.seed(6537540) logger.info("data shape: ") logger.info(Y.shape) Thresh = 1e-5 D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets) #D, M = np.int(np.ceil(Thrf / dt)), len(Onsets) n_sess, N, J = Y.shape[0], Y.shape[1], Y.shape[2] Crit_AH, Crit_CG, cTime, rerror, FE = 1, 1, [], [], [] EP, EPlh, Ent = [],[],[] Crit_H, Crit_G, Crit_Z, Crit_A, Crit_C = 1, 1, 1, 1, 1 cAH, cCG, AH1, CG1 = [], [], [], [] cA, cC, cH, cG, cZ = [], [], [], [], [] h_norm, g_norm = [], [] SUM_q_Z = [[] for m in xrange(M)] mua1 = [[] for m in xrange(M)] muc1 = [[] for m in xrange(M)] sigmaH = sigmaH * J / 100 print sigmaH gamma_h = gamma_h * 100 / J print gamma_h # Beta data MaxItGrad = 200 gradientStep = 0.005 gamma = 7.5 print 'gamma = ', gamma print 'voxels = ', J maxNeighbours, neighboursIndexes = vt.create_neighbours(graph, J) print 'graph.shape = ', graph.shape # Conditions print 'Onsets: ', Onsets print 'durations = ', durations print 'creating conditions...' X, XX, condition_names = vt.create_conditions_block_ms(Onsets, durations, M, N, D, n_sess, TR, dt) # Covariance matrix #R = vt.covariance_matrix(2, D, dt) _, R_inv = genGaussianSmoothHRF(zc, D, dt, 1., 2) R = np.linalg.inv(R_inv) if zc: XX = XX[:, :, :, 1:-1] # XX shape (S, M, N, D) D = D - 2 AH1, CG1 = np.zeros((J, M, D)), np.zeros((J, M, D)) print 'HRF length = ', D print 'Condition number = ', M print 'Number of scans = ', N print 'Number of voxels = ', J print 'Number of sessions = ', n_sess print 'XX.shape = ', XX.shape # Noise matrix Gamma = np.identity(N) # Noise initialization sigma_eps = np.ones((n_sess, J)) # Labels logger.info("Labels are initialized by setting active probabilities " "to ones ...") q_Z = np.ones((M, K, J), dtype=np.float64) / 2. #q_Z = np.zeros((M, K, J), dtype=np.float64) #q_Z[:, 1, :] = 1 q_Z1 = copy.deepcopy(q_Z) Z_tilde = copy.deepcopy(q_Z) # H and G TT, m_h = getCanoHRF(Thrf, dt) H = np.array(m_h[:D]).astype(np.float64) H /= np.linalg.norm(H) Hb = create_physio_brf(phy_params, response_dt=dt, response_duration=Thrf) Hb /= np.linalg.norm(Hb) if prior=='balloon': H = Hb.copy() H1 = copy.deepcopy(H) Sigma_H = np.zeros((D, D), dtype=np.float64) # Initialize model parameters Beta = beta * np.ones((M), dtype=np.float64) n_drift = 4 P = np.zeros((n_sess, N, n_drift+1), dtype=np.float64) L = np.zeros((n_drift+1, J, n_sess), dtype=np.float64) for s in xrange(0, n_sess): P[s, :, :] = vt.PolyMat(N, n_drift, TR) L[:, :, s] = vt.polyFit(Y[s, :, :], TR, n_drift, P[s, :, :]) print 'P shape = ', P.shape print 'L shape = ', L.shape WP = P.copy() AL = L.copy() PL = np.einsum('ijk,kli->ijl', P, L) y_tilde = Y - PL # Parameters Gaussian mixtures mu_Ma = np.append(np.zeros((M, 1)), np.ones((M, 1)), axis=1).astype(np.float64) sigma_Ma = np.ones((M, K), dtype=np.float64) * 0.3 # Params RLs m_A = np.zeros((n_sess, J, M), dtype=np.float64) for s in xrange(0, n_sess): for j in xrange(0, J): m_A[s, j, :] = (np.random.normal(mu_Ma, np.sqrt(sigma_Ma)) * q_Z[:, :, j]).sum(axis=1).T m_A1 = m_A.copy() Sigma_A = np.ones((M, M, J, n_sess)) * np.identity(M)[:, :, np.newaxis, np.newaxis] G = np.zeros_like(H) m_C = np.zeros_like(m_A) Sigma_G = np.zeros_like(Sigma_H) Sigma_C = np.zeros_like(Sigma_A) mu_Mc = np.zeros_like(mu_Ma) sigma_Mc = np.ones_like(sigma_Ma) W = np.zeros_like(Gamma) # (N, N) # Precomputations print 'W shape is ', W.shape WX = W.dot(XX).transpose(1, 2, 0, 3) # shape (S, M, N, D) Gamma_X = np.zeros((N, n_sess, M, D), dtype=np.float64) # shape (N, S, M, D) X_Gamma_X = np.zeros((D, M, n_sess, M, D), dtype=np.float64) # shape (D, M, S, M, D) Gamma_WX = np.zeros((N, n_sess, M, D), dtype=np.float64) # shape (N, S, M, D) XW_Gamma_WX = np.zeros((D, M, n_sess, M, D), dtype=np.float64) # shape (D, M, S, M, D) Gamma_WP = np.zeros((N, n_sess, n_drift+1), dtype=np.float64) # shape (N, S, M, D) WP_Gamma_WP = np.zeros((n_sess, n_drift+1, n_drift+1), dtype=np.float64) # shape (D, M, S, M, D) for s in xrange(0, n_sess): Gamma_X[:, s, :, :] = np.tensordot(Gamma, XX[s, :, :, :], axes=(1, 1)) X_Gamma_X[:, :, s, :, :] = np.tensordot(XX[s, :, :, :].T, Gamma_X[:, s, :, :], axes=(1, 0)) Gamma_WX[:, s, :, :] = np.tensordot(Gamma, WX[s, :, :, :], axes=(1, 1)) XW_Gamma_WX[:, :, s, :, :] = np.tensordot(WX[s, :, :, :].T, Gamma_WX[:, s, :, :], axes=(1, 0)) Gamma_WP[:, s, :] = Gamma.dot(WP[s, :, :]) # (N, n_drift) WP_Gamma_WP[s, :, :] = WP[s, :, :].T.dot(Gamma_WP[:, s, :]) # (n_drift, n_drift) sigma_eps_m = np.maximum(sigma_eps, eps) # (n_sess, J) cov_noise = sigma_eps_m[:, :, np.newaxis, np.newaxis] # (n_sess, J, 1, 1) ########################################################################### ############################################# VBJDE t1 = time.time() ni = 0 #while ((ni < NitMin + 1) or (((Crit_AH > Thresh) or (Crit_CG > Thresh)) \ # and (ni < NitMax))): #while ((ni < NitMin + 1) or (((Crit_AH > Thresh)) \ # and (ni < NitMax))): while ((ni < NitMin + 1) or (((Crit_FE > Thresh * np.ones_like(Crit_FE)).any()) \ and (ni < NitMax))): logger.info("-------- Iteration n° " + str(ni + 1) + " --------") if PLOT and ni >= 0: # Plotting HRF and PRF logger.info("Plotting HRF and PRF for current iteration") vt.plot_response_functions_it(ni, NitMin, M, H, G) # Managing types of prior priorH_cov_term = np.zeros_like(R_inv) matrix_covH = R_inv.copy() if prior=='balloon': logger.info(" prior balloon") #matrix_covH = np.eye(R_inv.shape[0], R_inv.shape[1]) priorH_mean_term = np.dot(matrix_covH / sigmaH, Hb) else: logger.info(" NO prior") priorH_mean_term = np.zeros_like(H) priorG_mean_term = np.zeros_like(G) ##################### # EXPECTATION ##################### # HRF H if estimateH: logger.info("E H step ...") Ht, Sigma_H = vt.expectation_H_ms(Sigma_A, m_A, m_C, G, XX, W, Gamma, Gamma_X, X_Gamma_X, J, y_tilde, cov_noise, matrix_covH, sigmaH, priorH_mean_term, priorH_cov_term, N, M, D, n_sess) if constraint: if not np.linalg.norm(Ht)==1: logger.info(" constraint l2-norm = 1") H = vt.constraint_norm1_b(Ht, Sigma_H) #H = Ht / np.linalg.norm(Ht) else: logger.info(" l2-norm already 1!!!!!") H = Ht.copy() Sigma_H = np.zeros_like(Sigma_H) else: H = Ht.copy() h_norm = np.append(h_norm, np.linalg.norm(H)) print 'h_norm = ', h_norm Crit_H = (np.linalg.norm(H - H1) / np.linalg.norm(H1)) ** 2 cH += [Crit_H] H1[:] = H[:] # A if estimateA: logger.info("E A step ...") m_A, Sigma_A = vt.expectation_A_ms(m_A, Sigma_A, H, G, m_C, W, XX, Gamma, Gamma_X, q_Z, mu_Ma, sigma_Ma, J, y_tilde, Sigma_H, sigma_eps_m, N, M, D, n_sess) cA += [(np.linalg.norm(m_A - m_A1) / np.linalg.norm(m_A1)) ** 2] m_A1[:, :, :] = m_A[:, :, :] # Q labels if estimateZ: logger.info("E Q step ...") q_Z, Z_tilde = vt.expectation_Q_ms(Sigma_A, m_A, Sigma_C, m_C, sigma_Ma, mu_Ma, sigma_Mc, mu_Mc, Beta, Z_tilde, q_Z, neighboursIndexes, graph, M, J, K, n_sess) if 0: import matplotlib.pyplot as plt plt.close('all') fig = plt.figure(1) for m in xrange(M): ax = fig.add_subplot(2, M, m + 1) im = ax.matshow(m_A[:, :, m].mean(0).reshape(20, 20)) plt.colorbar(im, ax=ax) ax = fig.add_subplot(2, M, m + 3) im = ax.matshow(q_Z[m, 1, :].reshape(20, 20)) plt.colorbar(im, ax=ax) fig = plt.figure(2) for m in xrange(M): for s in xrange(n_sess): ax = fig.add_subplot(M, n_sess, n_sess * m + s + 1) im = ax.matshow(m_A[s, :, m].reshape(20, 20)) plt.colorbar(im, ax=ax) plt.show() cZ += [(np.linalg.norm(q_Z - q_Z1) / (np.linalg.norm(q_Z1) + eps)) ** 2] q_Z1 = q_Z if ni > 0: free_energyE = 0 for s in xrange(n_sess): free_energyE += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess) if free_energyE < free_energy: logger.info("free energy has decreased after E step from %f to %f", free_energy, free_energyE) # crit. AH and CG logger.info("crit. AH and CG") AH = m_A[:, :, :, np.newaxis] * H[np.newaxis, np.newaxis, :] Crit_AH = (np.linalg.norm(AH - AH1) / (np.linalg.norm(AH1) + eps)) ** 2 cAH += [Crit_AH] AH1 = AH.copy() logger.info("Crit_AH = " + str(Crit_AH)) ##################### # MAXIMIZATION ##################### if prior=='balloon': logger.info(" prior balloon") AuxH = H - Hb AuxG = G - Gb else: logger.info(" NO prior") AuxH = H.copy() AuxG = G.copy() # Variance HRF: sigmaH if estimateSigmaH: logger.info("M sigma_H step ...") sigmaH = vt.maximization_sigma_asl(D, Sigma_H, matrix_covH, AuxH, use_hyperprior, gamma_h) logger.info('sigmaH = ' + str(sigmaH)) if ni > 0: free_energyVh = 0 for s in xrange(n_sess): free_energyVh += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess) if free_energyVh < free_energyE: logger.info("free energy has decreased after v_h computation from %f to %f", free_energyE, free_energyVh) # (mu,sigma) if estimateMP: logger.info("M (mu,sigma) a and c step ...") #print 'q_Z = ', q_Z #print q_Z.shape mu_Ma, sigma_Ma = vt.maximization_mu_sigma_ms(q_Z, m_A, Sigma_A, M, J, n_sess, K) print 'mu_Ma = ', mu_Ma print 'sigma_Ma = ', sigma_Ma if ni > 0: free_energyMP = 0 for s in xrange(n_sess): free_energyMP += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess) if free_energyMP < free_energyVh: logger.info("free energy has decreased after GMM parameters computation from %f to %f", free_energyVh, free_energyMP) # Drift L, alpha if estimateLA: logger.info("M L, alpha step ...") for s in xrange(n_sess): AL[:, :, s] = vt.maximization_LA_asl(Y[s, :, :], m_A[s, :, :], m_C[s, :, :], XX[s, :, :, :], WP[s, :, :], W, WP_Gamma_WP[s, :, :], H, G, Gamma) PL = np.einsum('ijk,kli->ijl', WP, AL) y_tilde = Y - PL if ni > 0: free_energyLA = 0 for s in xrange(n_sess): free_energyLA += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess) if free_energyLA < free_energyMP: logger.info("free energy has decreased after drifts computation from %f to %f", free_energyMP, free_energyLA) # Beta if estimateBeta: logger.info("M beta step ...") """Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2) Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3) Beta = vt.maximization_beta_m2(Beta.copy(), q_Z, Qtilde_sumneighbour, Qtilde, neighboursIndexes, maxNeighbours, gamma, MaxItGrad, gradientStep) logger.info(Beta) """ logger.info("M beta step ...") Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2) Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3) for m in xrange(0, M): Beta[m] = vt.maximization_beta_m2_scipy_asl(Beta[m].copy(), q_Z[m, :, :], Qtilde_sumneighbour[m, :, :], Qtilde[m, :, :], neighboursIndexes, maxNeighbours, gamma, MaxItGrad, gradientStep) logger.info(Beta) if ni > 0: free_energyB = 0 for s in xrange(n_sess): free_energyB += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess) if free_energyB < free_energyLA: logger.info("free energy has decreased after Beta computation from %f to %f", \ free_energyLA, free_energyB) if 0 and ni < 5: plt.close('all') for m in xrange(0, M): range_b = np.arange(-10., 20., 0.1) beta_plotting = np.zeros_like(range_b) grad_plotting = np.zeros_like(range_b) for ib, b in enumerate(range_b): beta_plotting[ib] = vt.fun(b, q_Z[m, :, :], Qtilde_sumneighbour[m, :, :], neighboursIndexes, gamma) grad_plotting[ib] = vt.grad_fun(b, q_Z[m, :, :], Qtilde_sumneighbour[m, :, :], neighboursIndexes, gamma) #print beta_plotting plt.figure(1) plt.hold('on') plt.plot(range_b, beta_plotting) plt.figure(2) plt.hold('on') plt.plot(range_b, grad_plotting) plt.show() # Sigma noise if estimateNoise: logger.info("M sigma noise step ...") for s in xrange(n_sess): sigma_eps[s, :] = vt.maximization_sigma_noise_asl(XX[s, :, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], H, m_C[s, :, :], Sigma_C[:, :, :, s], \ G, Sigma_H, Sigma_G, W, y_tilde[s, :, :], Gamma, \ Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], N) if PLOT: for m in xrange(M): SUM_q_Z[m] += [q_Z[m, 1, :].sum()] mua1[m] += [mu_Ma[m, 1]] free_energy = 0 for s in xrange(n_sess): if s==n_sess-1: plotFE = True else: plotFE = False free_energy += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG, m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G, AuxG, q_Z, neighboursIndexes, Beta, Gamma, gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], plot=plotFE, bold=True, S=n_sess) if ni > 0: if free_energy < free_energyB: logger.info("free energy has decreased after Noise computation from %f to %f", free_energyB, free_energy) if ni > 0: if free_energy < FE[-1]: logger.info("WARNING! free energy has decreased in this iteration from %f to %f", FE[-1], free_energy) FE += [free_energy] if ni > 5: #Crit_FE = np.abs((FE[-1] - FE[-2]) / FE[-2]) FE0 = np.array(FE) Crit_FE = np.abs((FE0[-5:] - FE0[-6:-1]) / FE0[-6:-1]) print Crit_FE print (Crit_FE > Thresh * np.ones_like(Crit_FE)).any() else: Crit_FE = 100 ni += 1 cTime += [time.time() - t1] logger.info("Computing reconstruction error") StimulusInducedSignal = vt.computeFit_asl(H, m_A[s, :, :], G, m_C[s, :, :], W, XX[s, :, :, :]) rerror = np.append(rerror, \ np.mean(((Y[s, :, :] - StimulusInducedSignal) ** 2).sum(axis=0)) \ / np.mean((Y[s, :, :] ** 2).sum(axis=0))) CompTime = time.time() - t1 # Normalize if not done already if not constraint: # or not normg: logger.info("l2-norm of H and G to 1 if not constraint") Hnorm = np.linalg.norm(H) H /= Hnorm Sigma_H /= Hnorm**2 m_A *= Hnorm if zc: H = np.concatenate(([0], H, [0])) ## Compute contrast maps and variance if computeContrast and len(contrasts) > 0: logger.info("Computing contrasts ... ") CONTRAST_A, CONTRASTVAR_A, \ CONTRAST_C, CONTRASTVAR_C = vt.compute_contrasts(condition_names, contrasts, m_A[s, :, :], m_C[s, :, :], Sigma_A[:, :, :, s], Sigma_C[:, :, :, s], M, J) else: CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C = 0, 0, 0, 0 ########################################################################### ########################################## PLOTS and SNR computation logger.info("Nb iterations to reach criterion: %d", ni) logger.info("Computational time = %s min %s s", str(np.int(CompTime // 60)), str(np.int(CompTime % 60))) logger.info("Iteration time = %s min %s s", str(np.int((CompTime // ni) // 60)), str(np.int((CompTime / ni) % 60))) logger.info("perfusion baseline mean = %f", np.mean(AL[0, :, s])) logger.info("perfusion baseline var = %f", np.var(AL[0, :, s])) logger.info("drifts mean = %f", np.mean(AL[1:, :, s])) logger.info("drifts var = %f", np.var(AL[1:, :, s])) logger.info("noise mean = %f", np.mean(sigma_eps[s, :])) logger.info("noise var = %f", np.var(sigma_eps[s, :])) SNR10 = 20 * (np.log10(np.linalg.norm(Y[s, :, :]) / \ np.linalg.norm(Y[s, :, :] - StimulusInducedSignal - PL[s, :, :]))) logger.info("SNR = %d", SNR10) return ni, m_A.mean(0), H, m_C.mean(0), G, Z_tilde, sigma_eps[s, :], \ mu_Ma, sigma_Ma, mu_Mc, sigma_Mc, Beta, AL[:, :, s], PL[s, :, :], \ np.zeros_like(AL[0, :, s]), Sigma_A[:, :, :, s], Sigma_C[:, :, :, s], Sigma_H, Sigma_G, rerror, \ CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C, \ cA[:], cH[2:], cC[2:], cG[2:], cZ[2:], cAH[2:], cCG[2:], \ cTime, FE
def create_canonical_hrf(hrf_duration=25., dt=.5): return shrf.getCanoHRF(hrf_duration, dt)[1]
plt.rc('ytick', labelsize=15) fig = plt.figure(figsize=(20, 9)) gs = gridspec.GridSpec(2, 2) # Parcellation image parcels_img = load_img(PARCELLATION_MASK) parcels_img_data = np.array(parcels_img.get_data()) # Anatomical image ANAT_IMAGE = glob.glob(os.path.join(INPUT_FOLDER, 'bold.nii')).pop() anat_img = load_img(ANAT_IMAGE) # Estimated HRF (3) hrf_s = xndarray.load(os.path.join(PYHRF_OUTPUT, 'jde_vem_hrf.nii')) time_axis, canonical_hrf = getCanoHRF(duration=HRF_DURATION, dt=DT) # Plot Canonical HRF (3) ax_hrf = plt.subplot(gs[1, 0]) ax_hrf.plot(time_axis, canonical_hrf, ":", label="Canonical") ax_hrf.set_xlim([0, np.max(time_axis)]) ax_hrf.set_ylabel("amplitude", size=15) ax_hrf.set_xlabel("time (s)", size=15) # Plot PPM (2) ax_ppm = plt.subplot(gs[0, 1]) ppm_img = load_img(os.path.join(PYHRF_OUTPUT, ppm_nii)) try: plot_stat_map(stat_map_img=ppm_img, threshold=PPM_THRESHOLD, draw_cross=False,
def gen_hrf( self, nItMin=30, nItMax=30, estimateSigmaH=0, estimateBeta=0, Onsets={'nuages': array([0])}, scale=1, ): """ allow to generate figures :param nItMin: Minimum number of iteration :type nItMin: int :param nItMax: Maximum number of iteration :type nItMax: int :param estimateSigmaH: estimation of sigmaH :type estimateSigmaH: int :param estimateBeta: estimation of Beta :type estimateBeta: int :param scale: scale factor :type scale: int """ # estimationSigmah = 0 sans estimation de sigmh , estimationSigmah=1 estimation de sigmah # estimateBeta = 0 sans estimation de beta , estimateBeta=1 estimation de beta # construction Onsets # Onsets = {'nuages' : array([1,6,7])} areas = ['ra'] labelFields = {} cNames = ['inactiv', 'activ'] spConf = RegularLatticeMapping((self.height, self.width, 1)) graph = graph_from_lattice( ones((self.height, self.width, 1), dtype=int)) J = self.Y.shape[0] l = int(sqrt(J)) # NbIter, nrls_mean, hrf_mean, hrf_covar, labels_proba, noise_var, \ # nrls_class_mean, nrls_class_var, beta, drift_coeffs, drift,CONTRAST, CONTRASTVAR, \ # nrls_criteria, hrf_criteria,labels_criteria, nrls_hrf_criteria, compute_time,compute_time_mean, \ # nrls_covar, stimulus_induced_signal, density_ratio,density_ratio_cano, density_ratio_diff, density_ratio_prod, \ # ppm_a_nrl,ppm_g_nrl, ppm_a_contrasts, ppm_g_contrasts, variation_coeff = \ # jde_vem_bold_fast_python(pl,graph, Y, Onsets, Thrf, K,TR, beta, dt, estimateSigmaH, sigmaH,nItMax,nItMin,estimateBeta) # FlagZ = 1 # q_Z = zeros((M,K,J),dtype=float64) # NbIter,m_A, m_H, q_Z, sigma_epsilone, mu_k, sigma_k,Beta,L,PL,CONTRAST, CONTRASTVAR,cA,cH,cZ,cAH,cTime,cTimeMean,Sigma_A,XX = \ # Main_vbjde_Extension_TD(height,width,q_Z,FlagZ,pl,graph,Y,Onsets,Thrf,K,TR,beta,dt,scale,estimateSigmaH,sigmaH,nItMax,nItMin,estimateBeta) # facteur = 1.0 # Y,height,width,bande = lecture_data(dataDir,2660,2730,2600,2680,bande,start,facteur,end) # FlagZ = 0 # NbIter_f,m_A_f, m_H_f, q_Z_f, sigma_epsilone_f, mu_k_f, sigma_k_f,Beta_f,L_f,PL,CONTRAST, CONTRASTVAR,cA,cH,cZ,cAH,cTime,cTimeMean,Sigma_A,XX = \ # Main_vbjde_Extension_TD(height,width,q_Z,FlagZ,pl,graph,Y,Onsets,Thrf,K,TR,beta,dt,scale,estimateSigmaH,sigmaH,nItMax,nItMin,estimateBeta) # ytild=PL # matshow(reshape(m_A_f[:,0],(height,width)) - reshape(m_A[:,0],(height,width)),cmap=get_cmap('gray')) # colorbar() FlagZ = 1 q_Z0 = zeros((self.M, self.K, J), dtype=float64) if not FlagZ: q_Z0 = q_Z FlagH = 1 TT, m_h = getCanoHRF(self.Thrf - self.dt, self.dt) self.hrf0 = hrf0 = array(m_h).astype(float64) Sigma_H0 = eye(hrf0.shape[0]) if not FlagH: hrf0 = h_H Sigma_H0 = Sigma_H self.m_A, self.m_H, self.q_Z, sigma_epsilone, mu_k, sigma_k, Beta, PL, Sigma_A, XX, Sigma_H = \ Main_vbjde_Extension_TD( FlagH, hrf0, Sigma_H0, self.height, self.width, q_Z0, FlagZ, self.pl, graph, self.Y, Onsets, self.Thrf, self.K, self.TR, self.beta, self.dt, scale, estimateSigmaH, self.sigmaH, nItMin, estimateBeta) fgs = self.ConditionalNRLHist(self.m_A, self.q_Z) MMin = -1.0 # Y.min() MMax = 1.0 # Y.max() pas = (MMax - MMin) / 100 xx = arange(MMin, MMax, pas) g0 = self.gaussian(xx, mu_k[0][0], sigma_k[0][0]) g1 = self.gaussian(xx, mu_k[0][1], sigma_k[0][1]) # # figure(77) # plot(xx,g0*pas, label='m=%.2f;v=%.2f' % (mu_k[0][0],sigma_k[0][0])) # hold(True) # plot(xx,g1*pas, label='m=%.2f;v=%.2f' % (mu_k[0][1],sigma_k[0][1])) # legend() # savgarde des PLs # # if ((pl != 0 )and (savepl !=0 )) : # for i in range (0,ytild.shape[0]) : # figure(nf) # PL_img =reshape(ytild[i,:],(height,width)) # matshow(PL_img,cmap=get_cmap('gray')) # colorbar() # nf=nf+1 # savefig(outDir+'PL'+str(i)+'bande=' +str(bande)+'.png') # savefig(outDir+'PL'+str(i)+'bande=' +str(bande)+'beta='+str(beta)+'sigma='+str(sigmaH)+'pl='+str(pl)+'dt='+str(dt)+'thrf'+str(Thrf)+'.png') # # figure Hrf ####### fgs.insert(0, figure((self.nf + 1) * 123)) title("Fonction de reponse", fontsize='xx-large') figtext(0.2, 0.04, 'bande = ' + str(self.bande) + ' beta =' + str(self.beta) + ' sigma = ' + str(self.sigmaH) + ' pl = ' + str(self.pl) + ' dt = ' + str(self.dt) + ' thrf = ' + str(self.Thrf), fontsize='x-large') plot(self.m_H) if self.shower == 1: show() return fgs