def train(self):
        enqueue_op = self.input_queue.enqueue(self.input_vars)

        if self.config.nr_tower > 1:
            grad_list = self._multi_tower_grads()
            if not self.async:
                grads = QueueInputTrainer._average_grads(grad_list)
                grads = self.process_grads(grads)
            else:
                grad_list = [self.process_grads(g) for g in grad_list]
                # pretend to average the grads, in order to make async and
                # sync have consistent effective learning rate
                def scale(grads):
                    return [(grad / self.config.nr_tower, var) for grad, var in grads]
                grad_list = map(scale, grad_list)
                grads = grad_list[0]  # use grad from the first tower for routinely stuff
        else:
            grads = self._single_tower_grad()
            grads = self.process_grads(grads)

        self.train_op = tf.group(
            self.config.optimizer.apply_gradients(grads, get_global_step_var()),
            summary_moving_average())

        if self.async:
            self.threads = []
            for k in range(1, self.config.nr_tower):
                train_op = self.config.optimizer.apply_gradients(grad_list[k])
                f = lambda op=train_op: self.sess.run([op]) # avoid late-binding
                th = LoopThread(f)
                th.pause()
                th.start()
                self.threads.append(th)
            self.async_running = False

        self.init_session_and_coord()
        # create a thread that keeps filling the queue
        self.input_th = EnqueueThread(self, self.input_queue, enqueue_op, self.input_vars)
        self.main_loop()
dataset/ETHPy150Open ppwwyyxx/tensorpack/tensorpack/train/trainer.py/QueueInputTrainer.train/original