code: def _build_gan_trainer(self, input, model):
          
          # Build the graph
          self.tower_func = TowerFuncWrapper(model.build_graph, model.get_input_signature())
          with TowerContext('', is_training=True):
              self.tower_func(*input.get_input_tensors())
          opt = model.get_optimizer()
  
          # Define the training iteration
          # by default, run one d_min after one g_min
          with tf.name_scope('optimize'):
              g_min = opt.minimize(model.g_loss, var_list=model.g_vars, name='g_op')
              with tf.control_dependencies([g_min]):
                  d_min = opt.minimize(model.d_loss, var_list=model.d_vars, name='d_op')
          self.train_op = d_min
docs: We need to set tower_func because it's a TowerTrainer,
          and only TowerTrainer supports automatic graph creation for inference during training.
  
          If we don't care about inference during training, using tower_func is
          not needed. Just calling model.build_graph directly is OK.