def train(logger, hyperparams, enable_eval=True, enable_debug=False):
    config_proto = get_config_proto(hyperparams.device_log_device_placement, hyperparams.device_allow_soft_placement, hyperparams.device_allow_growth, hyperparams.device_per_process_gpu_memory_fraction)
    summary_output_dir = hyperparams.train_summary_output_dir
    if (not tf.gfile.Exists(summary_output_dir)):
        tf.gfile.MakeDirs(summary_output_dir)
    logger.log_print('##### create train model #####')
    train_model = create_train_model(logger, hyperparams)
    train_sess = tf.Session(config=config_proto, graph=train_model.graph)
    if (enable_debug == True):
        train_sess = tf_debug.LocalCLIDebugWrapperSession(train_sess)
    train_summary_writer = SummaryWriter(train_model.graph, os.path.join(summary_output_dir, 'train'))
    init_model(train_sess, train_model)
    train_logger = TrainLogger(hyperparams.data_log_output_dir)
    if (enable_eval == True):
        logger.log_print('##### create infer model #####')
        infer_model = create_infer_model(logger, hyperparams)
        infer_sess = tf.Session(config=config_proto, graph=infer_model.graph)
        if (enable_debug == True):
            infer_sess = tf_debug.LocalCLIDebugWrapperSession(infer_sess)
        infer_summary_writer = SummaryWriter(infer_model.graph, os.path.join(summary_output_dir, 'infer'))
        init_model(infer_sess, infer_model)
        eval_logger = EvalLogger(hyperparams.data_log_output_dir)
    logger.log_print('##### start training #####')
    global_step = 0
    for epoch in range(hyperparams.train_num_epoch):
        (feed_dict, data_dict) = generate_feed_dict(train_model, len(train_model.input_answer), hyperparams.train_batch_size)
        train_sess.run(train_model.data_pipeline.initializer, feed_dict=feed_dict)
        step_in_epoch = 0
        while True:
            try:
                start_time = time.time()
                train_result = train_model.model.train(train_sess, train_model.word_embedding)
                end_time = time.time()
                global_step = train_result.global_step
                step_in_epoch += 1
                train_logger.update(train_result, epoch, step_in_epoch, (end_time - start_time))
                if ((step_in_epoch % hyperparams.train_step_per_stat) == 0):
                    train_logger.check()
                    train_summary_writer.add_summary(train_result.summary, global_step)
                if ((step_in_epoch % hyperparams.train_step_per_ckpt) == 0):
                    train_model.model.save(train_sess, global_step, 'debug')
                if (((step_in_epoch % hyperparams.train_step_per_eval) == 0) and (enable_eval == True)):
                    ckpt_file = infer_model.model.get_latest_ckpt('debug')
                    sample_result = sample_predict(infer_sess, infer_model, hyperparams.train_eval_batch_size, ckpt_file, 'debug')
                    extrinsic_eval(eval_logger, infer_summary_writer, sample_result, hyperparams.train_eval_metric, hyperparams.train_eval_detail_type, global_step, epoch)
                    decoding_eval(eval_logger, sample_result, hyperparams.train_decoding_sample_size, (hyperparams.train_random_seed + global_step), global_step, epoch)
            except tf.errors.OutOfRangeError:
                train_logger.check()
                train_summary_writer.add_summary(train_result.summary, global_step)
                train_model.model.save(train_sess, global_step, 'epoch')
                if (enable_eval == True):
                    ckpt_file = infer_model.model.get_latest_ckpt('epoch')
                    sample_result = sample_predict(infer_sess, infer_model, hyperparams.train_eval_batch_size, ckpt_file, 'epoch')
                    extrinsic_eval(eval_logger, infer_summary_writer, sample_result, hyperparams.train_eval_metric, hyperparams.train_eval_detail_type, global_step, epoch)
                    decoding_eval(eval_logger, sample_result, hyperparams.train_decoding_sample_size, (hyperparams.train_random_seed + global_step), global_step, epoch)
                break
    train_summary_writer.close_writer()
    if (enable_eval == True):
        infer_summary_writer.close_writer()
    logger.log_print('##### finish training #####')
def train(logger, hyperparams, enable_eval=True, enable_debug=False):
    config_proto = get_config_proto(hyperparams.device_log_device_placement, hyperparams.device_allow_soft_placement, hyperparams.device_allow_growth, hyperparams.device_per_process_gpu_memory_fraction)
    summary_output_dir = hyperparams.train_summary_output_dir
    if (not tf.gfile.Exists(summary_output_dir)):
        tf.gfile.MakeDirs(summary_output_dir)
    logger.log_print('##### create train model #####')
    train_model = create_train_model(logger, hyperparams)
    train_sess = tf.Session(config=config_proto, graph=train_model.graph)
    if (enable_debug == True):
        train_sess = tf_debug.LocalCLIDebugWrapperSession(train_sess)
    train_summary_writer = SummaryWriter(train_model.graph, os.path.join(summary_output_dir, 'train'))
    init_model(train_sess, train_model)
    train_logger = TrainLogger(hyperparams.data_log_output_dir)
    if (enable_eval == True):
        logger.log_print('##### create infer model #####')
        infer_model = create_infer_model(logger, hyperparams)
        infer_sess = tf.Session(config=config_proto, graph=infer_model.graph)
        if (enable_debug == True):
            infer_sess = tf_debug.LocalCLIDebugWrapperSession(infer_sess)
        infer_summary_writer = SummaryWriter(infer_model.graph, os.path.join(summary_output_dir, 'infer'))
        init_model(infer_sess, infer_model)
        eval_logger = EvalLogger(hyperparams.data_log_output_dir)
    logger.log_print('##### start training #####')
    global_step = 0
    for epoch in range(hyperparams.train_num_epoch):
        (feed_dict, data_dict) = generate_feed_dict(train_model, len(train_model.input_answer), hyperparams.train_batch_size)
        train_sess.run(train_model.data_pipeline.initializer, feed_dict=feed_dict)
        step_in_epoch = 0
        while True:
            try:
                start_time = time.time()
                train_result = train_model.model.train(train_sess, train_model.word_embedding)
                end_time = time.time()
                global_step = train_result.global_step
                step_in_epoch += 1
                train_logger.update(train_result, epoch, step_in_epoch, (end_time - start_time))
                if ((step_in_epoch % hyperparams.train_step_per_stat) == 0):
                    train_logger.check()
                    train_summary_writer.add_summary(train_result.summary, global_step)
                if ((step_in_epoch % hyperparams.train_step_per_ckpt) == 0):
                    train_model.model.save(train_sess, global_step, 'debug')
                if (((step_in_epoch % hyperparams.train_step_per_eval) == 0) and (enable_eval == True)):
                    ckpt_file = infer_model.model.get_latest_ckpt('debug')
                    sample_result = sample_predict(infer_sess, infer_model, hyperparams.train_eval_batch_size, ckpt_file, 'debug')
                    extrinsic_eval(eval_logger, infer_summary_writer, sample_result, hyperparams.train_eval_metric, hyperparams.train_eval_detail_type, global_step, epoch)
                    decoding_eval(eval_logger, sample_result, hyperparams.train_decoding_sample_size, (hyperparams.train_random_seed + global_step), global_step, epoch)
            except tf.errors.OutOfRangeError:
                train_logger.check()
                train_summary_writer.add_summary(train_result.summary, global_step)
                train_model.model.save(train_sess, global_step, 'epoch')
                if (enable_eval == True):
                    ckpt_file = infer_model.model.get_latest_ckpt('epoch')
                    sample_result = sample_predict(infer_sess, infer_model, hyperparams.train_eval_batch_size, ckpt_file, 'epoch')
                    extrinsic_eval(eval_logger, infer_summary_writer, sample_result, hyperparams.train_eval_metric, hyperparams.train_eval_detail_type, global_step, epoch)
                    decoding_eval(eval_logger, sample_result, hyperparams.train_decoding_sample_size, (hyperparams.train_random_seed + global_step), global_step, epoch)
                break
    train_summary_writer.close_writer()
    if (enable_eval == True):
        infer_summary_writer.close_writer()
    logger.log_print('##### finish training #####')