<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run_training(self, trace: Optional[TrainingTrace]=None) -> None: """ Run the main loop in the training mode. Calls - :py:meth:`cxflow.hooks.AbstractHook.after_epoch` - :py:meth:`cxflow.hooks.AbstractHook.after_epoch_profile` """

        for stream_name in [self._train_stream_name] + self._extra_streams:
            self.get_stream(stream_name)

        def training():
            logging.debug('Training started')
            self._epochs_done = 0

            # Zeroth epoch: after_epoch
            if not self._skip_zeroth_epoch:
                logging.info('Evaluating 0th epoch')
                self._run_zeroth_epoch([self._train_stream_name] + self._extra_streams)
                logging.info('0th epoch done\n\n')

            # Training loop: after_epoch, after_epoch_profile
            while True:
                epoch_id = self._epochs_done + 1
                logging.info('Training epoch %s', epoch_id)
                self._epoch_profile.clear()
                epoch_data = self._create_epoch_data()

                with self.get_stream(self._train_stream_name) as stream:
                    self.train_by_stream(stream)

                for stream_name in self._extra_streams:
                    with self.get_stream(stream_name) as stream:
                        self.evaluate_stream(stream)

                with Timer('after_epoch_hooks', self._epoch_profile):
                    for hook in self._hooks:
                        hook.after_epoch(epoch_id=epoch_id, epoch_data=epoch_data)

                for hook in self._hooks:
                    hook.after_epoch_profile(epoch_id=epoch_id, profile=self._epoch_profile,
                                             train_stream_name=self._train_stream_name,
                                             extra_streams=self._extra_streams)
                self._epochs_done = epoch_id
                if trace is not None:
                    trace[TrainingTraceKeys.EPOCHS_DONE] = self._epochs_done
                logging.info('Epoch %s done\n\n', epoch_id)

        self._try_run(training)