def test_gromov(): n_samples = 50 # nb samples mu_s = np.array([0, 0]) cov_s = np.array([[1, 0], [0, 1]]) xs = ot.datasets.get_2D_samples_gauss(n_samples, mu_s, cov_s) xt = xs[::-1].copy() p = ot.unif(n_samples) q = ot.unif(n_samples) C1 = ot.dist(xs, xs) C2 = ot.dist(xt, xt) C1 /= C1.max() C2 /= C2.max() G = ot.gromov_wasserstein(C1, C2, p, q, 'square_loss', epsilon=5e-4) # check constratints np.testing.assert_allclose(p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose(q, G.sum(0), atol=1e-04) # cf convergence gromov
def init_marginals(self): self.p = ot.unif( self.X.shape[0] ) # Without any prior information, we set the probabilities to what we observe empirically: uniform over all observed samples self.q = ot.unif( self.y.shape[0] ) # Without any prior information, we set the probabilities to what we observe empirically: uniform over all observed samples
def gromov_wasserstein_distance_latent_space(data_path, num_labels, num_clusters, result_path): import scipy as sp import matplotlib.pylab as pl import ot # z = np.load(data_path+ "/L-1/z.npy") # -1 means no discrimation for labelsa, the same vae transform , orthogonal concept to whether cluster on this z space or use other mehtod to split into clusters z = np.load( data_path + "/L-1" + config.z_name ) # -1 means no discrimation for labelsa, the same vae transform , orthogonal concept to whether cluster on this z space or use other mehtod to split into clusters # index = np.load(data_path+"/global_index_cluster_data.npy") index = np.load( data_path + config.global_index_name ) # according to label, vae, vgmm, merge , cluster , per cluster-index(globally) d_t = z[index.item().get('0')] d_s = z[index.item().get('1')] # Compute distance kernels, normalize them and then display xs = d_s xt = d_t print(xt.shape) n_samples = min(100, xs.shape[0], xt.shape[0]) xs = xs[:n_samples] xt = xt[:n_samples] C1 = sp.spatial.distance.cdist(xs, xs) C2 = sp.spatial.distance.cdist(xt, xt) C1 /= C1.max() C2 /= C2.max() p = ot.unif(n_samples) q = ot.unif(n_samples) gw0, log0 = ot.gromov.gromov_wasserstein(C1, C2, p, q, 'square_loss', verbose=True, log=True) gw, log = ot.gromov.entropic_gromov_wasserstein(C1, C2, p, q, 'square_loss', epsilon=5e-4, log=True, verbose=True) print('Gromov-Wasserstein distances: ' + str(log0['gw_dist'])) print('Entropic Gromov-Wasserstein distances: ' + str(log['gw_dist'])) pl.figure(1, (10, 5)) pl.subplot(1, 2, 1) pl.imshow(gw0, cmap='jet') pl.title('Gromov Wasserstein') pl.subplot(1, 2, 2) pl.imshow(gw, cmap='jet') pl.title('Entropic Gromov Wasserstein') pl.savefig(result_path + "/WD_TSNE.jpg")
def compute_gamma(self, pred): ''' Function to compute the OT between the target and source samples. :return:Gamma the OT matrix ''' # Reshaping the samples into vectors of dimensions number of modalities * patch_dimension. # train_vecs are of shape (batch_size, d) train_vec_source = np.reshape(self.image_representation_source, (self.batch_size, self.image_representation_source.shape[1]* self.image_representation_source.shape[2]* self.image_representation_source.shape[3]* self.image_representation_source.shape[4])) train_vec_target = np.reshape(self.image_representation_target, (self.batch_size, self.image_representation_target.shape[1]* self.image_representation_target.shape[2]* self.image_representation_target.shape[3]* self.image_representation_target.shape[4])) # Same for the ground truth but the GT is the same for both modalities truth_vec_source = np.reshape(self.train_batch[1][:self.batch_size], (self.batch_size, self.config.patch_shape[0]*self.config.patch_shape[1]*self.config.patch_shape[2])) pred_vec_source = np.reshape(pred[:self.batch_size], (self.batch_size, self.config.patch_shape[0]*self.config.patch_shape[1]*self.config.patch_shape[2])) # We don't have information on target labels pred_vec_target = np.reshape(pred[self.batch_size:], (self.batch_size, self.config.patch_shape[0]*self.config.patch_shape[1]*self.config.patch_shape[2])) # Compute the distance between samples and between the source_truth and the target prediction. C0 = cdist(train_vec_source, train_vec_target, metric="sqeuclidean") C1 = cdist(truth_vec_source, pred_vec_target, metric=self.config.jdot_distance) C = K.get_value(self.jdot_alpha)*C0+K.get_value(self.jdot_beta)*C1 # Computing gamma using the OT library gamma = ot.emd(ot.unif(self.batch_size), ot.unif(self.batch_size), C) return gamma
def gromov_wasserstein_distance(X, Y, device): import concurrent.futures # import pdb; pdb.set_trace() mb_size = X.size(0) gw_dist = np.zeros(mb_size) Tensor = torch.FloatTensor with concurrent.futures.ProcessPoolExecutor() as executor: for i in executor.map(range(mb_size)): C1 = sp.spatial.distance.cdist( X[i, :].reshape(28, 28).data.cpu().numpy(), X[i, :].reshape(28, 28).data.cpu().numpy() ) #Convert data back to an image from one hot encoding with size 28x28 C2 = sp.spatial.distance.cdist( Y[i, :].reshape(28, 28).data.cpu().numpy(), Y[i, :].reshape(28, 28).data.cpu().numpy()) C1 /= C1.max() C2 /= C2.max() p = unif(28) q = unif(28) gw_dist[i] = gromov_wasserstein2(C1, C2, p, q, loss_fun='square_loss', epsilon=5e-4) print("*" * 100) return Variable(Tensor(gw_dist), requires_grad=True).sum()
def test_gpu_sinkhorn(): rng = np.random.RandomState(0) for n_samples in [50, 100, 500, 1000]: a = rng.rand(n_samples // 4, 100) b = rng.rand(n_samples, 100) wa = ot.unif(n_samples // 4) wb = ot.unif(n_samples) wb2 = np.random.rand(n_samples, 20) wb2 /= wb2.sum(0, keepdims=True) M = ot.dist(a.copy(), b.copy()) M2 = ot.gpu.dist(a.copy(), b.copy(), to_numpy=False) reg = 1 G = ot.sinkhorn(wa, wb, M, reg) G1 = ot.gpu.sinkhorn(wa, wb, M, reg) np.testing.assert_allclose(G1, G, rtol=1e-10) # run all on gpu ot.gpu.sinkhorn(wa, wb, M2, reg, to_numpy=False, log=True) # run sinkhorn for multiple targets ot.gpu.sinkhorn(wa, wb2, M2, reg, to_numpy=False, log=True)
def test_otda(): n_samples = 150 # nb samples np.random.seed(0) xs, ys = ot.datasets.make_data_classif('3gauss', n_samples) xt, yt = ot.datasets.make_data_classif('3gauss2', n_samples) a, b = ot.unif(n_samples), ot.unif(n_samples) # LP problem da_emd = ot.da.OTDA() # init class da_emd.fit(xs, xt) # fit distributions da_emd.interp() # interpolation of source samples da_emd.predict(xs) # interpolation of source samples np.testing.assert_allclose(a, np.sum(da_emd.G, 1)) np.testing.assert_allclose(b, np.sum(da_emd.G, 0)) # sinkhorn regularization lambd = 1e-1 da_entrop = ot.da.OTDA_sinkhorn() da_entrop.fit(xs, xt, reg=lambd) da_entrop.interp() da_entrop.predict(xs) np.testing.assert_allclose(a, np.sum(da_entrop.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_entrop.G, 0), rtol=1e-3, atol=1e-3) # non-convex Group lasso regularization reg = 1e-1 eta = 1e0 da_lpl1 = ot.da.OTDA_lpl1() da_lpl1.fit(xs, ys, xt, reg=reg, eta=eta) da_lpl1.interp() da_lpl1.predict(xs) np.testing.assert_allclose(a, np.sum(da_lpl1.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_lpl1.G, 0), rtol=1e-3, atol=1e-3) # True Group lasso regularization reg = 1e-1 eta = 2e0 da_l1l2 = ot.da.OTDA_l1l2() da_l1l2.fit(xs, ys, xt, reg=reg, eta=eta, numItermax=20, verbose=True) da_l1l2.interp() da_l1l2.predict(xs) np.testing.assert_allclose(a, np.sum(da_l1l2.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_l1l2.G, 0), rtol=1e-3, atol=1e-3) # linear mapping da_emd = ot.da.OTDA_mapping_linear() # init class da_emd.fit(xs, xt, numItermax=10) # fit distributions da_emd.predict(xs) # interpolation of source samples # nonlinear mapping da_emd = ot.da.OTDA_mapping_kernel() # init class da_emd.fit(xs, xt, numItermax=10) # fit distributions da_emd.predict(xs) # interpolation of source samples
def test_lazy_empirical_sinkhorn(): # test sinkhorn n = 10 a = ot.unif(n) b = ot.unif(n) numIterMax = 1000 X_s = np.reshape(np.arange(n), (n, 1)) X_t = np.reshape(np.arange(0, n), (n, 1)) M = ot.dist(X_s, X_t) M_m = ot.dist(X_s, X_t, metric='minkowski') f, g = ot.bregman.empirical_sinkhorn(X_s, X_t, 1, numIterMax=numIterMax, isLazy=True, batchSize=(1, 3), verbose=True) G_sqe = np.exp(f[:, None] + g[None, :] - M / 1) sinkhorn_sqe = ot.sinkhorn(a, b, M, 1) f, g, log_es = ot.bregman.empirical_sinkhorn(X_s, X_t, 0.1, numIterMax=numIterMax, isLazy=True, batchSize=1, log=True) G_log = np.exp(f[:, None] + g[None, :] - M / 0.1) sinkhorn_log, log_s = ot.sinkhorn(a, b, M, 0.1, log=True) f, g = ot.bregman.empirical_sinkhorn(X_s, X_t, 1, metric='minkowski', numIterMax=numIterMax, isLazy=True, batchSize=1) G_m = np.exp(f[:, None] + g[None, :] - M_m / 1) sinkhorn_m = ot.sinkhorn(a, b, M_m, 1) loss_emp_sinkhorn, log = ot.bregman.empirical_sinkhorn2( X_s, X_t, 1, numIterMax=numIterMax, isLazy=True, batchSize=1, log=True) loss_sinkhorn = ot.sinkhorn2(a, b, M, 1) # check constratints np.testing.assert_allclose(sinkhorn_sqe.sum(1), G_sqe.sum(1), atol=1e-05) # metric sqeuclidian np.testing.assert_allclose(sinkhorn_sqe.sum(0), G_sqe.sum(0), atol=1e-05) # metric sqeuclidian np.testing.assert_allclose(sinkhorn_log.sum(1), G_log.sum(1), atol=1e-05) # log np.testing.assert_allclose(sinkhorn_log.sum(0), G_log.sum(0), atol=1e-05) # log np.testing.assert_allclose(sinkhorn_m.sum(1), G_m.sum(1), atol=1e-05) # metric euclidian np.testing.assert_allclose(sinkhorn_m.sum(0), G_m.sum(0), atol=1e-05) # metric euclidian np.testing.assert_allclose(loss_emp_sinkhorn, loss_sinkhorn, atol=1e-05)
def create_space_distributions(num_locations, num_cells): """Creates uniform distributions at the target and source spaces. num_locations -- the number of locations at the target space num_cells -- the number of single-cells in the data.""" p_locations = ot.unif(num_locations) p_expression = ot.unif(num_cells) return p_locations, p_expression
def test_gpu_sinkhorn_lpl1(): rng = np.random.RandomState(0) for n_samples in [50, 100, 500]: print(n_samples) a = rng.rand(n_samples // 4, 100) labels_a = np.random.randint(10, size=(n_samples // 4)) b = rng.rand(n_samples, 100) wa = ot.unif(n_samples // 4) wb = ot.unif(n_samples) M = ot.dist(a.copy(), b.copy()) M2 = ot.gpu.dist(a.copy(), b.copy(), to_numpy=False) reg = 1 G = ot.da.sinkhorn_lpl1_mm(wa, labels_a, wb, M, reg) G1 = ot.gpu.da.sinkhorn_lpl1_mm(wa, labels_a, wb, M, reg) np.testing.assert_allclose(G1, G, rtol=1e-10) ot.gpu.da.sinkhorn_lpl1_mm(wa, labels_a, wb, M2, reg, to_numpy=False, log=True)
def compute_deepjdot_loss(features_source, ys_pred, ys, features_target, yt_pred, gamma_criterion, g_criterion): # Compute the euclidian distance in the feature space #C0 = cdist(features_source.detach().cpu().numpy(), # features_target.detach().cpu().numpy(), p=0.2) C0 = torch.square(torch.cdist(features_source, features_target, p=2.0)) # Compute the loss function of labels #C1 = F.cross_entropy(yt_pred, ys) classes = torch.arange(yt_pred.shape[1]).reshape(1, yt_pred.shape[1]) one_hot_ys = (ys.unsqueeze(1) == classes.to(device=c.device)).float() C1 = torch.square( torch.cdist(one_hot_ys, F.softmax(yt_pred, dim=1), p=2.0)) C = c.alpha * C0 + c.tloss * C1 # Compute the gamma function #gamma = ot.emd(ot.unif(features_source.shape[0]), # ot.unif(features_target.shape[0]), C) gamma = ot.emd( torch.from_numpy(ot.unif( features_source.shape[0])).to(device=c.device), torch.from_numpy(ot.unif( features_target.shape[0])).to(device=c.device), C) # ot.emd: solve the OT problem for the pdfs of both source and target features # ot.unif: return an histogram of the arguments # Align Loss gamma_loss = gamma_criterion(features_source, features_target, gamma) # gamma loss get the fetures of the source, the features of the target # and gamma. It first performs the L2 distance between the features and # then return self.jdot_alpha * dnn.K.sum(self.gamma * (gdist)) # Classifier Loss clf_loss = g_criterion(ys, ys_pred, yt_pred, gamma) return clf_loss, gamma_loss, clf_loss + gamma_loss
def test_empirical_sinkhorn_divergence(): #Test sinkhorn divergence n = 10 a = ot.unif(n) b = ot.unif(n) X_s = np.reshape(np.arange(n), (n, 1)) X_t = np.reshape(np.arange(0, n * 2, 2), (n, 1)) M = ot.dist(X_s, X_t) M_s = ot.dist(X_s, X_s) M_t = ot.dist(X_t, X_t) emp_sinkhorn_div = ot.bregman.empirical_sinkhorn_divergence(X_s, X_t, 1) sinkhorn_div = (ot.sinkhorn2(a, b, M, 1) - 1 / 2 * ot.sinkhorn2(a, a, M_s, 1) - 1 / 2 * ot.sinkhorn2(b, b, M_t, 1)) emp_sinkhorn_div_log, log_es = ot.bregman.empirical_sinkhorn_divergence( X_s, X_t, 1, log=True) sink_div_log_ab, log_s_ab = ot.sinkhorn2(a, b, M, 1, log=True) sink_div_log_a, log_s_a = ot.sinkhorn2(a, a, M_s, 1, log=True) sink_div_log_b, log_s_b = ot.sinkhorn2(b, b, M_t, 1, log=True) sink_div_log = sink_div_log_ab - 1 / 2 * (sink_div_log_a + sink_div_log_b) # check constratints np.testing.assert_allclose(emp_sinkhorn_div, sinkhorn_div, atol=1e-05) # cf conv emp sinkhorn np.testing.assert_allclose(emp_sinkhorn_div_log, sink_div_log, atol=1e-05) # cf conv emp sinkhorn
def prob_dists(self, x_freq: Dict[str, float] = None, y_freq: Dict[str, float] = None, dist_shape: str = None, size: int = None) -> (np.ndarray, np.ndarray): """ Partly taken from Alvarez-Melis & Jaakkola (2018) Compute marginal distributions. This method presupposes the following attirbutes to be set: src_words, trg_words :param dist_shape: one of ['uniform', 'custom', 'zipf'] """ dist_shape = dist_shape if dist_shape in default.DIST_SHAPES else self.distribs size = size if size else self.size if self.size else min( len(x_freq), len(y_freq)) if dist_shape == 'uniform': p = ot.unif(size) q = ot.unif(size) elif dist_shape == 'zipf': p = utils.zipf_init('en', size) q = utils.zipf_init('en', size) elif dist_shape == 'custom' and x_freq and y_freq: p = np.array([x_freq.get(w, 0) for w in self.src_words]) q = np.array([y_freq.get(w, 0) for w in self.trg_words]) p /= np.sum(p) q /= np.sum(q) else: raise ValueError( "Unable to compute p/q: use one of default.DIST_SHAPES" " and provide frequencies for the option 'custom'.") return p, q
def sinkhorn_divergence(X, Y, reg=1000, maxiter=100, cuda=True): """ Function which computes the autodiff sharp Sinkhorn Divergence. parameters: - X : Source data (TorchTensor (batch size, ns)) - Y : Target data (TorchTensor (batch size, nt)) - reg : entropic ragularization parameter (float) - maxiter : number of loop (int) returns: - sharp Sinkhorn Divergence (float) """ Tensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor a = torch.from_numpy(ot.unif(X.size()[0])).type(Tensor).double() b = torch.from_numpy(ot.unif(Y.size()[0])).type(Tensor).double() M = distances(X, Y) Ms = distances(X, X) Mt = distances(Y, Y) SD = entropic_OT(a, b, M, reg=reg, maxiter=maxiter) SD -= 1. / 2 * entropic_OT(a, a, Ms, reg=reg, maxiter=maxiter - 50) SD -= 1. / 2 * entropic_OT(b, b, Mt, reg=reg, maxiter=maxiter - 50) return SD
def _entropic_gromov_wasserstein_distance(x, y): x_p = ot.unif(x.shape[0]) y_q = ot.unif(y.shape[0]) gw_dist = ot.gromov.entropic_gromov_wasserstein2(x, y, x_p, y_q, loss_fun="kl_loss") return np.array(gw_dist, dtype=np.float32)
def test_raise_errors(): n_samples = 20 # nb samples (gaussian) n_noise = 20 # nb of samples (noise) mu = np.array([0, 0]) cov = np.array([[1, 0], [0, 2]]) xs = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) xs = np.append(xs, (np.random.rand(n_noise, 2) + 1) * 4).reshape((-1, 2)) xt = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) xt = np.append(xt, (np.random.rand(n_noise, 2) + 1) * -3).reshape((-1, 2)) M = ot.dist(xs, xt) p = ot.unif(n_samples + n_noise) q = ot.unif(n_samples + n_noise) with pytest.raises(ValueError): ot.partial.partial_wasserstein_lagrange(p + 1, q, M, 1, log=True) with pytest.raises(ValueError): ot.partial.partial_wasserstein(p, q, M, m=2, log=True) with pytest.raises(ValueError): ot.partial.partial_wasserstein(p, q, M, m=-1, log=True) with pytest.raises(ValueError): ot.partial.entropic_partial_wasserstein(p, q, M, reg=1, m=2, log=True) with pytest.raises(ValueError): ot.partial.entropic_partial_wasserstein(p, q, M, reg=1, m=-1, log=True) with pytest.raises(ValueError): ot.partial.partial_gromov_wasserstein(M, M, p, q, m=2, log=True) with pytest.raises(ValueError): ot.partial.partial_gromov_wasserstein(M, M, p, q, m=-1, log=True) with pytest.raises(ValueError): ot.partial.entropic_partial_gromov_wasserstein(M, M, p, q, reg=1, m=2, log=True) with pytest.raises(ValueError): ot.partial.entropic_partial_gromov_wasserstein(M, M, p, q, reg=1, m=-1, log=True)
def test_partial_wasserstein(): n_samples = 20 # nb samples (gaussian) n_noise = 20 # nb of samples (noise) mu = np.array([0, 0]) cov = np.array([[1, 0], [0, 2]]) xs = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) xs = np.append(xs, (np.random.rand(n_noise, 2) + 1) * 4).reshape((-1, 2)) xt = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) xt = np.append(xt, (np.random.rand(n_noise, 2) + 1) * -3).reshape((-1, 2)) M = ot.dist(xs, xt) p = ot.unif(n_samples + n_noise) q = ot.unif(n_samples + n_noise) m = 0.5 w0, log0 = ot.partial.partial_wasserstein(p, q, M, m=m, log=True) w, log = ot.partial.entropic_partial_wasserstein(p, q, M, reg=1, m=m, log=True, verbose=True) # check constratints np.testing.assert_equal(w0.sum(1) - p <= 1e-5, [True] * len(p)) # cf convergence wasserstein np.testing.assert_equal(w0.sum(0) - q <= 1e-5, [True] * len(q)) # cf convergence wasserstein np.testing.assert_equal(w.sum(1) - p <= 1e-5, [True] * len(p)) # cf convergence wasserstein np.testing.assert_equal(w.sum(0) - q <= 1e-5, [True] * len(q)) # cf convergence wasserstein # check transported mass np.testing.assert_allclose(np.sum(w0), m, atol=1e-04) np.testing.assert_allclose(np.sum(w), m, atol=1e-04) w0, log0 = ot.partial.partial_wasserstein2(p, q, M, m=m, log=True) w0_val = ot.partial.partial_wasserstein2(p, q, M, m=m, log=False) G = log0['T'] np.testing.assert_allclose(w0, w0_val, atol=1e-1, rtol=1e-1) # check constratints np.testing.assert_equal(G.sum(1) <= p, [True] * len(p)) # cf convergence wasserstein np.testing.assert_equal(G.sum(0) <= q, [True] * len(q)) # cf convergence wasserstein np.testing.assert_allclose(np.sum(G), m, atol=1e-04)
def setup(n_samples): rng = np.random.RandomState(123456789) a = rng.rand(n_samples // 4, 100) b = rng.rand(n_samples, 100) wa = ot.unif(n_samples // 4) wb = ot.unif(n_samples) M = ot.dist(a.copy(), b.copy()) return wa, wb, M
def GW_word_mapping(xs, xt, src_words, tgt_words, eps=1e-3, metric='cosine', loss='square_loss', max_iter=1000, tol=1e-9, verbose=False): """ All-in-one wrapper function to compute GW for word embedding mapping. Computes distance matrices, marginal distributions, solves GW problem and returns translations. """ # 1. Compute distance matrices print('Computing distance matrices....', end='') C1 = sp.spatial.distance.cdist(xs, xs, metric=metric) C2 = sp.spatial.distance.cdist(xt, xt, metric=metric) print('Done!') # 2. Compute marginal distributions p = ot.unif(xs.shape[0]) q = ot.unif(xt.shape[0]) # 3. Solve GW problem print('Solving GW problem....') G = ot.gromov_wasserstein(C1, C2, p, q, loss, max_iter=max_iter, tol=tol, epsilon=eps, verbose=verbose) cost = np.sum(G * tensor_square_loss(C1, C2, G)) # 4. Analyze solution print('cost(G): {:8.2f}'.format(cost)) print('G is p-feasible: {}'.format( 'Yes' if np.allclose(G.sum(1), p) else 'No')) print('G is q-feasible: {}'.format( 'Yes' if np.allclose(G.sum(0), q) else 'No')) plt.figure() plt.imshow(G, cmap='jet') plt.colorbar() plt.show() # 5. Compute word translations from mapping mapping = translations_from_coupling(G, src_words, tgt_words, verbose=True) return mapping, G, cost
def test_fgw_barycenter(): np.random.seed(42) ns = 50 nt = 60 Xs, ys = ot.datasets.make_data_classif('3gauss', ns, random_state=42) Xt, yt = ot.datasets.make_data_classif('3gauss2', nt, random_state=42) ys = np.random.randn(Xs.shape[0], 2) yt = np.random.randn(Xt.shape[0], 2) C1 = ot.dist(Xs) C2 = ot.dist(Xt) n_samples = 3 X, C = ot.gromov.fgw_barycenters(n_samples, [ys, yt], [C1, C2], [ot.unif(ns), ot.unif(nt)], [.5, .5], 0.5, fixed_structure=False, fixed_features=False, p=ot.unif(n_samples), loss_fun='square_loss', max_iter=100, tol=1e-3) np.testing.assert_allclose(C.shape, (n_samples, n_samples)) np.testing.assert_allclose(X.shape, (n_samples, ys.shape[1])) xalea = np.random.randn(n_samples, 2) init_C = ot.dist(xalea, xalea) X, C = ot.gromov.fgw_barycenters(n_samples, [ys, yt], [C1, C2], ps=[ot.unif(ns), ot.unif(nt)], lambdas=[.5, .5], alpha=0.5, fixed_structure=True, init_C=init_C, fixed_features=False, p=ot.unif(n_samples), loss_fun='square_loss', max_iter=100, tol=1e-3) np.testing.assert_allclose(C.shape, (n_samples, n_samples)) np.testing.assert_allclose(X.shape, (n_samples, ys.shape[1])) init_X = np.random.randn(n_samples, ys.shape[1]) X, C, log = ot.gromov.fgw_barycenters( n_samples, [ys, yt], [C1, C2], [ot.unif(ns), ot.unif(nt)], [.5, .5], 0.5, fixed_structure=False, fixed_features=True, init_X=init_X, p=ot.unif(n_samples), loss_fun='square_loss', max_iter=100, tol=1e-3, log=True) np.testing.assert_allclose(C.shape, (n_samples, n_samples)) np.testing.assert_allclose(X.shape, (n_samples, ys.shape[1]))
def retrain_mapping_to_child(self): for barycenter in self.barycenter_in_seq: barycenter.load_barycenter_mtrx(self.outdir, self) C1 = barycenter.barycenter_mtrx C1 = np.asarray(C1, dtype=np.float64) for i in range(len(barycenter.child)): barycenter.child[i].load_barycenter_mtrx(self.outdir, self) C2 = barycenter.child[i].barycenter_mtrx C2 = np.asarray(C2, dtype=np.float64) mapping = compute_gromov_wasserstein(C2, C1, ot.unif(len(C2)), ot.unif(len(C1)), self.gw_args.tol, False, True, self.gw_args.mapping_entreg, self.gw_args.gwmaxiter) barycenter.mapping_to_child[i] = mapping barycenter.save_barycenter_mtrx(self.outdir)
def gromov_wasserstein_distance(data_path,num_labels,num_clusters,result_path): import json import scipy as sp import numpy as np import matplotlib.pylab as pl import ot # z: global training, cluster according to label # z = np.load(data_path + "/L-1/z.npy") z = np.load(data_path + "/L-1" + config.z_name) # with open(data_path + "/L-1/cluster_dict.json") as f: with open(data_path + "/L-1"+config.cluster_index_json_name) as f: pos_index_dict = json.load(f) # cluster index dictionary, not according to label. cluster on the whole space # dict: dictionary of data which training and clustering within label dict = InputDataset.concatenate_data_from_dir(data_path, num_labels,num_clusters) for i in range(num_clusters): # Compute distance kernels, normalize them and then display xs = dict[str(i)] #FIXME: this is index or latent space? xt = z[pos_index_dict[str(i)]] n_samples = min(xs.shape[0], xt.shape[0]) xs = xs[:n_samples] xt = xt[:n_samples] C1 = sp.spatial.distance.cdist(xs, xs) C2 = sp.spatial.distance.cdist(xt, xt) C1 /= C1.max() C2 /= C2.max() p = ot.unif(n_samples) q = ot.unif(n_samples) gw0, log0 = ot.gromov.gromov_wasserstein( C1, C2, p, q, 'square_loss', verbose=True, log=True) gw, log = ot.gromov.entropic_gromov_wasserstein( C1, C2, p, q, 'square_loss', epsilon=5e-4, log=True, verbose=True) print(" [*] cluster "+ str(i)+": ") print('Gromov-Wasserstein distances: ' + str(log0['gw_dist'])) print('Entropic Gromov-Wasserstein distances: ' + str(log['gw_dist'])) pl.figure(1, (10, 5)) pl.subplot(1, 2, 1) pl.imshow(gw0, cmap='jet') pl.title('Gromov Wasserstein') pl.subplot(1, 2, 2) pl.imshow(gw, cmap='jet') pl.title('Entropic Gromov Wasserstein') pl.savefig(result_path + "/WD.jpg")
def test_entropic_gromov(): n_samples = 50 # nb samples mu_s = np.array([0, 0]) cov_s = np.array([[1, 0], [0, 1]]) xs = ot.datasets.make_2D_samples_gauss(n_samples, mu_s, cov_s, random_state=42) xt = xs[::-1].copy() p = ot.unif(n_samples) q = ot.unif(n_samples) C1 = ot.dist(xs, xs) C2 = ot.dist(xt, xt) C1 /= C1.max() C2 /= C2.max() G = ot.gromov.entropic_gromov_wasserstein(C1, C2, p, q, 'square_loss', epsilon=5e-4, verbose=True) # check constratints np.testing.assert_allclose(p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose(q, G.sum(0), atol=1e-04) # cf convergence gromov gw, log = ot.gromov.entropic_gromov_wasserstein2(C1, C2, p, q, 'kl_loss', epsilon=1e-2, log=True) G = log['T'] np.testing.assert_allclose(gw, 0, atol=1e-1, rtol=1e-1) # check constratints np.testing.assert_allclose(p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose(q, G.sum(0), atol=1e-04) # cf convergence gromov
def main(): main_dir = os.path.split(os.getcwd())[0] result_dir = main_dir + '/results' experiment = 'fmril' nor_method = 'no' clf_method = 'svm' source_id = np.arange(5) target_id = 6 op_function = 'l1l2' # 'lpl1' 'l1l2' if experiment == 'fmril': source = fmril elif experiment == 'fmrir': source = fmrir else: source = meg result_dir = result_dir + '/{}'.format(experiment) y_target = source.y_target subjects = np.array(source.subjects) x_data = source.x_data_pow if experiment == 'meg' else source.x_data x_indi = source.x_indi_pow if experiment == 'meg' else source.x_indi x = x_indi if nor_method == 'indi' else x_data indices_sub = fucs.split_subjects(subjects) S = len(source_id) xs = [x[indices_sub[i]] for i in source_id] ys = [y_target[indices_sub[i]] for i in source_id] xt = x[indices_sub[target_id]] yt = y_target[indices_sub[target_id]] Cs = [sp.spatial.distance.cdist(xs[s], xs[s]) for s in range(S)] Cs = [cs / cs.max() for cs in Cs] ns = [len(xs[s]) for s in range(S)] ps = [ot.unif(ns[s]) for s in range(S)] p = ot.unif(len(xt)) lambdas = ot.unif(S) C, T = ot.gromov.gromov_barycenters(len(xt), Cs, ps, p, lambdas, 'square_loss', 5e-4, max_iter=100, tol=1e-5) ot_source = [] note = 'barycenter_{}s_{}t_{}_{}_{}_{}'.format(source_id, target_id, experiment, nor_method, clf_method, op_function) print(note)
def scot(X, y, k, e, rho = 1, mode="connectivity", metric="correlation", XontoY=True, returnCoupling=False, balanced = True): """ Given two datasets (X and y) and the hyperparameters (k: number of neighbors to be used in kNN graph construction; and e: eplison value in entropic regularization), returns the resulting datasets after transport For transport in the opposite direction, set XontoY to False """ ## I think we should let users choose what type of normalization they want to use since that might matter in comparisons to other methods ## e.g. MMD-MA uses l-2 norm sometimes and they might want to use that for fair comparison. So commented out the part below -Pinar # X=ut.zscore_standardize(np.asarray(X)) # y=ut.zscore_standardize(np.asarray(y)) # Construct the kNN graphs Cx=ut.get_graph_distance_matrix(X, k, mode=mode, metric=metric) Cy=ut.get_graph_distance_matrix(y, k, mode=mode, metric=metric); # Initialize marginal distributions over data: X_sampleNo= Cx.shape[0] y_sampleNo= Cy.shape[0] p=ot.unif(X_sampleNo) q=ot.unif(y_sampleNo) # Perform optimization to get the coupling matrix between domains: if balanced: couplingM, log = ot.gromov.entropic_gromov_wasserstein(Cx, Cy, p, q, 'square_loss', epsilon=e, log=True, verbose=True) else: solver = TLBSinkhornSolver(nits=1000, nits_sinkhorn=2500, gradient=False, tol=1e-3, tol_sinkhorn=1e-3) couplingM, _ = solver.tlb_sinkhorn(torch.Tensor(p).cuda(), torch.Tensor(Cx).cuda(), torch.Tensor(q).cuda(), torch.Tensor(Cy).cuda(), rho=rho*0.5*(Cx.mean() + Cy.mean()), eps=e, init=None) couplingM = couplingM.cpu().numpy() log = None # check to make sure GW congerged, if not, warn the user with an error statement converged=True #initialize the convergence flag if (np.isnan(couplingM).any() or np.any(~couplingM.any(axis=1)) or np.any(~couplingM.any(axis=0))): # or sum(sum(couplingM)) < .95): print("Did not converge. Try increasing the epsilon value. ") converged=False # If the user wants to get the coupling matrix and the optimization log at the end of this and investigate it or perform some projection themselves, # allow them (useful for hyperparameter tuning with projections in both directions) : if returnCoupling==True: return couplingM, log # Otherwise perform barycentric projection in the desired direction and return the aligned matrices else: if converged==False: #except if the convergence failed, just return None, None. return None, None if XontoY==True: X_transported = ut.transport_data(X,y,couplingM,transposeCoupling=False) return X_transported, y else: y_transported = ut.transport_data(X,y,couplingM,transposeCoupling=True) return X, y_transported
def gromov_wasserstein_distance_latent_space_cluster(data_path,num_labels,num_clusters,result_path,args): import scipy as sp import matplotlib.pylab as pl import ot # z = np.load(data_path+ "/L-1/z.npy") # -1 means no discrimation for labelsa, the same vae transform , orthogonal concept to whether cluster on this z space or use other mehtod to split into clusters z = np.load(data_path+ "/L-1" + config.z_name,allow_pickle=True) # -1 means no discrimation for labelsa, the same vae transform , orthogonal concept to whether cluster on this z space or use other mehtod to split into clusters # index = np.load(data_path+"/global_index_cluster_data.npy") index = np.load(data_path + config.global_index_name,allow_pickle=True) # according to label, vae, vgmm, merge , cluster , per cluster-index(globally) results = {} mat = np.zeros((num_clusters,num_clusters)) for i in range(num_clusters): xs = z[index.item().get(str(i))] for j in range(num_clusters): xt = z[index.item().get(str(j))] # Compute distance kernels, normalize them and then display n_samples = min(xs.shape[0], xt.shape[0]) if args.debug == True: n_samples = 100 xs = xs[:n_samples] xt = xt[:n_samples] C1 = sp.spatial.distance.cdist(xs, xs) C2 = sp.spatial.distance.cdist(xt, xt) C1 /= C1.max() C2 /= C2.max() p = ot.unif(n_samples) q = ot.unif(n_samples) gw0, log0 = ot.gromov.gromov_wasserstein( C1, C2, p, q, 'square_loss', verbose=True, log=True) gw, log = ot.gromov.entropic_gromov_wasserstein( C1, C2, p, q, 'square_loss', epsilon=5e-4, log=True, verbose=True) print('Gromov-Wasserstein distances between {}_{} clusters: {} '.format(i,j,str(log0['gw_dist'])) ) print('Entropic Gromov-Wasserstein distances between {}_{} clusters: {}'.format(i,j,str(log['gw_dist'])) ) results[str(i)+str(j)]={"GW":log0['gw_dist'],"EGW":log['gw_dist']} mat[i,j] = log0['gw_dist'] pl.figure(1, (10, 5)) pl.subplot(1, 2, 1) pl.imshow(gw0, cmap='jet') pl.title('Gromov Wasserstein') pl.subplot(1, 2, 2) pl.imshow(gw, cmap='jet') pl.title('Entropic Gromov Wasserstein') pl.savefig(result_path + "/WD_TSNE{}_{}.jpg".format(i,j)) # print(results) print(mat) with open("wd_vgmm.txt", 'a') as lf: lf.write(str(results)) return results
def run_Pamona(self, data): print("Pamona start!") time1 = time.time() init_random_seed(666) sampleNo = [] Max = [] Min = [] p = [] q = [] n_datasets = len(data) for i in range(n_datasets): sampleNo.append(np.shape(data[i])[0]) self.dist.append( Pamona_geodesic_distances(data[i], self.n_neighbors, mode=self.mode, metric=self.metric)) for i in range(n_datasets - 1): Max.append(np.maximum(sampleNo[i], sampleNo[-1])) Min.append(np.minimum(sampleNo[i], sampleNo[-1])) if self.n_shared is None: self.n_shared = Min for i in range(n_datasets - 1): if self.n_shared[i] > Min[i]: self.n_shared[i] = Min[i] p.append(ot.unif(Max[i])[0:len(data[i])]) q.append(ot.unif(Max[i])[0:len(data[-1])]) for i in range(n_datasets - 1): if self.M is not None: T_tmp = self.entropic_gromov_wasserstein(self.dist[i], self.dist[-1], p[i], q[i], \ self.n_shared[i]/Max[i]-1e-15, self.M[i]) else: T_tmp = self.entropic_gromov_wasserstein(self.dist[i], self.dist[-1], p[i], q[i], \ self.n_shared[i]/Max[i]-1e-15) self.T.append(T_tmp) self.Gc.append(T_tmp[:len(p[i]), :len(q[i])]) integrated_data = self.project_func(data) time2 = time.time() print("Pamona Done! takes {:f}".format(time2 - time1), 'seconds') return integrated_data, self.T
def gromov_wasserstein_distance_TSNE_test(data_path, num_labels, num_clusters, result_path): import scipy as sp import matplotlib.pylab as pl pl.switch_backend('agg') # FIXME: add this line if executed on server. import ot d_t = np.load(data_path + config.statistic_name4d_t) d_s = np.load(data_path + config.statistic_name4d_s) # Compute distance kernels, normalize them and then display xs = d_s.item().get('0') xt = d_t.item().get('0') print(xt.shape) print(xs.shape) n_samples = min(100, xs.shape[0], xt.shape[0]) xs = xs[:n_samples] xt = xt[:n_samples] C1 = sp.spatial.distance.cdist(xs, xs) C2 = sp.spatial.distance.cdist(xt, xt) C1 /= C1.max() C2 /= C2.max() p = ot.unif(n_samples) q = ot.unif(n_samples) gw0, log0 = ot.gromov.gromov_wasserstein(C1, C2, p, q, 'square_loss', verbose=True, log=True) gw, log = ot.gromov.entropic_gromov_wasserstein(C1, C2, p, q, 'square_loss', epsilon=5e-4, log=True, verbose=True) print('Gromov-Wasserstein distances: ' + str(log0['gw_dist'])) print('Entropic Gromov-Wasserstein distances: ' + str(log['gw_dist'])) pl.figure(1, (10, 5)) pl.subplot(1, 2, 1) pl.imshow(gw0, cmap='jet') pl.title('Gromov Wasserstein') pl.subplot(1, 2, 2) pl.imshow(gw, cmap='jet') pl.title('Entropic Gromov Wasserstein') pl.savefig(result_path + "/WD_TSNE.jpg")
def test_gromov(): n_samples = 50 # nb samples mu_s = np.array([0, 0]) cov_s = np.array([[1, 0], [0, 1]]) xs = ot.datasets.make_2D_samples_gauss(n_samples, mu_s, cov_s, random_state=4) xt = xs[::-1].copy() p = ot.unif(n_samples) q = ot.unif(n_samples) C1 = ot.dist(xs, xs) C2 = ot.dist(xt, xt) C1 /= C1.max() C2 /= C2.max() G = ot.gromov.gromov_wasserstein(C1, C2, p, q, 'square_loss', verbose=True) # check constratints np.testing.assert_allclose(p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose(q, G.sum(0), atol=1e-04) # cf convergence gromov Id = (1 / (1.0 * n_samples)) * np.eye(n_samples, n_samples) np.testing.assert_allclose(G, np.flipud(Id), atol=1e-04) gw, log = ot.gromov.gromov_wasserstein2(C1, C2, p, q, 'kl_loss', log=True) gw_val = ot.gromov.gromov_wasserstein2(C1, C2, p, q, 'kl_loss', log=False) G = log['T'] np.testing.assert_allclose(gw, 0, atol=1e-1, rtol=1e-1) np.testing.assert_allclose(gw, gw_val, atol=1e-1, rtol=1e-1) # cf log=False # check constratints np.testing.assert_allclose(p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose(q, G.sum(0), atol=1e-04) # cf convergence gromov
def test_fgw(): n_samples = 50 # nb samples mu_s = np.array([0, 0]) cov_s = np.array([[1, 0], [0, 1]]) xs = ot.datasets.make_2D_samples_gauss(n_samples, mu_s, cov_s, random_state=42) xt = xs[::-1].copy() ys = np.random.randn(xs.shape[0], 2) yt = ys[::-1].copy() p = ot.unif(n_samples) q = ot.unif(n_samples) C1 = ot.dist(xs, xs) C2 = ot.dist(xt, xt) C1 /= C1.max() C2 /= C2.max() M = ot.dist(ys, yt) M /= M.max() G, log = ot.gromov.fused_gromov_wasserstein(M, C1, C2, p, q, 'square_loss', alpha=0.5, log=True) # check constratints np.testing.assert_allclose( p, G.sum(1), atol=1e-04) # cf convergence fgw np.testing.assert_allclose( q, G.sum(0), atol=1e-04) # cf convergence fgw Id = (1 / (1.0 * n_samples)) * np.eye(n_samples, n_samples) np.testing.assert_allclose( G, np.flipud(Id), atol=1e-04) # cf convergence gromov fgw, log = ot.gromov.fused_gromov_wasserstein2(M, C1, C2, p, q, 'square_loss', alpha=0.5, log=True) G = log['T'] np.testing.assert_allclose(fgw, 0, atol=1e-1, rtol=1e-1) # check constratints np.testing.assert_allclose( p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose( q, G.sum(0), atol=1e-04) # cf convergence gromov
def test_unif(): n = 100 u = ot.unif(n) np.testing.assert_allclose(1, np.sum(u))
def test_unmix(): n_bins = 50 # nb bins # Gaussian distributions a1 = ot.datasets.get_1D_gauss(n_bins, m=20, s=10) # m= mean, s= std a2 = ot.datasets.get_1D_gauss(n_bins, m=40, s=10) a = ot.datasets.get_1D_gauss(n_bins, m=30, s=10) # creating matrix A containing all distributions D = np.vstack((a1, a2)).T # loss matrix + normalization M = ot.utils.dist0(n_bins) M /= M.max() M0 = ot.utils.dist0(2) M0 /= M0.max() h0 = ot.unif(2) # wasserstein reg = 1e-3 um = ot.bregman.unmix(a, D, M, M0, h0, reg, 1, alpha=0.01,) np.testing.assert_allclose(1, np.sum(um), rtol=1e-03, atol=1e-03) np.testing.assert_allclose([0.5, 0.5], um, rtol=1e-03, atol=1e-03) ot.bregman.unmix(a, D, M, M0, h0, reg, 1, alpha=0.01, log=True, verbose=True)
def test_clean_zeros(): n = 100 nz = 50 nz2 = 20 u1 = ot.unif(n) u1[:nz] = 0 u1 = u1 / u1.sum() u2 = ot.unif(n) u2[:nz2] = 0 u2 = u2 / u2.sum() M = ot.utils.dist0(n) a, b, M2 = ot.utils.clean_zeros(u1, u2, M) assert len(a) == n - nz assert len(b) == n - nz2
def test_entropic_gromov(): n_samples = 50 # nb samples mu_s = np.array([0, 0]) cov_s = np.array([[1, 0], [0, 1]]) xs = ot.datasets.get_2D_samples_gauss(n_samples, mu_s, cov_s) xt = xs[::-1].copy() p = ot.unif(n_samples) q = ot.unif(n_samples) C1 = ot.dist(xs, xs) C2 = ot.dist(xt, xt) C1 /= C1.max() C2 /= C2.max() G = ot.gromov.entropic_gromov_wasserstein( C1, C2, p, q, 'square_loss', epsilon=5e-4) # check constratints np.testing.assert_allclose( p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose( q, G.sum(0), atol=1e-04) # cf convergence gromov gw, log = ot.gromov.entropic_gromov_wasserstein2( C1, C2, p, q, 'kl_loss', epsilon=1e-2, log=True) G = log['T'] np.testing.assert_allclose(gw, 0, atol=1e-1, rtol=1e-1) # check constratints np.testing.assert_allclose( p, G.sum(1), atol=1e-04) # cf convergence gromov np.testing.assert_allclose( q, G.sum(0), atol=1e-04) # cf convergence gromov
def test_gromov_barycenter(): ns = 50 nt = 60 Xs, ys = ot.datasets.get_data_classif('3gauss', ns) Xt, yt = ot.datasets.get_data_classif('3gauss2', nt) C1 = ot.dist(Xs) C2 = ot.dist(Xt) n_samples = 3 Cb = ot.gromov.gromov_barycenters(n_samples, [C1, C2], [ot.unif(ns), ot.unif(nt) ], ot.unif(n_samples), [.5, .5], 'square_loss', # 5e-4, max_iter=100, tol=1e-3) np.testing.assert_allclose(Cb.shape, (n_samples, n_samples)) Cb2 = ot.gromov.gromov_barycenters(n_samples, [C1, C2], [ot.unif(ns), ot.unif(nt) ], ot.unif(n_samples), [.5, .5], 'kl_loss', # 5e-4, max_iter=100, tol=1e-3) np.testing.assert_allclose(Cb2.shape, (n_samples, n_samples))
pl.xlabel('x') pl.ylabel('y') pl.legend() pl.title('Toy regression example') #%% TLOT itermax=5 alpha=1 C0=cdist(xs,xt,metric='sqeuclidean') #print np.max(C0) C0=C0/np.median(C0) fcost = cdist(ys,yt,metric='sqeuclidean') C=alpha*C0+fcost G0=ot.emd(ot.unif(n),ot.unif(n),C) fit_params={'epochs':100} model,loss = jdot.jdot_nn_l2(get_model,xs,ys,xt,ytest=yt,fit_params=fit_params,numIterBCD = itermax, alpha=alpha) ypred=model.predict(xvisu.reshape((-1,1))) pl.figure(2) pl.clf() pl.scatter(xs,ys,label='Source samples',edgecolors='k') pl.scatter(xt,yt,label='Target samples',edgecolors='k') pl.plot(xvisu,fs_s(xvisu),'b',label='Source model') pl.plot(xvisu,fs_t(xvisu),'g',label='Target model') pl.plot(xvisu,ypred,'r',label='JDOT model')
import ot import ot.plot ############################################################################## # Dataset 1 : uniform sampling # ---------------------------- n = 20 # nb samples xs = np.zeros((n, 2)) xs[:, 0] = np.arange(n) + 1 xs[:, 1] = (np.arange(n) + 1) * -0.001 # to make it strictly convex... xt = np.zeros((n, 2)) xt[:, 1] = np.arange(n) + 1 a, b = ot.unif(n), ot.unif(n) # uniform distribution on samples # loss matrix M1 = ot.dist(xs, xt, metric='euclidean') M1 /= M1.max() # loss matrix M2 = ot.dist(xs, xt, metric='sqeuclidean') M2 /= M2.max() # loss matrix Mp = np.sqrt(ot.dist(xs, xt, metric='euclidean')) Mp /= Mp.max() # Data pl.figure(1, figsize=(7, 3))
C1 /= C1.max() C2 /= C2.max() pl.figure() pl.subplot(121) pl.imshow(C1) pl.subplot(122) pl.imshow(C2) pl.show() ############################################################################# # # Compute Gromov-Wasserstein plans and distance # --------------------------------------------- p = ot.unif(n_samples) q = ot.unif(n_samples) gw0, log0 = ot.gromov.gromov_wasserstein( C1, C2, p, q, 'square_loss', verbose=True, log=True) gw, log = ot.gromov.entropic_gromov_wasserstein( C1, C2, p, q, 'square_loss', epsilon=5e-4, log=True, verbose=True) print('Gromov-Wasserstein distances: ' + str(log0['gw_dist'])) print('Entropic Gromov-Wasserstein distances: ' + str(log['gw_dist'])) pl.figure(1, (10, 5))
def test_otda(): n_samples = 150 # nb samples np.random.seed(0) xs, ys = ot.datasets.get_data_classif('3gauss', n_samples) xt, yt = ot.datasets.get_data_classif('3gauss2', n_samples) a, b = ot.unif(n_samples), ot.unif(n_samples) # LP problem da_emd = ot.da.OTDA() # init class da_emd.fit(xs, xt) # fit distributions da_emd.interp() # interpolation of source samples da_emd.predict(xs) # interpolation of source samples np.testing.assert_allclose(a, np.sum(da_emd.G, 1)) np.testing.assert_allclose(b, np.sum(da_emd.G, 0)) # sinkhorn regularization lambd = 1e-1 da_entrop = ot.da.OTDA_sinkhorn() da_entrop.fit(xs, xt, reg=lambd) da_entrop.interp() da_entrop.predict(xs) np.testing.assert_allclose( a, np.sum(da_entrop.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_entrop.G, 0), rtol=1e-3, atol=1e-3) # non-convex Group lasso regularization reg = 1e-1 eta = 1e0 da_lpl1 = ot.da.OTDA_lpl1() da_lpl1.fit(xs, ys, xt, reg=reg, eta=eta) da_lpl1.interp() da_lpl1.predict(xs) np.testing.assert_allclose(a, np.sum(da_lpl1.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_lpl1.G, 0), rtol=1e-3, atol=1e-3) # True Group lasso regularization reg = 1e-1 eta = 2e0 da_l1l2 = ot.da.OTDA_l1l2() da_l1l2.fit(xs, ys, xt, reg=reg, eta=eta, numItermax=20, verbose=True) da_l1l2.interp() da_l1l2.predict(xs) np.testing.assert_allclose(a, np.sum(da_l1l2.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_l1l2.G, 0), rtol=1e-3, atol=1e-3) # linear mapping da_emd = ot.da.OTDA_mapping_linear() # init class da_emd.fit(xs, xt, numItermax=10) # fit distributions da_emd.predict(xs) # interpolation of source samples # nonlinear mapping da_emd = ot.da.OTDA_mapping_kernel() # init class da_emd.fit(xs, xt, numItermax=10) # fit distributions da_emd.predict(xs) # interpolation of source samples