Beispiel #1
0
    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)
Beispiel #2
0
    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