def learn(self, batch):
        '''
        Performs a gradient descent step on 'batch'

        Arguments:
            batch: a minibatch sampled from the replay memory, after preprocessing steps such as transfer to pytorch
            tensors and aggregation step
        '''
        self.current_iteration += 1
        with self.total_learn_time.time():
            tensorplex_update_dict = self._optimize(
                batch.obs,
                batch.actions,
                batch.rewards,
                batch.obs_next,
                batch.dones
            )
            tensorplex_update_dict['performance/total_learn_time'] = self.total_learn_time.avg
            self.tensorplex.add_scalars(tensorplex_update_dict, global_step=self.current_iteration)
            self.periodic_checkpoint(
                global_steps=self.current_iteration,
                score=None,
            )

        Performs a gradient descent step on 'batch'

        Arguments:
            batch: a minibatch sampled from the replay memory, after preprocessing steps such as transfer to pytorch
            tensors and aggregation step
        
surreal/learner/ddpg.py