def pca_kde(z_data, m_out_data, encoded, dim=1, show_mapped=False, show_z=False, show_Ex=False): plt.clf() if show_z and not show_mapped: all_data = torch.cat([z_data, encoded]) U, S, V = torch.pca_lowrank(all_data) pca1 = torch.matmul(z_data, V[:, :dim]) pca3 = torch.matmul(encoded, V[:, :dim]) sns.kdeplot(pca3.flatten().numpy(), label='E(x)-optimize', alpha=0.6, color='r') plot = sns.kdeplot(pca1.flatten().numpy(), label='Z-target', alpha=0.6, color='b') if show_mapped and not show_z: all_data = torch.cat([m_out_data, encoded]) U, S, V = torch.pca_lowrank(all_data) pca2 = torch.matmul(m_out_data, V[:, :dim]) pca3 = torch.matmul(encoded, V[:, :dim]) sns.kdeplot(pca2.flatten().numpy(), label='M(z)-optimize', alpha=0.6, color='r') plot = sns.kdeplot(pca3.flatten().numpy(), label='E(x)-target', alpha=0.6, color='b') if show_mapped and not show_Ex: #case vanilla-mimic all_data = torch.cat([z_data, encoded]) U, S, V = torch.pca_lowrank(all_data) pca1 = torch.matmul(z_data, V[:, :dim]) pca2 = torch.matmul(m_out_data, V[:, :dim]) pca3 = torch.matmul(encoded, V[:, :dim]) sns.kdeplot(pca2.flatten().numpy(), label='M(E(x))-optimize', alpha=0.6, color='b') sns.kdeplot(pca3.flatten().numpy(), label='E(x)-input', alpha=0.6, color='r') plot = sns.kdeplot(pca1.flatten().numpy(), label='Z-target', alpha=0.6, color='g') plot.legend() return plot
def init(self, X): # generate map self.z = tensor(self.get_lattice_points(self.n_grids), requires_grad=False) self.rbfs = tensor(self.get_lattice_points(self.n_rbfs), requires_grad=False) d = cdist(self.z, self.rbfs, p=2).square_() self.phi = exp(-d / (2 * self.sigma)) # init W and beta from PCA if not self.pca: #use torch oca _, explained_variance, components = pca_lowrank(X, center=self.center, q=X.size()[1]) else: pca = PCA(n_components=self.n_components + 1, random_state=11) pca.fit(X) components = tensor(pca.components_) explained_variance = tensor(pca.explained_variance_) self.W = matmul(matmul(pinverse(self.phi), self.z), components[:self.n_components, :]) betainv1 = explained_variance[self.n_components] inter_dist = cdist(matmul(self.phi, self.W), matmul(self.phi, self.W), p=2) inter_dist.fill_diagonal_(np.inf) betainv2 = inter_dist.min(axis=0).values.mean() / 2 self.beta = 1 / max(betainv1, betainv2)
def get_principal_directions(self, x, num_dims): q = min(x.size(1), 1024) if len(x.shape) == 4: x = x.permute(0, 2, 3, 1) x = x.reshape(-1, x.size(3)) _, _, V = torch.pca_lowrank(x, q=q, niter=10) return V[:, :num_dims]
def __call__(self, seed_embeddings: torch.Tensor): """ # Parameters !!! Note In the examples below, we treat gender identity as binary, which does not accurately characterize gender in real life. seed_embeddings : `torch.Tensor` A tensor of size (batch_size, ..., dim) containing seed word embeddings related to a concept. For example, if the concept is gender, seed_embeddings could contain embeddings for words like "man", "king", "brother", "woman", "queen", "sister", etc. # Returns bias_direction : `torch.Tensor` A unit tensor of size (dim, ) representing the concept subspace. """ # Some sanity checks if seed_embeddings.ndim < 2: raise ConfigurationError( "seed_embeddings1 must have at least two dimensions.") with torch.set_grad_enabled(self.requires_grad): # pca_lowrank centers the embeddings by default # There will be two dimensions when applying PCA to # definitionally-gendered words: 1) the gender direction, # 2) all other directions, with the gender direction being principal. _, _, V = torch.pca_lowrank(seed_embeddings, q=2) # get top principal component bias_direction = V[:, 0] return self._normalize_bias_direction(bias_direction)
def __init__(self, device, data, z_dim=10, sz=64): self.z_dim = z_dim self.sz = sz self.cached = True d = data.cpu().float().view(-1, sz * sz) (U, S, V) = torch.pca_lowrank(d, q=z_dim) self.encoded = torch.matmul(d, V[:, :z_dim])
def learningprior_latent_pca_plt(z, E_x, M_z, dim=1): fig1, ax1 = plt.subplots() all_data = torch.cat([E_x, M_z]) U, S, V = torch.pca_lowrank(all_data) pca_z = torch.matmul(z, V[:, :dim]) pca_Ex = torch.matmul(E_x, V[:, :dim]) pca_Mz = torch.matmul(M_z, V[:, :dim]) sns.kdeplot(pca_Ex.flatten().numpy(), label='E(x):optimize', alpha=0.6, color='r', ax=ax1) sns.kdeplot(pca_Mz.flatten().numpy(), label='M(z):target', alpha=0.6, color='b', ax=ax1) sns.kdeplot(pca_z.flatten().numpy(), label='z:input', alpha=0.6, color='g', ax=ax1) ax1.legend() ax1.set_title('latent kde in pca to %d dim ' % dim) return fig1
def fit(self, X_cpu, y_cpu=None, transform=False): ### Input matrix `X_cpu` sould have member variable `.shape` and ### the length of the shape should be 2 (i.e. 2-dimensional matrix). if not (hasattr(X_cpu, "shape") and len(X_cpu.shape) == 2): raise RuntimeError( "PCA.fit: input variable should be 2-dimensional matrix.") ### Move variable to GPU. X = torch.from_numpy(X_cpu).to(self.dev) ### Calculate PCA. For getting stable results, subtract average before hand. m = torch.mean(X, dim=0) U, S, V = torch.pca_lowrank(X - m, self.n_components_, center=False, niter=self.niter) ### Store the PCA results as NumPy array on CPU. self.mean_ = m.cpu().numpy() self.components_ = V.cpu().numpy().T self.explained_variance_ = np.square( S.cpu().numpy()) / (X_cpu.shape[0] - 1) ### Return transform results of `X_cpu` if `transform` is True. if transform: return torch.matmul(X - m, V).cpu().numpy() else: return self
def get_pca(vec, k, normalize=True, verbose=False): if normalize: if verbose: print("mean:", torch.mean(vec, 0, True)) print("standard deviation:", torch.std(vec, 0, True)) vec = (vec - torch.mean(vec, 0, True)) / torch.std(vec, 0, True) u, s, v = torch.pca_lowrank(vec) return torch.matmul(vec, v[:, :k])
def __call__(self, seed_embeddings1: torch.Tensor, seed_embeddings2: torch.Tensor): """ # Parameters !!! Note In the examples below, we treat gender identity as binary, which does not accurately characterize gender in real life. seed_embeddings1 : `torch.Tensor` A tensor of size (batch_size, ..., dim) containing seed word embeddings related to a concept group. For example, if the concept is gender, seed_embeddings1 could contain embeddings for linguistically masculine words, e.g. "man", "king", "brother", etc. seed_embeddings2: `torch.Tensor` A tensor of the same size as seed_embeddings1 containing seed word embeddings related to a different group for the same concept. For example, seed_embeddings2 could contain embeddings for linguistically feminine words, e.g. "woman", "queen", "sister", etc. !!! Note For Paired-PCA, the embeddings at the same positions in each of seed_embeddings1 and seed_embeddings2 are expected to form seed word pairs. For example, if the concept is gender, the embeddings for ("man", "woman"), ("king", "queen"), ("brother", "sister"), etc. should be at the same positions in seed_embeddings1 and seed_embeddings2. !!! Note All tensors are expected to be on the same device. # Returns bias_direction : `torch.Tensor` A unit tensor of size (dim, ) representing the concept subspace. """ # Some sanity checks if seed_embeddings1.size() != seed_embeddings2.size(): raise ConfigurationError( "seed_embeddings1 and seed_embeddings2 must be the same size.") if seed_embeddings1.ndim < 2: raise ConfigurationError( "seed_embeddings1 and seed_embeddings2 must have at least two dimensions." ) with torch.set_grad_enabled(self.requires_grad): paired_embeddings = seed_embeddings1 - seed_embeddings2 _, _, V = torch.pca_lowrank( paired_embeddings, q=min(paired_embeddings.size(0), paired_embeddings.size(1)) - 1, center=False, ) bias_direction = V[:, 0] return self._normalize_bias_direction(bias_direction)
def pca(a: torch.Tensor, n_dim: int = 2) -> torch.Tensor: """ From pytorch example. Small helper function to perform a PCA and project on the N_dim relevant dimmensions for clustering :param a: :param n_dim: :return: """ assert a.ndim == 2 (U, S, V) = torch.pca_lowrank(a) return torch.matmul(a, V[:, :n_dim])
def f_spicy_GreeDS(x, algo, ncomp): """ f_spicy_GreeDS(x,algo,ncomp) Compute a single iteration of the spicy-GreeDS algorithm. Parameters ---------- x : numpy.array current estimate of the circumstellar signal algo : instance of a subclass of mayonnaise_pipeline ncomp: int rank of the speckle field component (xl) Returns ------- frame : numpy.array Current image produced by spicy-GreeDS. L : numpy.array Current speckle field estimated by spicy-GreeDS. """ with torch.no_grad(): device = algo.data.device X = x.expand(algo.t, algo.n, algo.n) R = algo.data - mayo_hci.cube_rotate_kornia( x.expand(algo.t, algo.n, algo.n), algo.pa_rotate_matrix).expand( 2, algo.t, algo.n, algo.n) U, Sigma, V = torch.pca_lowrank(0.5 * (R[0] + mayo_hci.scale_cube( R[1], algo.contraction_matrix)).reshape(algo.t, algo.n * algo.n), q=ncomp, niter=4, center=False) L = (U @ torch.diag(Sigma) @ V.T).reshape(algo.t, algo.n, algo.n) #U_np, S_np, V_np = np.linalg.svd(0.5*(R[0]+mayo_hci.scale_cube(R[1] ,algo.contraction_matrix)).reshape(algo.t,algo.n*algo.n).to('cpu').detach().numpy(),full_matrices=False) #U = torch.from_numpy(U_np).to(device) #Sigma = torch.from_numpy(S_np).to(device) #V = torch.from_numpy(V_np.T).to(device) #L = (U[:,:ncomp] @ torch.diag(Sigma[:ncomp]) @ V[:,:ncomp].T).reshape(algo.t,algo.n,algo.n) S_0 = algo.data[0] - L S_1 = algo.data[1] - mayo_hci.scale_cube(L, algo.dilatation_matrix) S_der = 0.5 * ( mayo_hci.cube_rotate_kornia(S_0, algo.pa_derotate_matrix) + mayo_hci.cube_rotate_kornia(S_1, algo.pa_derotate_matrix)) frame = torch.mean(S_der, axis=0) * algo.mask frame *= frame > 0 return frame, L
def tensorboard_singular_value_plot(predictions, targets, writer: SummaryWriter, step, data_split): u, s, v = torch.pca_lowrank(predictions.detach().cpu(), q=min(predictions.shape)) fig, ax = plt.subplots() s = 100 * s / s.sum() ax.plot(s.numpy()) writer.add_figure(f'singular_values/{data_split}', figure=fig, global_step=step) fig, ax = plt.subplots() ax.plot(np.cumsum(s.numpy())) writer.add_figure(f'singular_values_cumsum/{data_split}', figure=fig, global_step=step)
def knn(x, k, dim_reduce=False): batch_size, num_features, num_points = x.shape # Dimensionality reduction if num_features == 6: x = x[:, :3, :] elif dim_reduce: U, S, V = torch.pca_lowrank(x.transpose(-2, -1)) x = torch.matmul(V.transpose(-2, -1), x) # Find pairwise Euclidean distances inner = -2*torch.matmul(x.transpose(2, 1), x) xx = torch.sum(x**2, dim=1, keepdim=True) pairwise_distance = -xx - inner - xx.transpose(2, 1) idx = pairwise_distance.topk(k=k, dim=-1)[1] # (batch_size, num_points, k) return idx
def pca(As, rank): # can deal with either list of inputs or a single A vector if type(As) is not list: As = [As] N = len(As) # mix up the samples and timesteps, but keep the dimensions A = torch.cat(As) u, s, v = torch.pca_lowrank(A) projs = [] for ix in range(N): traj = As[ix] traj_proj = traj @ v[:, :rank] projs.append(traj_proj) return projs
def fit(self, x): assert len(x.shape) == 2 assert x.dtype == 'float32' n, d = x.shape # TODO: Check if fits in GPU, Implement incremental PCA _x = torch.from_numpy(x) _mu = _x.mean(dim=0, keepdim=True) Z, S, V = torch.pca_lowrank((_x - _mu).cuda(), q=self.n_components, niter=3, center=False) # Z, S, V = torch.pca_lowrank((_x-_mu), q=self.n_components, niter=3, center=False) self.mean_ = _mu.numpy() self.components_ = V.cpu().numpy().T self.explained_variance_ = np.square(S.cpu().numpy()) / (n - 1) return self
def pca_performance(X, targets, dim=2): # if type(X) == "list": X = torch.tensor(np.array(X)) U, S, V = torch.pca_lowrank(X) low_rank = torch.matmul(X, V[:, :dim]).detach().numpy() rgbs = cmap(gradient[targets]) fig = plt.figure() if (dim == 2): plt.scatter(low_rank[:, 0], low_rank[:, 1], s=50, c=rgbs, alpha=0.5) plt.xticks([-.8, 0, .8], []) plt.yticks([-1, 0, 1], []) plt.xlim([-.8, .8]) plt.ylim([-1, 1]) elif (dim == 3): ax = fig.add_subplot(111, projection='3d') ax.scatter(low_rank[:, 0], low_rank[:, 1], low_rank[:, 2], s=6) # plt.legend() # plt.title("PCA") plt.show() pca_results = {"low_rank": low_rank, "targets": targets} pca_hist_stack(low_rank, targets, num_bins=50) return pca_results
def load_state_dict(state: table): max_rank = r if isinstance(state, nn.Module): state = state.state_dict() state = state.copy() if max_rank == -1 and f"_{name}" in state: getattr(self, f"_{name}").data.copy_(state[f"_{name}"]) elif max_rank != -1 and f"_{name}_U" in state and f"_{name}_V" in state: U = state[f"_{name}_U"] V = state[f"_{name}_V"] getattr(self, f"_{name}_V").data.copy_(V) getattr(self, f"_{name}_U").data.copy_(U) elif max_rank != -1 and f"_{name}" in state: U, S, V = torch.pca_lowrank(state[f"_{name}"], q=max_rank, center=False) getattr(self, f"_{name}_V").data.copy_(V @ torch.diag(torch.sqrt(S))) getattr(self, f"_{name}_U").data.copy_(U @ torch.diag(torch.sqrt(S))) elif max_rank == -1 and f"_{name}_U" in state and f"_{name}_V" in state: U = state[f"_{name}_U"] V = state[f"_{name}_V"] getattr(self, f"_{name}").data.copy_(U @ V.T)
def fit(self, X_CPU, transform = False, adjust_sign = True): if not (hasattr(X_CPU, "shape") and len(X_CPU.shape) == 2): raise RuntimeError("PCA.fit: input variable should be 2-dimensional matrix.") X = torch.from_numpy(X_CPU).to(self.device) m = torch.mean(X, dim = 0) U, S, V = torch.pca_lowrank(X - m, self.n_components, center = False, niter = self.niter) Z = torch.matmul(X - m, V) if adjust_sign: s = torch.sign(torch.mean(Z**3, axis = 0)) V = V * s[np.newaxis, :] Z = torch.matmul(X - m, V) self.mean_ = m.cpu().numpy() self.components_ = V.cpu().numpy().T self.explained_variance_ = np.square(S.cpu().numpy()) / (X_CPU.shape[0] - 1) if transform: return Z.cpu().numpy() else : return self
def _init_pca(Y, latent_dim): U, S, V = torch.pca_lowrank(Y, q=latent_dim) return torch.nn.Parameter(torch.matmul(Y, V[:, :latent_dim]))
def pca(data): print(data.size()) (U, S, V) = torch.pca_lowrank(data) return (U, S, V)
def compute_pca(self, embeddings): u, s, v = torch.pca_lowrank(embeddings) return torch.matmul(embeddings, v[:, :2])
def pca_torch(self, x: torch.Tensor, normalize=None): with torch.no_grad(): U, S, V = torch.pca_lowrank(x.T, center=False, niter=10) return torch.matmul(x.T, V[:, :3]), S[:3].sum() / S.sum()
plt.plot(sorted_t.numpy(), sorted_mu.numpy(), label=str(tt), color=colors[i]) # plt.legend() plt.savefig(save_folder + str(N_decoding) + 'interpolation_nolegend.png', dpi=800) # Experiment 2: PCA in latent space # We encode different time series dynamics context points into the # latent space and use PCA to visualize the different mean encodings # (mu_z). # Note the strong separation between different dynamics. k = 2 # number of principal components (2 for visualization) A = torch.cat([A for freq, A, _ in results]) with torch.no_grad(): U, S, V = torch.pca_lowrank(A) proj = torch.matmul(A, V[:, :k]).cpu().numpy() colors = matplotlib.cm.winter(np.linspace(0, 1, len(freqs))) plt.figure() for i, freq in enumerate(freqs): plt.scatter(proj[i * 100:(i + 1) * 100, 0], proj[i * 100:(i + 1) * 100, 1], color=colors[i], label='freq= ' + str(freq)) # plt.legend() plt.savefig(save_folder + str(N_decoding) + 'pca_nolegend.png', dpi=800)
flattened_image_array = np.array([im.flatten() for im in imagelist]) dataset_config_dir, dataset_config_basefile = os.path.split( dataset_config_file) base_file_name = os.path.splitext(dataset_config_basefile)[0] + ( "_pca_%d" % (num_components, )) print("Fitting a %d-component pca with %d samples" % (num_components, flattened_image_array.shape[0])) if gpu >= 0: flattened_image_torch = torch.from_numpy(flattened_image_array).cuda(gpu) flattened_image_torch.requires_grad = False flattened_image_stdevs, flattened_image_means = torch.std_mean( flattened_image_torch, dim=0) q = min(num_components, flattened_image_torch.shape[0], flattened_image_torch.shape[1]) U, S, V = torch.pca_lowrank(flattened_image_torch, niter=3, q=q, center=True) irand = int( np.random.randint(0, high=flattened_image_torch.shape[0], dtype=np.int64)) improj = torch.matmul( (flattened_image_torch[irand] - flattened_image_means).unsqueeze(0), V[:, :num_components]) # imrtreshape = (255.0*torch.clamp(torch.matmul(improj, V[:, :num_components].t())[0] + flattened_image_means, 0.0, 1.0)).cpu().numpy().astype(np.uint8).reshape(sourcesize).transpose(1,2,0) imrtreshape = (255.0 * torch.clamp( torch.matmul(improj, V[:, :num_components].t())[0] + flattened_image_means, 0.0, 1.0)).cpu().numpy().astype( np.uint8).reshape(sourcesize).transpose(1, 2, 0)
def calculate_generative_score(self, feature_pca_plot=False): fid = self.calculate_frechet_distance(self.real_mu, self.real_sigma, self.fake_mu, self.fake_sigma) real_pick = np.random.permutation(self.real_feature_np)[:10000] fake_pick = np.random.permutation(self.fake_feature_np)[:10000] metrics = prdc.compute_prdc(real_features=real_pick, fake_features=fake_pick, nearest_k=5) metrics['fid'] = fid metrics['real_is'] = self.real_inception_score metrics['fake_is'] = self.fake_inception_score if feature_pca_plot: ''' plt.clf() real = torch.tensor(real_pick) fake = torch.tensor(fake_pick) real_fake = torch.cat([real, fake]) U, S, V = torch.pca_lowrank(real_fake) real_pca2 = torch.matmul(real, V[:, :2]) fake_pca2 = torch.matmul(fake, V[:, :2]) plt.scatter(fake_pca2[:,0], fake_pca2[:,1], label='fake', alpha=0.6, s=0.1) plot = plt.scatter(real_pca2[:,0], real_pca2[:,1], label='real', alpha=0.6, s=0.1) plt.legend() plt.xlabel('pca dim1') plt.ylabel('pca dim2') return metrics, plot ''' real_feature = torch.tensor(self.real_feature_np) fake_feature = torch.tensor(self.fake_feature_np) fake_real = torch.cat((real_feature, fake_feature)) U, S, V = torch.pca_lowrank(fake_real) real_pick = torch.tensor( np.random.permutation(self.real_feature_np)[:2048]) fake_pick = torch.tensor( np.random.permutation(self.fake_feature_np)[:2048]) real_pca = torch.matmul(real_pick, V[:, :3]) fake_pca = torch.matmul(fake_pick, V[:, :3]) plt.clf() fig = plt.figure(figsize=(6, 6)) ax = fig.add_subplot(111, projection='3d') ax.scatter(real_pca[:, 0], real_pca[:, 1], real_pca[:, 2], alpha=0.2, label='real', zorder=0) ax.scatter(fake_pca[:, 0], fake_pca[:, 1], fake_pca[:, 2], alpha=0.2, label='fake', zorder=10) mean_x_fake, mean_y_fake, mean_z_fake = torch.mean( fake_pca[:, 0]), torch.mean(fake_pca[:, 1]), torch.mean(fake_pca[:, 2]) mean_x_real, mean_y_real, mean_z_real = torch.mean( real_pca[:, 0]), torch.mean(real_pca[:, 1]), torch.mean(real_pca[:, 2]) diff = ((mean_x_fake - mean_x_real)**2 + (mean_y_fake - mean_y_real)**2 + (mean_z_fake - mean_z_real)**2)**0.5 ann_x, ann_y, ann_z = (mean_x_fake + mean_x_real) / 2, ( mean_y_fake + mean_y_real) / 2, (mean_z_fake + mean_z_real) / 2 ax.plot((mean_x_real, mean_x_fake), (mean_y_real, mean_y_fake), (mean_z_real, mean_z_fake), color='black', lw=3, zorder=15, marker='*', linestyle='--') ax.text(ann_x, ann_y, ann_z, ' %.1f ' % diff, 'y', fontsize=20, zorder=15) ax.legend() ax.set_title('PCA to 3D feature scatter') return metrics, fig else: return metrics
def sumin_pca(self, X, k): u, s, v = torch.pca_lowrank(X, center=True) return torch.mm(X, v[:, :k])
def _init_pca(self): U, S, V = torch.pca_lowrank(self.Y.T) self.X = torch.nn.Parameter( torch.matmul(self.Y.T, V[:, :self.latent_dim]))
def create_traced_func(func, device, batch_size): traced_func = torch.jit.trace( func, (TestSymEig3x3.create_random_sym3x3(device, batch_size), )) return traced_func FUNC_NAME_TO_FUNC = { "sym3x3eig": (lambda inputs: symeig3x3(inputs, eigenvectors=True)), "sym3x3eig_traced_cuda": create_traced_func((lambda inputs: symeig3x3(inputs, eigenvectors=True)), CUDA_DEVICE, 1024), "torch_symeig": (lambda inputs: torch.symeig(inputs, eigenvectors=True)), "torch_linalg_eigh": (lambda inputs: torch.linalg.eigh(inputs)), "torch_pca_lowrank": (lambda inputs: torch.pca_lowrank(inputs, center=False, niter=1)), "sym3x3eig_no_vecs": (lambda inputs: symeig3x3(inputs, eigenvectors=False)), "torch_symeig_no_vecs": (lambda inputs: torch.symeig(inputs, eigenvectors=False)), "torch_linalg_eigvalsh_no_vecs": (lambda inputs: torch.linalg.eigvalsh(inputs)), } def test_symeig3x3(func_name, batch_size, device) -> Callable[[], Any]: func = FUNC_NAME_TO_FUNC[func_name] inputs = TestSymEig3x3.create_random_sym3x3(device, batch_size) torch.cuda.synchronize() def symeig3x3():
def biggan_components(model, class_lbl, num_components=32, num_samples=12800, feat_size=128, method='sgd'): """ Args: model: BigGAN model instance num_components: number of PCA components num_samples: number of samples to estimate PCA feat_size: feature size of BigGAN method: method for solving for z-space principal components Quick and dirty implementation of: Erik Härkönen et al. - GANSpace: Discovering Interpretable GAN Controls https://github.com/harskish/ganspace https://arxiv.org/abs/2004.02546 WARNING: Do not use this as a benchmark for the work above. """ assert method in ['sgd', 'lstsq'] # Compute features and run PCA with torch.no_grad(): z = torch.randn(num_samples, feat_size).cuda() if type(class_lbl) is int: c = model.get_class_embedding(class_lbl) else: c = class_lbl c = c.repeat(z.size(0), 1) feat = model.generator.gen_z(torch.cat([z, c], 1)) feat_mean = feat.mean(0).unsqueeze(0) u, s, v = torch.pca_lowrank(feat, q=num_components) x = torch.mm(feat - feat_mean, v) if method == 'sgd': # convex problem, should converge fast u = torch.nn.parameter.Parameter( torch.randn(feat_size, num_components, requires_grad=True).cuda()) lr = 1 opt = torch.optim.Adam([u], lr=lr) for i in range(100): opt.zero_grad() loss = ((z - torch.mm(x, u.t()))**2).mean() loss.backward() opt.step() for param_group in opt.param_groups: param_group['lr'] = param_group['lr'] * 0.98 u = F.normalize(u, p=2, dim=1) elif method == 'lstsq': # torch.lstsq is throwing error, using SGD for now raise NotImplementedError() return u.permute(1, 0)
def main(): # Set configs torch.set_grad_enabled(False) device = 'cuda' path_factor = 'factor.pt' m = 3 degree = 10 truncation = 0.7 out_prefix = 'ganspace' imsize = 256 f_dict = torch.load(path_factor) #path_ckpt = f_dict['ckpt'] #path_ckpt = 'checkpoint/twdne3_dict.pt' #state_dict = torch.load(path_ckpt) path_ckpt = 'checkpoint/2020-01-11-skylion-stylegan2-animeportraits-networksnapshot-024664.pt' state_dict = torch.load(path_ckpt)['g'] print('loading eigenvector of %s' % (path_ckpt)) g = Generator(512, 512, 8).to(device) g.load_state_dict(state_dict) # TODO ganSpace의 code를 보았을 때 randn을 사용하는 것 같은데, randn과 rand의 차이 실험해보기 num_rands = 1024 zs = torch.rand(num_rands, 512).to(device) #zs = torch.randn(num_rands, 512).to(device) latents = g.style(zs) U, S, V = torch.pca_lowrank(latents, 512) V.to(device) trunc = g.mean_latent(4096) trunc = torch.load('trunc.pt') latent = torch.randn(1, 512, device=device) latent = g.get_latent(latent) latent = torch.load('latent.pt') print(latent[0, :10]) indices = torch.arange(100) imgs = torch.zeros((3, len(indices) * imsize, (2 * m + 1) * imsize)) for i in range(len(indices)): index = indices[i] direction = degree * V[:, index] scales = torch.linspace(-1, 1, 2 * m + 1) for j in range(len(scales)): scale = scales[j] * 1 # TODO 이거 이렇게 안 넣고 batch로 g에 넣어주면 되지 않나? img, _ = g([latent + scale * direction], truncation=truncation, truncation_latent=trunc, input_is='latent', randomize_noise=False) img = F.interpolate(img, (imsize, imsize)) imgs[:, i * imsize:(i + 1) * imsize, j * imsize:(j + 1) * imsize] = img[0] path_save = './control/%s_degree-%f.png' % (out_prefix, degree) imgs = torch.clamp(imgs * 256, 0, 255).type(torch.uint8) imgs = TF.to_pil_image(imgs.permute((1, 2, 0)).numpy()) imgs.save(path_save) print(path_save)