def save_traverse_new(self, iters, num_reps, limb=-3, limu=3, inter=2 / 3, loc=-1): encoderA = self.encoderA encoderB = self.encoderB decoderA = self.decoderA decoderB = self.decoderB interpolation = torch.arange(limb, limu + 0.001, inter) np.random.seed(123) rii = np.random.randint(self.N, size=num_reps) #--# prn_str = '(TRAVERSAL) random image IDs = {}'.format(rii) print(prn_str) self.dump_to_record(prn_str) #--# random_XA = [0] * num_reps random_XB = [0] * num_reps random_zmu = [0] * num_reps for i, i2 in enumerate(rii): random_XA[i], random_XB[i] = \ self.data_loader.dataset.__getitem__(i2)[0:2] if self.use_cuda: random_XA[i] = random_XA[i].cuda() random_XB[i] = random_XB[i].cuda() random_XA[i] = random_XA[i].unsqueeze(0) random_XB[i] = random_XB[i].unsqueeze(0) # mu_infA, std_infA, logvar_infA = encoderA(random_XA[i]) mu_infB, std_infB, logvar_infB = encoderB(random_XB[i]) random_zmu[i], _, _ = apply_poe(self.use_cuda, mu_infA, logvar_infA, mu_infB, logvar_infB) if self.dataset.lower() == 'idaz_elli_3df': fixed_idxs = [10306, 7246, 21440] fixed_XA = [0] * len(fixed_idxs) fixed_XB = [0] * len(fixed_idxs) fixed_zmu = [0] * len(fixed_idxs) for i, idx in enumerate(fixed_idxs): fixed_XA[i], fixed_XB[i] = \ self.data_loader.dataset.__getitem__(idx)[0:2] if self.use_cuda: fixed_XA[i] = fixed_XA[i].cuda() fixed_XB[i] = fixed_XB[i].cuda() fixed_XA[i] = fixed_XA[i].unsqueeze(0) fixed_XB[i] = fixed_XB[i].unsqueeze(0) mu_infA, std_infA, logvar_infA = encoderA(fixed_XA[i]) mu_infB, std_infB, logvar_infB = encoderB(fixed_XB[i]) fixed_zmu[i], _, _ = apply_poe(self.use_cuda, mu_infA, logvar_infA, mu_infB, logvar_infB) IMG = {} for i, idx in enumerate(fixed_idxs): IMG['fixed'+str(i)] = \ torch.cat([fixed_XA[i], fixed_XB[i]], dim=2) for i in range(num_reps): IMG['random'+str(i)] = \ torch.cat([random_XA[i], random_XB[i]], dim=2) Z = {} for i, idx in enumerate(fixed_idxs): Z['fixed' + str(i)] = fixed_zmu[i] for i in range(num_reps): Z['random' + str(i)] = random_zmu[i] else: raise NotImplementedError WS = torch.ones(IMG['fixed1'].shape) if self.use_cuda: WS = WS.cuda() # do traversal and collect generated images gifs = [] for key in Z: z_ori = Z[key] # traversal over z for val in interpolation: gifs.append(WS) for row in range(self.z_dim): if loc != -1 and row != loc: continue z = z_ori.clone() for val in interpolation: z[:, row] = val sampleA = torch.sigmoid(decoderA(z)).data sampleB = torch.sigmoid(decoderB(z)).data sample = torch.cat([sampleA, sampleB], dim=2) gifs.append(sample) #### # save the generated files, also the animated gifs out_dir = os.path.join(self.output_dir_trvsl, str(iters)) mkdirs(self.output_dir_trvsl) mkdirs(out_dir) gifs = torch.cat(gifs) gifs = gifs.view(len(Z), 1 + self.z_dim, len(interpolation), self.nc, 2 * 64, 64).transpose(1, 2) for i, key in enumerate(Z.keys()): for j, val in enumerate(interpolation): I = torch.cat([IMG[key], gifs[i][j]], dim=0) save_image(tensor=I.cpu(), filename=os.path.join(out_dir, '%s_%03d.jpg' % (key, j)), nrow=1 + 1 + self.z_dim, pad_value=1) # make animated gif grid2gif(out_dir, key, str(os.path.join(out_dir, key + '.gif')), delay=10)
def eval_disentangle_metric2(self): # some hyperparams num_pairs = 800 # # data pairs (d,y) for majority vote classification bs = 50 # batch size nsamps_per_factor = 100 # samples per factor nsamps_agn_factor = 5000 # factor-agnostic samples self.set_mode(train=False) # 1) estimate variances of latent points factor agnostic dl = DataLoader(self.data_loader.dataset, batch_size=bs, shuffle=True, num_workers=self.args.num_workers, pin_memory=True) iterator = iter(dl) M = [] for ib in range(int(nsamps_agn_factor / bs)): # sample a mini-batch XAb, XBb, _, _, _ = next(iterator) # (bs x C x H x W) if self.use_cuda: XAb = XAb.cuda() XBb = XBb.cuda() # z = encA(xA) mu_infA, _, logvar_infA = self.encoderA(XAb) # z = encB(xB) mu_infB, _, logvar_infB = self.encoderB(XBb) # z = encAB(xA,xB) via POE mu_POE, _, _ = apply_poe( self.use_cuda, mu_infA, logvar_infA, mu_infB, logvar_infB, ) mub = mu_POE M.append(mub.cpu().detach().numpy()) M = np.concatenate(M, 0) # estimate sample vairance and mean of latent points for each dim vars_agn_factor = np.var(M, 0) # 2) estimatet dim-wise vars of latent points with "one factor varied" factor_ids = range(0, len(self.latent_sizes)) # true factor ids vars_per_factor = np.zeros([num_pairs, self.z_dim]) true_factor_ids = np.zeros(num_pairs, np.int) # true factor ids # prepare data pairs for majority-vote classification i = 0 for j in factor_ids: # for each factor # repeat num_paris/num_factors times for r in range(int(num_pairs / len(factor_ids))): # randomly choose true factors (id's and class values) to fix fac_ids = list(np.setdiff1d(factor_ids, j)) fac_classes = \ [ np.random.randint(self.latent_sizes[k]) for k in fac_ids ] # randomly select images (with the other factors fixed) if len(fac_ids) > 1: indices = np.where( np.sum(self.latent_classes[:, fac_ids] == fac_classes, 1) == len(fac_ids))[0] else: indices = np.where( self.latent_classes[:, fac_ids] == fac_classes)[0] np.random.shuffle(indices) idx = indices[:nsamps_per_factor] M = [] for ib in range(int(nsamps_per_factor / bs)): XAb, XBb, _, _, _ = dl.dataset[idx[(ib * bs):(ib + 1) * bs]] if XAb.shape[0] < 1: # no more samples continue if self.use_cuda: XAb = XAb.cuda() XBb = XBb.cuda() mu_infA, _, logvar_infA = self.encoderA(XAb) mu_infB, _, logvar_infB = self.encoderB(XBb) mu_POE, _, _ = apply_poe( self.use_cuda, mu_infA, logvar_infA, mu_infB, logvar_infB, ) mub = mu_POE M.append(mub.cpu().detach().numpy()) M = np.concatenate(M, 0) # estimate sample var and mean of latent points for each dim if M.shape[0] >= 2: vars_per_factor[i, :] = np.var(M, 0) else: # not enough samples to estimate variance vars_per_factor[i, :] = 0.0 # true factor id (will become the class label) true_factor_ids[i] = j i += 1 # 3) evaluate majority vote classification accuracy # inputs in the paired data for classification largest_var_dims = np.argmax(vars_per_factor / (vars_agn_factor + 1e-20), axis=1) # contingency table C = np.zeros([self.z_dim, len(factor_ids)]) for i in range(num_pairs): C[largest_var_dims[i], true_factor_ids[i]] += 1 num_errs = 0 # # misclassifying errors of majority vote classifier for k in range(self.z_dim): num_errs += np.sum(C[k, :]) - np.max(C[k, :]) metric2 = (num_pairs - num_errs) / num_pairs # metric = accuracy self.set_mode(train=True) return metric2, C