def train_and_evaluate(model, train_data, val_data, optimizer, scheduler, params, model_dir, restore_dir=None): """Train the model and evaluate every epoch.""" # reload weights from restore_dir if specified if restore_dir is not None: model = BertForSequenceTagging.from_pretrained(tagger_model_dir) best_val_f1 = 0.0 patience_counter = 0 for epoch in range(1, params.epoch_num + 1): # Run one epoch logging.info("Epoch {}/{}".format(epoch, params.epoch_num)) # Compute number of batches in one epoch params.train_steps = params.train_size // params.batch_size params.val_steps = params.val_size // params.batch_size # data iterator for training train_data_iterator = data_loader.data_iterator(train_data, shuffle=True) # Train for one epoch on training set train(model, train_data_iterator, optimizer, scheduler, params) # data iterator for evaluation train_data_iterator = data_loader.data_iterator(train_data, shuffle=False) val_data_iterator = data_loader.data_iterator(val_data, shuffle=False) # Evaluate for one epoch on training set and validation set # params.eval_steps = params.train_steps # train_metrics = evaluate(model, train_data_iterator, params, mark='Train') params.eval_steps = params.val_steps val_metrics = evaluate(model, val_data_iterator, params, mark='Val') val_f1 = val_metrics['f1'] improve_f1 = val_f1 - best_val_f1 if improve_f1 > 0: logging.info("- Found new best F1") best_val_f1 = val_f1 model.save_pretrained(model_dir) if improve_f1 < params.patience: patience_counter += 1 else: patience_counter = 0 else: patience_counter += 1 # Early stopping and logging best f1 if (patience_counter >= params.patience_num and epoch > params.min_epoch_num) or epoch == params.epoch_num: logging.info("Best val f1: {:05.2f}".format(best_val_f1)) break
def bert_ner_init(): args = parser.parse_args() tagger_model_dir = 'experiments/' + args.dataset # Load the parameters from json file json_path = os.path.join(tagger_model_dir, 'params.json') assert os.path.isfile( json_path), "No json configuration file found at {}".format(json_path) params = utils.Params(json_path) # Use GPUs if available params.device = torch.device( 'cuda' if torch.cuda.is_available() else 'cpu') # Set the random seed for reproducible experiments random.seed(args.seed) torch.manual_seed(args.seed) params.seed = args.seed # Set the logger utils.set_logger(os.path.join(tagger_model_dir, 'evaluate.log')) # Create the input data pipeline logging.info("Loading the dataset...") # Initialize the DataLoader data_dir = 'data/' + args.dataset if args.dataset in ["conll"]: bert_class = 'bert-base-cased' elif args.dataset in ["msra"]: bert_class = 'bert-base-chinese' data_loader = DataLoader(data_dir, bert_class, params, token_pad_idx=0, tag_pad_idx=-1) # Load the model model = BertForSequenceTagging.from_pretrained(tagger_model_dir) model.to(params.device) return model, data_loader, args.dataset, params
data_loader = DataLoader(data_dir, bert_class, params, token_pad_idx=0, tag_pad_idx=-1) logging.info("Loading the datasets...") # Load training data and test data train_data = data_loader.load_data('train') val_data = data_loader.load_data('val') # Specify the training and validation dataset sizes params.train_size = train_data['size'] params.val_size = val_data['size'] logging.info("Loading BERT model...") # Prepare model model = BertForSequenceTagging.from_pretrained(bert_class, num_labels=len(params.tag2idx)) model.to(params.device) # Prepare optimizer if params.full_finetuning: param_optimizer = list(model.named_parameters()) 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': params.weight_decay}, {'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0} ] else: # only finetune the head classifier param_optimizer = list(model.classifier.named_parameters()) optimizer_grouped_parameters = [{'params': [p for n, p in param_optimizer]}]
if args.dataset in ["proto"]: bert_class = 'dmis-lab/biobert-v1.1' # auto # bert_class = 'pretrained_bert_models/bert-base-cased/' # manual elif args.dataset in ["msra"]: bert_class = 'dmis-lab/biobert-v1.1' # auto # bert_class = 'pretrained_bert_models/bert-base-chinese/' # manual data_loader = DataLoader(data_dir, bert_class, params, token_pad_idx=0, tag_pad_idx=-1) # Load the model model = BertForSequenceTagging.from_pretrained(tagger_model_dir) model.to(params.device) #txtfiles of test data txtfiles = [] for file in glob.glob("data/proto/interactive/sentences/*.txt"): txtfiles.append(file) for i in txtfiles: # Load data test_data = data_loader.load_data_active('interactive', i) # Specify the test set size params.test_size = test_data['size'] params.eval_steps = params.test_size // params.batch_size test_data_iterator = data_loader.data_iterator(test_data,