def main():
    parser = argparse.ArgumentParser()

    ## Required parameters
    parser.add_argument("--data_dir",
                        default=None,
                        type=str,
                        required=True,
                        help="The input data dir. Should contain the .tsv files for the task.")
    parser.add_argument("--model_dir",
                        default=None,
                        type=str,
                        required=True,
                        help="The output directory where the model checkpoints are written.")

    args = parser.parse_args()

    # TODO: Fix hardcoded values
    max_seq_length = 512
    bert_model = 'bert-base-cased'
    do_lower_case = False
    n_classe = 3
    test_file = 'gap-development.tsv'
    batch_size = 1

    # Load a trained model and config that you have fine-tuned
    config = BertConfig(os.path.join(args.model_dir, CONFIG_NAME))
    model = BertForMultipleChoice(config, num_choices=3)
    model.load_state_dict(torch.load(os.path.join(args.model_dir, WEIGHTS_NAME)))
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)

    tokenizer = BertTokenizer.from_pretrained(bert_model, do_lower_case=do_lower_case)

    # Prepare test data
    examples = read_GAP_examples(os.path.join(args.data_dir, test_file), n_classes=n_classes), is_training=False)
    features = convert_examples_to_features(examples, tokenizer, max_seq_length, True)

    all_input_ids = torch.tensor(select_field(features, 'input_ids'), dtype=torch.long)
    all_input_mask = torch.tensor(select_field(features, 'input_mask'), dtype=torch.long)
    all_segment_ids = torch.tensor(select_field(features, 'segment_ids'), dtype=torch.long)

    data = TensorDataset(all_input_ids, all_input_mask, all_segment_ids)

    dataloader = DataLoader(data,
                            sampler=SequentialSampler(data),
                            batch_size=batch_size,
                            shuffle=False)
Beispiel #2
0
def get_scores(args, split='test'):

    if split == 'train':
        input_file = os.path.join(args.data_dir, args.csvtrain)
        filescores = os.path.join(
            args.data_dir, 'PriorScores/priorscores_answers_train.pckl')
    elif split == 'val':
        input_file = os.path.join(args.data_dir, args.csvval)
        filescores = os.path.join(args.data_dir,
                                  'PriorScores/priorscores_answers_val.pckl')
    elif split == 'test':
        input_file = os.path.join(args.data_dir, args.csvtest)
        filescores = os.path.join(args.data_dir,
                                  'PriorScores/priorscores_answers_test.pckl')

    if os.path.exists(filescores):
        return

    # Load Model
    tokenizer = BertTokenizer.from_pretrained(args.bert_model,
                                              do_lower_case=args.do_lower_case)
    output_model_file = os.path.join(outdir, WEIGHTS_NAME)
    output_config_file = os.path.join(outdir, CONFIG_NAME)
    config = BertConfig(output_config_file)
    model = BertForMultipleChoice(config, num_choices=4)
    model.load_state_dict(torch.load(output_model_file))
    model.to(args.device)
    n_gpu = torch.cuda.device_count()
    logger.info("device: {} n_gpu: {}".format(args.device, n_gpu))
    if n_gpu > 1:
        model = torch.nn.DataParallel(model)

    # Data
    eval_examples = read_samples(input_file)
    eval_features = convert_to_features(eval_examples, tokenizer,
                                        args.max_seq_length)
    all_input_ids = torch.tensor(select_field(eval_features, 'input_ids'),
                                 dtype=torch.long)
    all_input_mask = torch.tensor(select_field(eval_features, 'input_mask'),
                                  dtype=torch.long)
    all_segment_ids = torch.tensor(select_field(eval_features, 'segment_ids'),
                                   dtype=torch.long)
    all_labels = torch.tensor([example.label for example in eval_examples],
                              dtype=torch.long)
    eval_data = TensorDataset(all_input_ids, all_input_mask, all_segment_ids,
                              all_labels)
    eval_sampler = SequentialSampler(eval_data)
    eval_dataloader = DataLoader(eval_data,
                                 sampler=eval_sampler,
                                 batch_size=args.eval_batch_size)

    # Run prediction
    logger.info("***** Compute prior scores *****")
    logger.info("Num examples = %d", len(eval_examples))
    logger.info("Batch size = %d", args.eval_batch_size)
    model.eval()
    batch_idx = 0
    for _, batch in enumerate(tqdm(eval_dataloader, desc="Iteration")):
        input_ids, input_mask, segment_ids, truelabel = batch
        input_ids = input_ids.to(args.device)
        input_mask = input_mask.to(args.device)
        segment_ids = segment_ids.to(args.device)

        with torch.no_grad():
            logits = model(input_ids, segment_ids, input_mask)
            logits = nn.functional.softmax(logits)

        logits = logits.detach().cpu().numpy()
        if batch_idx == 0:
            scores = logits
        else:
            scores = np.concatenate((scores, logits), axis=0)
        batch_idx += 1

    if not os.path.exists(os.path.dirname(filescores)):
        os.mkdir(os.path.dirname(filescores))
    utils.save_obj(scores, filescores)
    logger.info('Prior scores for %s saved into %s' % (split, filescores))
def main(config, bert_vocab_file, bert_model_dir):

    if not os.path.exists(config.output_dir):
        os.makedirs(config.output_dir)

    if not os.path.exists(config.cache_dir):
        os.makedirs(config.cache_dir)

    output_model_file = os.path.join(config.output_dir,
                                     config.weights_name)  # 模型输出文件
    output_config_file = os.path.join(config.output_dir, config.config_name)

    # 设备准备
    gpu_ids = [int(device_id) for device_id in config.gpu_ids.split()]
    device, n_gpu = get_device(gpu_ids[0])
    if n_gpu > 1:
        n_gpu = len(gpu_ids)

    config.train_batch_size = config.train_batch_size // config.gradient_accumulation_steps
    """ 设定随机种子 """
    random.seed(config.seed)
    np.random.seed(config.seed)
    torch.manual_seed(config.seed)
    if n_gpu > 0:
        torch.cuda.manual_seed_all(config.seed)

    tokenizer = BertTokenizer.from_pretrained(
        bert_vocab_file, do_lower_case=config.do_lower_case)
    label_list = ["0", "1", "2", "3"]
    if config.do_train:

        # 数据准备
        train_file = os.path.join(config.data_dir, "train.json")
        dev_file = os.path.join(config.data_dir, "dev.json")

        train_dataloader, train_len = load_data(train_file, tokenizer,
                                                config.max_seq_length,
                                                config.train_batch_size)

        dev_dataloader, dev_len = load_data(dev_file, tokenizer,
                                            config.max_seq_length,
                                            config.dev_batch_size)

        num_train_steps = int(train_len / config.train_batch_size /
                              config.gradient_accumulation_steps *
                              config.num_train_epochs)

        # 模型准备
        model = BertForMultipleChoice.from_pretrained(
            bert_model_dir, cache_dir=config.cache_dir, num_choices=4)

        model.to(device)
        if n_gpu > 1:
            model = torch.nn.DataParallel(model, device_ids=gpu_ids)

        # 优化器准备
        param_optimizer = list(model.named_parameters())
        param_optimizer = [n for n in param_optimizer if 'pooler' not in n[0]]

        no_decay = ['bias', 'LayerNorm.bias', 'LayerNorm.weight']
        optimizer_grouped_parameters = [{
            'params': [
                p for n, p in param_optimizer
                if not any(nd in n for nd in no_decay)
            ],
            'weight_decay':
            0.01
        }, {
            'params':
            [p for n, p in param_optimizer if any(nd in n for nd in no_decay)],
            'weight_decay':
            0.0
        }]

        optimizer = BertAdam(optimizer_grouped_parameters,
                             lr=config.learning_rate,
                             warmup=config.warmup_proportion,
                             t_total=num_train_steps)

        criterion = nn.CrossEntropyLoss()
        criterion = criterion.to(device)

        train(config.num_train_epochs, n_gpu, train_dataloader, dev_dataloader,
              model, optimizer, criterion, config.gradient_accumulation_steps,
              device, label_list, output_model_file, output_config_file,
              config.log_dir, config.print_step)

    test_file = os.path.join(config.data_dir, "test.json")
    test_dataloader, _ = load_data(test_file, tokenizer, config.max_seq_length,
                                   config.test_batch_size)

    bert_config = BertConfig(output_config_file)
    model = BertForMultipleChoice(bert_config, num_choices=len(label_list))
    model.load_state_dict(torch.load(output_model_file))
    model.to(device)
    """ 损失函数准备 """
    criterion = nn.CrossEntropyLoss()
    criterion = criterion.to(device)

    test_loss, test_acc, test_report = evaluate(model, test_dataloader,
                                                criterion, device, label_list)

    print("-------------- Test -------------")
    print(f'\t  Loss: {test_loss: .3f} | Acc: {test_acc*100: .3f} %')

    for label in label_list:
        print('\t {}: Precision: {} | recall: {} | f1 score: {}'.format(
            label, test_report[label]['precision'],
            test_report[label]['recall'], test_report[label]['f1-score']))
    print_list = ['macro avg', 'weighted avg']

    for label in print_list:
        print('\t {}: Precision: {} | recall: {} | f1 score: {}'.format(
            label, test_report[label]['precision'],
            test_report[label]['recall'], test_report[label]['f1-score']))