예제 #1
0
    def __init__(self,
                 config,
                 vae_decoder,
                 mem_model,
                 dataset,
                 dir_name='plots'):
        self.config = config
        self.decoder = vae_decoder
        self.model = mem_model
        self.sequence_len = self.config.rnn['sequence_len']
        self.latent_dim = self.config.vae['latent_space_dim']

        # Check if destination dir exists
        self.plots_dir = os.path.join(self.config.rnn['logs_dir'], dir_name)
        create_directory(self.plots_dir)

        # Prepare data
        (states, actions), _ = dataset[0]
        self.n_episodes = min(self.config.rnn['rend_n_episodes'], len(dataset))
        self.eval_states = torch.zeros(
            (self.n_episodes, self.sequence_len, states.shape[1]),
            device=next(self.model.parameters()).device,
            dtype=states.dtype)
        self.eval_actions = torch.zeros(
            (self.n_episodes, self.sequence_len, actions.shape[1]),
            device=next(self.model.parameters()).device,
            dtype=actions.dtype)
        for i in range(self.n_episodes):
            (states, actions), _ = dataset[i]
            self.eval_states[i] = states
            self.eval_actions[i] = actions
예제 #2
0
def train_mem(ctx, path, vae_path):
    """Train MDN-RNN model as specified in .json config with data at `PATH`."""

    from third_party.torchtrainer import EarlyStopping, LambdaCallback, ModelCheckpoint, CSVLogger, RandomBatchSampler, evaluate
    from torch.utils.data import DataLoader
    config = obtain_config(ctx)

    env = hrl.create_gym(config.general['game_name'])

    # Create checkpoint directory, if it doesn't exist
    create_directory(os.path.dirname(config.rnn['ckpt_path']))

    # Create training DataLoader
    dataset = MDNDataset(path, config.rnn['sequence_len'],
                         config.rnn['terminal_prob'],
                         config.rnn['dataset_fraction'])
    data_loader = DataLoader(dataset,
                             batch_sampler=RandomBatchSampler(
                                 dataset, config.rnn['batch_size']),
                             pin_memory=True)

    # Build model
    rnn = build_rnn_model(config.rnn, config.vae['latent_space_dim'],
                          env.action_space)

    # Create callbacks
    callbacks = [
        EarlyStopping(metric='loss',
                      patience=config.rnn['patience'],
                      verbose=1),
        LambdaCallback(on_batch_begin=lambda _, batch_size: rnn.model.
                       init_hidden(batch_size)),
        ModelCheckpoint(config.rnn['ckpt_path'], metric='loss',
                        save_best=True),
        CSVLogger(
            filename=os.path.join(config.rnn['logs_dir'], 'train_mem.csv'))
    ]

    # Evaluate and visualize memory progress if render allowed
    if config.allow_render:
        if vae_path is None:
            raise ValueError("To render provide valid path to VAE checkpoint!")

        # Build VAE model and load checkpoint
        _, _, decoder = build_vae_model(config.vae,
                                        config.general['state_shape'],
                                        vae_path)

        callbacks += [
            MemoryVisualization(config, decoder, rnn.model, dataset,
                                'mdn_plots')
        ]

    # Fit MDN-RNN model!
    rnn.fit_loader(data_loader,
                   epochs=config.rnn['epochs'],
                   callbacks=callbacks)

    dataset.close()
예제 #3
0
    def save_es_ckpt_and_mind_weights(self, ckpt_path, mind_path, score):
        # Create CMA-ES checkpoint dir if doesn't exist
        create_directory(os.path.dirname(ckpt_path))

        # Create Mind weights checkpoint dir if doesn't exist
        mind_dir = os.path.dirname(mind_path)
        create_directory(mind_dir)

        # Create paths for best and mean Mind weights checkpoints
        mind_name = os.path.basename(mind_path).split('.')[0]
        best_path = os.path.join(mind_dir, mind_name + "_best.ckpt")
        mean_path = os.path.join(mind_dir, mind_name + "_mean.ckpt")

        with open(os.path.abspath(ckpt_path), 'wb') as f:
            pickle.dump(self, f)
        log.debug("Saved CMA-ES checkpoint in path: %s", ckpt_path)

        if self.check_if_better(score):
            log.info("New best score: %f", score)
            with open(os.path.abspath(best_path), 'wb') as f:
                pickle.dump(self.best_param(), f)
            with open(os.path.abspath(mean_path), 'wb') as f:
                pickle.dump(self.current_param(), f)
            log.debug("Saved Mind weights in path: %s", mind_path)
예제 #4
0
def save_results(names, pred, y_true, path):
    common_utils.create_directory(os.path.dirname(path))
    with open(path, 'w') as f:
        f.write("stay,prediction,y_true\n")
        for (name, x, y) in zip(names, pred, y_true):
            f.write("{},{:.6f},{}\n".format(name, x, y))
예제 #5
0
def train_vae(ctx, path):
    """Train VAE model as specified in .json config with data at `PATH`."""

    from keras.callbacks import EarlyStopping, LambdaCallback, ModelCheckpoint, CSVLogger
    config = obtain_config(ctx)

    # Get dataset length and eight examples to evaluate VAE on
    with h5.File(path, 'r') as hfile:
        n_transitions = hfile.attrs['N_TRANSITIONS']
        X_eval = hfile['states'][:8] / 255.

    # Get training data
    train_gen = HDF5DataGenerator(path,
                                  'states',
                                  'states',
                                  batch_size=config.vae['batch_size'],
                                  end=int(n_transitions * 0.8),
                                  preprocess_fn=lambda X, y:
                                  (X / 255., y / 255.))
    val_gen = HDF5DataGenerator(path,
                                'states',
                                'states',
                                batch_size=config.vae['batch_size'],
                                start=int(n_transitions * 0.8),
                                preprocess_fn=lambda X, y:
                                (X / 255., y / 255.))

    # Build VAE model
    vae, _, _ = build_vae_model(config.vae, config.general['state_shape'])

    # If render features enabled...
    if config.allow_render:
        # ...plot first eight training examples with VAE reconstructions
        # at the beginning of every epoch
        import matplotlib
        matplotlib.use("Agg")
        import matplotlib.gridspec as gridspec
        import matplotlib.pyplot as plt

        # Check if destination dir exists
        plots_dir = os.path.join(config.vae['logs_dir'], "plots_vae")
        if not os.path.exists(plots_dir):
            os.makedirs(plots_dir)

        # Evaluate VAE at the end of epoch
        def plot_samples(epoch, logs):
            pred = vae.predict(X_eval)

            samples = np.empty_like(np.concatenate((X_eval, pred)))
            samples[0::2] = X_eval
            samples[1::2] = pred

            _ = plt.figure(figsize=(4, 4))
            gs = gridspec.GridSpec(4, 4)
            gs.update(wspace=0.05, hspace=0.05)

            for i, sample in enumerate(samples):
                ax = plt.subplot(gs[i])
                plt.axis('off')
                ax.set_xticklabels([])
                ax.set_yticklabels([])
                ax.set_aspect('equal')
                plt.imshow(sample.reshape(*config.general['state_shape']))

            # Save figure to logs dir
            plt.savefig(
                os.path.join(
                    plots_dir, "interpreter_sample_{}".format(
                        dt.datetime.now().strftime("%d-%mT%H:%M"))))
            plt.close()
    else:

        def plot_samples(epoch, logs):
            pass

    # Create checkpoint and logging directory, if it doesn't exist
    create_directory(os.path.dirname(config.vae['ckpt_path']))
    create_directory(os.path.dirname(config.vae['logs_dir']))

    # Initialize callbacks
    callbacks = [
        EarlyStopping(patience=config.vae['patience']),
        LambdaCallback(on_epoch_begin=plot_samples),
        ModelCheckpoint(config.vae['ckpt_path'],
                        verbose=1,
                        save_best_only=True,
                        save_weights_only=True),
        CSVLogger(filename=os.path.join(config.vae['logs_dir'],
                                        'train_vae.csv'),
                  append=True)
    ]

    # Fit VAE model!
    vae.fit_generator(
        generator=train_gen,
        validation_data=val_gen,
        epochs=config.vae['epochs'],
        use_multiprocessing=False,
        # NOTE:  There is no need for more then one workers, we are disk IO bound (I suppose ...)
        # NOTE2: h5py from conda should be threadsafe... but it apparently isn't and raises
        #        `OSError: Can't read data (wrong B-tree signature)` sporadically if `workers` = 1
        #        and always if `workers` > 1. That's why this generator needs to run in main thread
        #        (`workers` = 0).
        workers=3,
        max_queue_size=100,
        shuffle=True,  # It shuffles whole batches, not items in batches
        callbacks=callbacks)