Beispiel #1
0
    def fit(self, model, train_data, val_data=None):
        logger = Logger() if self.config.log_file is not None else None
        train_loader = self.get_dataloader(model, train_data, shuffle=True)
        val_loader = None if val_data is None else self.get_dataloader(
            model, val_data, shuffle=False)
        self._train(model, train_loader, val_loader, logger)

        return model
Beispiel #2
0
    def fit(self, model, train_data, val_data=None):
        logger = Logger() if self.config.log_file is not None else None

        # Generator
        gen_collate_fn = self.generator_collate_fn(model)
        gen_train_loader = self.get_dataloader(model,
                                               train_data,
                                               gen_collate_fn,
                                               shuffle=True)
        gen_val_loader = None if val_data is None else self.get_dataloader(
            model, val_data, gen_collate_fn, shuffle=False)
        self._pretrain_generator(model, gen_train_loader, gen_val_loader,
                                 logger)

        # Discriminator
        dsc_collate_fn = self.discriminator_collate_fn(model)
        dsc_train_loader = self.get_dataloader(model,
                                               train_data,
                                               dsc_collate_fn,
                                               shuffle=True)
        dsc_val_loader = None if val_data is None else self.get_dataloader(
            model, val_data, dsc_collate_fn, shuffle=False)
        self._pretrain_discriminator(model, dsc_train_loader, dsc_val_loader,
                                     logger)

        # Policy gradient
        self.ref_smiles, self.ref_mols = None, None
        if model.metrics_reward is not None:
            (self.ref_smiles, self.ref_mols
             ) = model.metrics_reward.get_reference_data(train_data)

        pg_train_loader = dsc_train_loader
        self._train_policy_gradient(model, pg_train_loader, logger)

        del self.ref_smiles
        del self.ref_mols

        return model
Beispiel #3
0
    def _train(self, model, train_loader, val_loader=None):
        criterions = {
            'autoencoder': nn.CrossEntropyLoss(),
            'generator': lambda t: -torch.mean(F.logsigmoid(t)),
            'discriminator': nn.BCEWithLogitsLoss()
        }

        optimizers = {
            'autoencoder':
            torch.optim.Adam(list(model.encoder.parameters()) +
                             list(model.decoder.parameters()),
                             lr=self.config.lr),
            'generator':
            torch.optim.Adam(model.encoder.parameters(), lr=self.config.lr),
            'discriminator':
            torch.optim.Adam(model.discriminator.parameters(),
                             lr=self.config.lr)
        }
        schedulers = {
            k: torch.optim.lr_scheduler.StepLR(v, self.config.step_size,
                                               self.config.gamma)
            for k, v in optimizers.items()
        }
        device = torch.device(self.config.device)
        log = Logger()

        for epoch in range(self.config.train_epochs):
            tqdm_data = tqdm(train_loader,
                             desc='Training (epoch #{})'.format(epoch))
            for scheduler in schedulers.values():
                scheduler.step()
            log.append(
                self._train_epoch(model, tqdm_data, criterions, optimizers))
            log.write(self.config.log_file)
            if val_loader is not None:
                tqdm_data = tqdm(val_loader,
                                 desc='Validation (epoch #{})'.format(epoch))
                self._train_epoch(model, tqdm_data, criterions)

            if epoch % self.config.save_frequency == 0:
                model.to('cpu')
                torch.save(
                    model.state_dict(),
                    self.config.model_save[:-3] + '_{0:03d}.pt'.format(epoch))
                model.to(device)
Beispiel #4
0
    def fit(self, model, data):
        def get_params():
            return (p for p in model.parameters() if p.requires_grad)

        model.train()
        log = Logger()
        n_epoch = self.config.num_epochs

        optimizer = optim.Adam(get_params(), lr=self.config.lr)
        for epoch in range(n_epoch):
            if epoch < self.config.kl_start:
                kl_w = 0
            else:
                kl_w = self.config.kl_w

            word_acc, topo_acc, assm_acc, steo_acc, all_kl = 0, 0, 0, 0, 0
            with tqdm.tqdm(data) as train_dataloader:
                train_dataloader.set_description('Train (epoch #{})'.format(epoch))

                for it, batch in enumerate(train_dataloader):
                    model.zero_grad()
                    loss, kl_div, wacc, tacc, sacc, dacc = model(batch, kl_w)
                    loss.backward()
                    optimizer.step()

                    word_acc += wacc
                    topo_acc += tacc
                    assm_acc += sacc
                    steo_acc += dacc
                    all_kl += kl_div

                    postfix = {'kl': all_kl / (it + 1),
                               'word': word_acc / (it + 1) * 100,
                               'topo': topo_acc / (it + 1) * 100,
                               'assm': assm_acc / (it + 1) * 100,
                               'steo': steo_acc / (it + 1) * 100}

                    train_dataloader.set_postfix(postfix)
            log.append(postfix)
            log.save(self.config.log_file)
            if epoch % self.config.save_frequency == 0:
                model.to('cpu')
                torch.save(model.state_dict(), self.config.model_save[:-3]+'_{0:03d}.pt'.format(epoch))
                model.to(device)
Beispiel #5
0
    def fit(self, model, data):
        def get_params():
            return (p for p in model.parameters() if p.requires_grad)

        if isinstance(data, tuple):
            train_dataloader = data[0]
            val_dataloader = data[1]
        else:
            train_dataloader = data
            val_dataloader = None

        num_epochs = self.config.num_epochs
        device = torch.device(self.config.device)
        criterion = nn.CrossEntropyLoss()
        optimizer = optim.Adam(get_params(), lr=self.config.lr)
        scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                    self.config.step_size,
                                                    self.config.gamma)
        elog = Logger()
        for epoch in range(num_epochs):
            scheduler.step()
            model.train()
            train_dataloader = tqdm.tqdm(train_dataloader)
            train_dataloader.set_description('Train (epoch #{})'.format(epoch))

            loss = self._pass_data(model, train_dataloader, criterion,
                                   optimizer)
            elog.append({'loss': loss})
            if val_dataloader is not None:
                val_dataloader = tqdm.tqdm(val_dataloader)
                val_dataloader.set_description(
                    'Validation (epoch #{})'.format(epoch))

                self._pass_data(model, val_dataloader, criterion)

            if epoch % self.config.save_frequency == 0:
                model.to('cpu')
                torch.save(
                    model.state_dict(),
                    self.config.model_save[:-3] + '_{0:03d}.pt'.format(epoch))
                model.to(device)
            elog.save(self.config.log_file)
        torch.save(model.state_dict(), self.config.model_save)
Beispiel #6
0
############ load training data

print("Loading training set...")
train_split = DatasetSplit("train", config.train_load)
train_dataloader = train_split.get_dataloader(batch_size=config.train_bsz)

if config.valid_load is not None:
    print("Loading validation set...")
    valid_split = DatasetSplit("valid", config.valid_load)
    valid_dataloader = valid_split.get_dataloader(batch_size=config.train_bsz,
                                                  shuffle=False)

vocab = train_split._vocab

############ get model and train

print("Initializing model...")
model = LVAE(vocab, config)

## (optional) load trained model
if config.model_load is not None:
    model.load_state_dict(torch.load(config.train_from))

model.to(device)

## log training process to csv file
logger = Logger() if config.log_path is not None else None

print("Start training...")
train(model, config, train_dataloader, valid_dataloader, logger)
Beispiel #7
0
    def fit(self, model, content_train, style_instance, content_test=None):
        self.encoder_c = model.encoder_c
        self.encoder_s1 = model.encoder_s1
        self.encoder_s2 = model.encoder_s2
        self.decoder = model.decoder
        self.discriminator = model.Discriminator
        self.heteroencoder = model.heteroencoder
        cuda = True if torch.cuda.is_available() else False
        if cuda:
            print('Using CUDA')
            self.discriminator.cuda()
            self.encoder_c.cuda()
            self.encoder_s1.cuda()
            self.encoder_s2.cuda()
            self.decoder.cuda()
            self.heteroencoder.cuda()
        else:
            print('Using CPU')

        logger = Logger() if self.config.log_file is not None else None

        _, smi2vec = load_model()
        print("Training GAN.")

        def get_latent(smiles):
            vec = smi2vec(smiles)
            latent = self.heteroencoder.encode(vec)
            latent = latent.reshape(latent.shape[0], self.latent_size)
            return latent

        os.makedirs('./latent_save', exist_ok=True)
        if not os.path.exists(
                f'./latent_save/latent_content_train_{self.config.target}.pkl'
        ):
            latent_content_train = get_latent(content_train)
            latent_style_instance = get_latent(style_instance)

            pickle.dump(
                latent_content_train,
                open(
                    f'./latent_save/latent_content_train_{self.config.target}.pkl',
                    'wb'))
            pickle.dump(
                latent_style_instance,
                open(
                    f'./latent_save/latent_style_instance_{self.config.target}.pkl',
                    'wb'))
            if content_test is not None:
                latent_content_test = get_latent(content_test)
                pickle.dump(
                    latent_content_test,
                    open(
                        f'./latent_save/latent_content_test_{self.config.target}.pkl',
                        'wb'))
        else:
            latent_content_train = pickle.load(
                open(
                    f'./latent_save/latent_content_train_{self.config.target}.pkl',
                    'rb'))
            latent_style_instance = pickle.load(
                open(
                    f'./latent_save/latent_style_instance_{self.config.target}.pkl',
                    'rb'))
            if content_test is not None:
                latent_content_test = pickle.load(
                    open(
                        f'./latent_save/latent_content_test_{self.config.target}.pkl',
                        'rb'))

        train_loader = self.get_dataloader(model,
                                           LatentMolsDataset(
                                               latent_content_train,
                                               latent_style_instance,
                                               is_train=True),
                                           shuffle=True)
        val_loader = None if content_test is None else self.get_dataloader(
            model,
            LatentMolsDataset(latent_content_test, latent_style_instance),
            shuffle=False)

        self._train(model, train_loader, val_loader, logger)
        return model
Beispiel #8
0
    def fit(self,
            model,
            train_data,
            val_data=None):
        from ddc_pub import ddc_v3 as ddc
        self.generator = model.Generator
        self.discriminator = model.Discriminator
        cuda = True if torch.cuda.is_available() else False
        if cuda:
            self.discriminator.cuda()
            self.generator.cuda()

        logger = Logger() if self.config.log_file is not None else None

        if self.config.heteroencoder_version == 'new':
            # Train the heteroencoder first
            print("Training heteroencoder.")
            currentDirectory = os.getcwd()
            path = '{}/moses/latentgan/heteroencoder_models/new_model' \
                .format(currentDirectory)
            encoder_checkpoint_path = \
                '{}/moses/latentgan/heteroencoder_models/checkpoints/' \
                .format(currentDirectory)
            # Convert all SMILES to binary RDKit mols to be
            #  compatible with the heteroencoder
            heteroencoder_mols = [Chem.rdchem.Mol
                                      .ToBinary(Chem.MolFromSmiles(smiles))
                                  for smiles in train_data]
            # Dataset information
            dataset_info = self._get_dataset_info(
                train_data, name="heteroencoder_train_data")
            # Initialize heteroencoder with default parameters
            heteroencoder_model = ddc.DDC(x=np.array(heteroencoder_mols),
                                          y=np.array(heteroencoder_mols),
                                          dataset_info=dataset_info,
                                          scaling=False,
                                          noise_std=self.config.
                                          heteroencoder_noise_std,
                                          lstm_dim=self.config.
                                          heteroencoder_layer_dim,
                                          dec_layers=self.config.
                                          heteroencoder_dec_layers,
                                          td_dense_dim=0,
                                          batch_size=self.config.
                                          heteroencoder_batch_size,
                                          codelayer_dim=self.latent_size)
            # Train heteroencoder
            heteroencoder_model.fit(epochs=self.config.heteroencoder_epochs,
                                    lr=self.config.heteroencoder_lr,
                                    model_name="new_model",
                                    mini_epochs=self.config.
                                    heteroencoder_mini_epochs,
                                    patience=self.config.
                                    heteroencoder_patience,
                                    save_period=self.config.
                                    heteroencoder_save_period,
                                    checkpoint_dir=encoder_checkpoint_path,
                                    gpus=1,
                                    use_multiprocessing=False,
                                    workers=1,
                                    lr_decay=self.config.
                                    heteroencoder_lr_decay,
                                    sch_epoch_to_start=self.config.
                                    heteroencoder_lr_decay_start)

            heteroencoder_model.save(path)

        heteroencoder = load_model(
            model_version=self.config.heteroencoder_version)
        print("Training GAN.")
        mols_in = [Chem.rdchem.Mol.ToBinary(
            Chem.MolFromSmiles(smiles)) for smiles in train_data]
        latent_train = heteroencoder.transform(
            heteroencoder.vectorize(mols_in))
        # Now encode the GAN training set to latent vectors

        latent_train = latent_train.reshape(latent_train.shape[0],
                                            self.latent_size)

        if val_data is not None:
            mols_val = [Chem.rdchem.Mol.ToBinary(Chem.MolFromSmiles(smiles))
                        for smiles in val_data]
            latent_val = heteroencoder.transform(
                heteroencoder.vectorize(mols_val))
            latent_val = latent_val.reshape(latent_val.shape[0],
                                            self.latent_size)

        train_loader = self.get_dataloader(model,
                                           LatentMolsDataset(latent_train),
                                           shuffle=True)
        val_loader = None if val_data is None else self.get_dataloader(
            model, LatentMolsDataset(latent_val), shuffle=False
        )

        self._train(model, train_loader, val_loader, logger)
        return model
Beispiel #9
0
    def fit(self, model, data):
        def get_params():
            return (p for p in model.vae.parameters() if p.requires_grad)

        model.train()

        n_epoch = self._n_epoch()
        kl_annealer = KLAnnealer(n_epoch, self.config)

        optimizer = optim.Adam(get_params(), lr=self.config.lr_start)
        lr_annealer = CosineAnnealingLRWithRestart(optimizer, self.config)

        device = torch.device(self.config.device)
        n_last = self.config.n_last
        elog, ilog = Logger(), Logger()

        for epoch in range(n_epoch):
            # Epoch start
            kl_weight = kl_annealer(epoch)

            # Iters
            T = tqdm.tqdm(data)
            for i, x in enumerate(T):
                # Forward
                kl_loss, recon_loss = model(x)
                loss = kl_weight * kl_loss + recon_loss

                # Backward
                optimizer.zero_grad()
                loss.backward()
                clip_grad_norm_(get_params(), self.config.grad_clipping)
                optimizer.step()

                # Log
                lr = optimizer.param_groups[0]['lr']
                ilog.append({
                    'epoch': epoch,
                    'kl_loss': kl_loss.item(),
                    'recon_loss': recon_loss.item(),
                    'loss': loss.item(),
                    'kl_weight': kl_weight,
                    'lr': lr
                })

                # Update T
                kl_loss_value = np.mean(ilog['kl_loss'][-n_last:])
                recon_loss_value = np.mean(ilog['recon_loss'][-n_last:])
                loss_value = np.mean(ilog['loss'][-n_last:])
                postfix = [
                    f'loss={loss_value:.5f}', f'(kl={kl_loss_value:.5f}',
                    f'recon={recon_loss_value:.5f})',
                    f'klw={kl_weight:.5f} lr={lr:.5f}'
                ]
                T.set_postfix_str(' '.join(postfix))
                T.set_description(f'Train (epoch #{epoch})')
                T.refresh()

            # Log
            elog.append({
                **{k: v
                   for k, v in ilog[-1].items() if 'loss' not in k}, 'kl_loss':
                kl_loss_value,
                'recon_loss': recon_loss_value,
                'loss': loss_value
            })

            # Save model at each epoch
            if epoch % self.config.save_frequency == 0:
                model.to('cpu')
                torch.save(
                    model.state_dict(),
                    self.config.model_save[:-3] + '_{0:03d}.pt'.format(epoch))
                model.to(device)

            elog.save(self.config.log_file)

            # Epoch end
            lr_annealer.step()

        torch.save(model.state_dict(), self.config.model_save)
        return elog, ilog
Beispiel #10
0
 def fit(self, model, train_data, fps_data, val_data=None):
     log = Logger()
     self._pretrain_generator(model, train_data, fps_data, log, val_data)
     self._pretrain_discriminator(model, train_data, fps_data, log,
                                  val_data)
     self._train_policy_gradient(model, train_data, fps_data, log)