Run a single training epoch

def train_epoch(self, epoch_info, source: 'vel.api.Source', interactive=True):
        """ Run a single training epoch """
        self.train()

        if interactive:
            iterator = tqdm.tqdm(source.train_loader(), desc="Training", unit="iter", file=sys.stdout)
        else:
            iterator = source.train_loader()

        for batch_idx, (data, target) in enumerate(iterator):
            batch_info = BatchInfo(epoch_info, batch_idx)

            batch_info.on_batch_begin()
            self.train_batch(batch_info, data, target)
            batch_info.on_batch_end()

            iterator.set_postfix(loss=epoch_info.result_accumulator.intermediate_value('loss'))