//  [python]
def train(self):
        """

        :return:
        """
        self._sess.run(tf.global_variables_initializer())
        self._sess.run(tf.local_variables_initializer())
        if self._cfg.TRAIN.RESTORE_FROM_SNAPSHOT.ENABLE:
            try:
                LOG.info('=> Restoring weights from: {:s} ... '.format(self._initial_weight))
                self._loader.restore(self._sess, self._initial_weight)
                global_step_value = self._sess.run(self._global_step)
                remain_epoch_nums = self._train_epoch_nums - math.floor(global_step_value / self._steps_per_epoch)
                epoch_start_pt = self._train_epoch_nums - remain_epoch_nums
            except OSError as e:
                LOG.error(e)
                LOG.info('=> {:s} does not exist !!!'.format(self._initial_weight))
                LOG.info('=> Now it starts to train LaneNet from scratch ...')
                epoch_start_pt = 1
            except Exception as e:
                LOG.error(e)
                LOG.info('=> Can not load pretrained model weights: {:s}'.format(self._initial_weight))
                LOG.info('=> Now it starts to train LaneNet from scratch ...')
                epoch_start_pt = 1
        else:
            LOG.info('=> Starts to train LaneNet from scratch ...')
            epoch_start_pt = 1

        best_model = []
        for epoch in range(epoch_start_pt, self._train_epoch_nums):
            # training part
            train_epoch_losses = []
            train_epoch_mious = []
            traindataset_pbar = tqdm.tqdm(range(1, self._steps_per_epoch))
            for _ in traindataset_pbar:
                if self._enable_miou and epoch % self._record_miou_epoch == 0:
                    _, _, summary, train_step_loss, train_step_binary_loss, \
                        train_step_instance_loss, global_step_val = self._sess.run(
                            fetches=[
                                self._train_op, self._miou_update_op, self._write_summary_op_with_miou,
                                self._loss, self._binary_loss, self._instance_loss,
                                self._global_step
                            ]
                    )
                    train_step_miou = self._sess.run(
                        fetches=self._miou
                    )
                    train_epoch_losses.append(train_step_loss)
                    train_epoch_mious.append(train_step_miou)
                    self._summary_writer.add_summary(summary, global_step=global_step_val)
                    traindataset_pbar.set_description(
                        'train loss: {:.5f}, b_loss: {:.5f}, i_loss: {:.5f}, miou: {:.5f}'.format(
                            train_step_loss, train_step_binary_loss, train_step_instance_loss, train_step_miou
                        )
                    )
                else:
                    _, summary, train_step_loss, train_step_binary_loss, \
                        train_step_instance_loss, global_step_val = self._sess.run(
                            fetches=[
                                self._train_op, self._write_summary_op,
                                self._loss, self._binary_loss, self._instance_loss,
                                self._global_step
                            ]
                    )
                    train_epoch_losses.append(train_step_loss)
                    self._summary_writer.add_summary(summary, global_step=global_step_val)
                    traindataset_pbar.set_description(
                        'train loss: {:.5f}, b_loss: {:.5f}, i_loss: {:.5f}'.format(
                            train_step_loss, train_step_binary_loss, train_step_instance_loss
                        )
                    )

            train_epoch_losses = np.mean(train_epoch_losses)
            if self._enable_miou and epoch % self._record_miou_epoch == 0:
                train_epoch_mious = np.mean(train_epoch_mious)

            # validation part
            val_epoch_losses = []
            val_epoch_mious = []
            valdataset_pbar = tqdm.tqdm(range(1, self._val_steps_per_epoch))
            for _ in valdataset_pbar:
                try:
                    if self._enable_miou and epoch % self._record_miou_epoch == 0:
                        _, val_summary, val_step_loss, val_step_binary_loss, \
                            val_step_instance_loss, val_global_step_val = self._sess.run(
                                    fetches=[
                                        self._val_miou_update_op, self._val_write_summary_op_with_miou,
                                        self._val_loss, self._val_binary_loss, self._val_instance_loss,
                                        self._val_global_step
                                    ]
                            )
                        val_step_miou = self._sess.run(
                            fetches=self._val_miou
                        )
                        val_epoch_losses.append(val_step_loss)
                        val_epoch_mious.append(val_step_miou)
                        self._summary_writer.add_summary(val_summary, global_step=val_global_step_val)
                        valdataset_pbar.set_description(
                            'val loss: {:.5f}, b_loss: {:.5f}, i_loss: {:.5f}, val miou: {:.5f}'.format(
                                val_step_loss, val_step_binary_loss, val_step_instance_loss, val_step_miou)
                        )
                    else:
                        val_summary, val_step_loss, val_step_binary_loss, \
                            val_step_instance_loss, val_global_step_val = self._sess.run(
                                fetches=[
                                    self._val_write_summary_op,
                                    self._val_loss, self._val_binary_loss, self._val_instance_loss,
                                    self._val_global_step
                                ]
                            )
                        val_epoch_losses.append(val_step_loss)
                        self._summary_writer.add_summary(val_summary, global_step=val_global_step_val)
                        valdataset_pbar.set_description(
                            'val loss: {:.5f} b_loss: {:.5f}, i_loss: {:.5f}'.format(
                                val_step_loss, val_step_binary_loss, val_step_instance_loss
                            )
                        )
                except tf.errors.OutOfRangeError as _:
                    break
            val_epoch_losses = np.mean(val_epoch_losses)
            if self._enable_miou and epoch % self._record_miou_epoch == 0:
                val_epoch_mious = np.mean(val_epoch_mious)

            # model saving part
            if epoch % self._snapshot_epoch == 0:
                if self._enable_miou:
                    if len(best_model) < 10:
                        best_model.append(val_epoch_mious)
                        best_model = sorted(best_model)
                        snapshot_model_name = 'tusimple_val_miou={:.4f}.ckpt'.format(val_epoch_mious)
                        snapshot_model_path = ops.join(self._model_save_dir, snapshot_model_name)
                        os.makedirs(self._model_save_dir, exist_ok=True)
                        self._saver.save(self._sess, snapshot_model_path, global_step=epoch)
                    else:
                        best_model = sorted(best_model)
                        if val_epoch_mious > best_model[0]:
                            best_model[0] = val_epoch_mious
                            best_model = sorted(best_model)
                            snapshot_model_name = 'tusimple_val_miou={:.4f}.ckpt'.format(val_epoch_mious)
                            snapshot_model_path = ops.join(self._model_save_dir, snapshot_model_name)
                            os.makedirs(self._model_save_dir, exist_ok=True)
                            self._saver.save(self._sess, snapshot_model_path, global_step=epoch)
                        else:
                            pass
                else:
                    snapshot_model_name = 'tusimple_val_loss={:.4f}.ckpt'.format(val_epoch_losses)
                    snapshot_model_path = ops.join(self._model_save_dir, snapshot_model_name)
                    os.makedirs(self._model_save_dir, exist_ok=True)
                    self._saver.save(self._sess, snapshot_model_path, global_step=epoch)

            log_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
            if self._enable_miou and epoch % self._record_miou_epoch == 0:
                LOG.info(
                    '=> Epoch: {:d} Time: {:s} Train loss: {:.5f} Train miou: {:.5f} '
                    'Val loss: {:.5f} Val miou: {:.5f}...'.format(
                        epoch, log_time,
                        train_epoch_losses,
                        train_epoch_mious,
                        val_epoch_losses,
                        val_epoch_mious
                    )
                )
            else:
                LOG.info(
                    '=> Epoch: {:d} Time: {:s} Train loss: {:.5f} Val loss: {:.5f}...'.format(
                        epoch, log_time,
                        train_epoch_losses,
                        val_epoch_losses
                    )
                )
        if self._enable_miou:
            LOG.info('Best model\'s val mious are: {}'.format(best_model))
        LOG.info('Complete training process good luck!!')

        return