Run reinforcement learning algorithm

def run(self):
        """ Run reinforcement learning algorithm """
        device = self.model_config.torch_device()

        # Reinforcer is the learner for the reinforcement learning model
        reinforcer = self.reinforcer.instantiate(device)
        optimizer = self.optimizer_factory.instantiate(reinforcer.model)

        # All callbacks used for learning
        callbacks = self.gather_callbacks(optimizer)
        # Metrics to track through this training
        metrics = reinforcer.metrics()

        training_info = self.resume_training(reinforcer, callbacks, metrics)

        reinforcer.initialize_training(training_info)
        training_info.on_train_begin()

        if training_info.optimizer_initial_state:
            optimizer.load_state_dict(training_info.optimizer_initial_state)

        global_epoch_idx = training_info.start_epoch_idx + 1

        while training_info['frames'] < self.total_frames:
            epoch_info = EpochInfo(
                training_info,
                global_epoch_idx=global_epoch_idx,
                batches_per_epoch=self.batches_per_epoch,
                optimizer=optimizer,
            )

            reinforcer.train_epoch(epoch_info)

            if self.openai_logging:
                self._openai_logging(epoch_info.result)

            self.storage.checkpoint(epoch_info, reinforcer.model)

            global_epoch_idx += 1

        training_info.on_train_end()

        return training_info