def train(config, model, train_iter, dev_iter): start_time = time.time() model.train() 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': 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 = torch.optim.Adam(model.parameters(), lr=config.learning_rate) optimizer = BertAdam(optimizer_grouped_parameters, lr=config.learning_rate, warmup=0.05, t_total=len(train_iter) * config.num_epochs) total_batch = 0 # 记录进行到多少batch # dev_best_loss = float('inf') dev_best_acc = -float('inf') last_improve = 0 # 记录上次验证集loss下降的batch数 flag = False # 记录是否很久没有效果提升 model.train() for epoch in range(config.num_epochs): print('Epoch [{}/{}]'.format(epoch + 1, config.num_epochs)) for i, batch in enumerate(train_iter): trains = (batch[0], batch[1], batch[2]) labels = torch.squeeze(batch[3], dim=1) outputs = model(trains) model.zero_grad() class_weight = torch.FloatTensor([1, 1, 1, 1, 1, 1, 1, 0.4, 2, 1]).cuda() loss = F.cross_entropy(outputs, labels, weight=class_weight) # loss = F.cross_entropy(outputs, labels) loss.backward() optimizer.step() if total_batch % 100 == 0: # 每多少轮输出在训练集和验证集上的效果 true = labels.data.cpu() predic = torch.max(outputs.data, 1)[1].cpu() train_acc = metrics.accuracy_score(true, predic) dev_acc, dev_loss, ouputs_all = evaluate(config, model, dev_iter) if dev_acc > dev_best_acc: # dev_best_loss = dev_loss dev_best_acc = dev_acc torch.save(model.state_dict(), config.save_path) improve = '*' last_improve = total_batch else: improve = '' time_dif = get_time_dif(start_time) msg = 'Iter: {0:>6}, Train Loss: {1:>5.2}, Train Acc: {2:>6.2%}, Val Loss: {3:>5.2}, Val Acc: {4:>6.2%}, Time: {5} {6}' print(msg.format(total_batch, loss.item(), train_acc, dev_loss, dev_acc, time_dif, improve)) model.train() total_batch += 1 if total_batch - last_improve > config.require_improvement: # 验证集loss超过1000batch没下降,结束训练 print("No optimization for a long time, auto-stopping...") flag = True break if flag: break
def label_test(config, model, test_iter): # test model.load_state_dict(torch.load(config.save_path)) model.eval() start_time = time.time() test_acc, test_loss, test_report, test_confusion, _ = evaluate(config, model, test_iter, test=True) msg = 'Test Loss: {0:>5.2}, Test Acc: {1:>6.2%}' print(msg.format(test_loss, test_acc)) print("Precision, Recall and F1-Score...") print(test_report) print("Confusion Matrix...") print(test_confusion) time_dif = get_time_dif(start_time) print("Time usage:", time_dif)
seed = config.seed np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic = True # 保证每次结果一样 config.test_path = dataset + '/unlabeled_data.csv' start_time = time.time() data_df = load_data(config.test_path, config, with_label=False) print('Reading testing data...') test_data = Mydataset(config=config, data=data_df, with_labels=False) test_iter = DataLoader(dataset=test_data, batch_size=config.batch_size, shuffle=False) time_dif = get_time_dif(start_time) print("Time usage:", time_dif) model = bert_RNN(config).to(config.device) predict_all = test(config, model, test_iter) # ---------------------生成文件-------------------------- df_test = pd.read_csv(config.submit_example_path, encoding='utf-8') id2label, label2id = json.load(open(config.id2label_path)) id2label = {int(i): j for i, j in id2label.items()} # 转为int型(原本是字符串形式) class_labels = [] rank_labels = [] for i in predict_all: label = str(id2label[i]) class_labels.append(label) if label in ['财经', '时政']: