目录

  • 1 相关信息
  • 2 引言
  • 3 实现
    • 3.1 数据预处理
    • 3.2 Bert
  • 4 提分点技巧讲解
  • 5 未来展望

1 相关信息

  • 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–1 赛后总结与分析

  • 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–2 数据分析

  • 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–3 TextCNN Fasttext 方案

  • 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–4 机器学习LGB 方案

  • 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–5 Bert 方案

  • 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–6 提分方案

2 引言

(1)Baseline的选择

我选择的是Datawhale闫强“致Great Bert方案”进行的迭代优化,其中是使用加载预训练模型,进行微调。用到了差分学习率和AdamW 优化器。这些点这对于Bert的微调有巨大的作用。还有更多Bert微调技巧来自于论文《How to Fine-Tune BERT for Text Classification?》论文中提到的微调策略有

  1. 处理长文本 我们知道BERT 的最大序列长度为 512,BERT 应用于文本分类的第一个问题是如何处理长度大于 512 的文本。本文尝试了以下方式处理长文章。
  • 截断法 文章的关键信息位于开头和结尾。 我们可以使用三种不同的截断文本方法来执行 BERT 微调。

    • 只截断头部
    • 只截断尾部
    • 头尾截断
  • 层级法 输入的文本首先被分成k = L/510个片段,喂入 BERT 以获得 k 个文本片段的表示向量。 每个分数的表示是最后一层的 [CLS] 标记的隐藏状态,然后我们使用均值池化、最大池化和自注意力来组合所有分数的表示。
  1. 不同层的特征 BERT 的每一层都捕获输入文本的不同特征。 改论文研究了来自不同层的特征的有效性,可以看到:最后一层表征效果最好;最后4层进行max-pooling效果最好
  2. 灾难性遗忘 Catastrophic forgetting (灾难性遗忘)通常是迁移学习中的常见诟病,这意味着在学习新知识的过程中预先训练的知识会被遗忘。 因此,本文还研究了 BERT 是否存在灾难性遗忘问题。 我们用不同的学习率对 BERT 进行了微调,发现需要较低的学习率,例如 2e-5,才能使 BERT 克服灾难性遗忘问题。 在 4e-4 的较大学习率下,训练集无法收敛。所以当预训练模型失效不能够收敛的时候多检查下超参数是否设置有问题。
  3. Layer-wise Decreasing Layer Rate 逐层降低学习率 下表 显示了不同基础学习率和衰减因子在 IMDb 数据集上的性能。 我们发现为下层分配较低的学习率对微调 BERT 是有效的,比较合适的设置是 ξ=0.95 和 lr=2.0e-5

(2)方案的改进

通过以下方案,将单模型Bert从0.79逐步提升到0.8246,最终通过模型融合得到最高得分0.8304

  • 数据预处理

Bert的数据预处理,只做了所有字母转换为小写和词性还原,词性还原比如working还原为work,采用nltk.stem.WordNetLemmatizer.lemmatize(word)工具包。其他的预处理,则是适得其反,过多的预处理,会降低模型精度,因为通过查阅资料,Bert预训练的模型,在训练当初就是使用原生数据训练的,为了达到更好的fine tune微调效果,在使用预训练模型的数据尽量与训练模型时候的数据形式保持统一。

  • K折交叉验证

选择的是5折2epoch训练,3090的显卡,5W的数据,batch—size为10,bert_base都得训练7个小时左右,bert_large 10个小时左右,Roberta_large 14个小时左右。更别说后期通过数据增强和加入伪标签总训练数据近16W的时候,训练时间加倍。一训练就是一整天。所以选择5折2epoch是迫不得已,通过观察发现,训练完模型都没有过拟合,完全可以加大训练深度,设4epoch模型精度会更高。

  • Bert+Bi-LSTM

    • bert_base
    • Bert_large
    • Roberta_large

Bert_ base模型最小,有444M,8G的显存的勉强能跑起来,模型精度在bert中最低,历史最高得分0.8162。bert_large模型规模中等,1G以上的,11G的显存都无法跑起来。模型精度中等,历史最高得分0.8171。Roberta_large规模比Bert_large还要大,需要的显存更大。模型精度最高历史最高得分0.8246,通过其他Baseline的启发,在bert后加一层Bi-LSTM能提高千分点。也有方案加一层Attention的,但是我们没有取得成功。

  • 数据增强:具体实现见英文文本数据增强

    • 第一种:随机删除、随机替换、同义词替换
    • 第二种:互译(回译):翻译成其他语言再翻译会英文

第一种方式,将原始训练集5W的数据全部增强,第二种方式也将原始5W数据进行了增强。在传统 深度学习模型TextCNN、FastText方案中,这两种增强并没有带来增益,但是在Bert中,两种数据增强方式,都带来了增益。

这两种方式我们尝试了三种组合。带来的增益幅度也是不一样的

(1)原始数据5W+第一种数据增强5W:提升0.05+

(2)原始数据5W+第二种数据增强5W:提升0.05+

(3)原始数据5W+第一种数据增强5W+第二种数据增强5W:提升0.1+

  • 伪标签:具体实现见【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–6 提分方案

    • 根据多模型结果投票的原理

将测试集放入各个模型中预测,得到多个模型的预测结果,选择各个模型都投票的数据,给测试集做伪标签,即获得Top K 的高质量标签,再将这些伪标签和对应的文本数据加入训练集中重新从零训练模型。直接将线上提升0.1+个点,反复重复以上操作,还能得到更高准确率,直到不再提升。该方式在传统DL 方案中能提升0.3个点,绝对的大杀器。

注意图片中的第二个Model和第一个Model不是同一个,第二个Model,是重新训练出来的

  • 调参

    • Batch_size
    • 学习率
    • 文本截断长度MAX_LEN

注意本次任务中通过对比实验,Batch_size选择的是10 ,对应模型初始学习率2e-5,全连接层的初始学习率是1e-4。如果显存够大,可以加倍,但是学习率也需要加倍。实验过程中,batch-size为4时,模型精度更高,但是太费时,我们只能舍弃精度,加快训练。

文本的最大长度,通过实验对比,选择过100、200、300,发现300的时候模型精度最高

  • 混合精度训练,具体实现见【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–6 提分方案

混合精度训练是在尽可能减少精度损失的情况下利用半精度浮点数加速训练。它使用FP16即半精度浮点数存储权重和梯度。在减少占用内存的同时起到了加速训练的效果。

  • 模型融合:具体实现见【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–6 提分方案

    • Stacking
    • Voting投票融合

Stacking 是将验证集和测试集同时放入多个模型中预测,各自得到预测矩阵,再将每个模型的预测矩阵水平合并得到新的矩阵,则将验证集合并的预测矩阵作为基模型的训练集,去训练基模型,基模型此任务中选择的LogisticRegression 。用测试集合并的预测矩阵放入基模型预测作为最终的预测值。

Voting 在分类任务中是常用的融合技巧,以下一张图,一目了然,每一列表示一个模型的预测结果,每行去计数,每行出现次数最高的数即是该行的最终值。

但是我们的最终融合方式并不是简单的等权融合,而是变形的加权融合。是把个模型的历史的高分结果,进行了按比例融合,选择了3个bert_base、4个roberta_large、3个bert_large、一个robert_base、1个机器学习LGB、1个textcnn、1个fasttext。如下图所示

3 实现

Github源码下载

3.1 数据预处理

(1)加载包

import pandas as pd
from nltk.stem import WordNetLemmatizer
from tqdm import tqdm
import re
import nltk
tqdm.pandas()
import re
import os
import pickletrain = pd.read_csv('./data/train_data.csv',sep="\t")
test = pd.read_csv('./data/test.csv', sep='\t')
def preprocess_text(document):stemmer = WordNetLemmatizer()text = str(document)# 替换换行符text = text.replace("\n", ' ')# 用单个空格替换多个空格text = re.sub(r'\s+', ' ', text, flags=re.I)# 转换为小写text = text.lower()# 词形还原tokens = text.split()tokens = [stemmer.lemmatize(word) for word in tokens]preprocessed_text = ' '.join(tokens)return preprocessed_text
train["title"] = train["title"].progress_apply(lambda x: preprocess_text(x))
train["abstract"] = train["abstract"].progress_apply(lambda x: preprocess_text(x))
test["title"] = test["title"].progress_apply(lambda x: preprocess_text(x))
test["abstract"] = test["abstract"].progress_apply(lambda x: preprocess_text(x))

(2)训练集预处理

train_text_list = []
for index, row in train.iterrows():title = row["title"]abstract = row["abstract"]text = "[CLS] " + title + " [SEP] " + abstract + " [SEP]"train_text_list.append(text)
train['text'] = train_text_listlabel_path = "data/pseudo_data/label_id2cate.pkl"
#将标签进行转换
label_id2cate = dict(enumerate(train.categories.unique()))
label_cate2id = {value: key for key, value in label_id2cate.items()}with open(label_path, 'wb') as f:pickle.dump(label_id2cate, f, pickle.HIGHEST_PROTOCOL)
train['label'] = train['categories'].map(label_cate2id)
train_data = pd.DataFrame(columns=['text','label'])
train_data['text'] = train['text']
train_data['label'] = train['label']
train_data.to_csv('data/train_clean_data.csv', sep='\t',index=False)

(3)测试集预处理

test_text_list = []
for index, row in test.iterrows():title = row["title"]abstract = row["abstract"]text = "[CLS] " + title + " [SEP] " + abstract + " [SEP]"test_text_list.append(text)
test['text'] = test_text_list
pseudo_label = pd.read_csv("./submit_voting-8-9-2.csv")
test['label'] = pseudo_label['categories'].map(label_cate2id)
# 去除换行符
test_data = test.drop(['paperid', 'title', 'abstract'], axis=1, inplace=False)
test_data.to_csv('data/test_clean_data.csv', sep='\t', index=False)

3.2 Bert

bert_base、bert_large、roberta_large代码都是一样的,唯一的不同在于使用预训练模型和对应分词器的选择不同。在以下代码会注释说明

(1)加载包

# 导入transformers
import transformers
from transformers import AutoConfig,AutoModel,AutoTokenizer,logging
from torch.utils.data import RandomSampler,Dataset, DataLoader
from transformers import BertModel, BertTokenizer, BertConfig, AdamW, get_linear_schedule_with_warmup
from transformers import RobertaTokenizer, RobertaModel
# 导入torch
import torch
import torch.nn as nn
import torch.nn.functional as F# 常用包
import re
import os
import numpy as np
import pandas as pd
from tqdm import tqdm
import pickle
import os
import torch
import torch.nn as nn
from torch.utils import data
from sklearn.utils import resample
from sklearn.metrics import accuracy_score
# 全局变量
os.environ["TOKENIZERS_PARALLELISM"] = "false"
RANDOM_SEED = 42
np.random.seed(RANDOM_SEED)
torch.manual_seed(RANDOM_SEED)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

(2)模型结构

cache_dir = '/media/mgege007/winType/cache'
class PaperClassifier(nn.Module):def __init__(self):n_classes = 39super(PaperClassifier, self).__init__()# 如果是Bert_large,此处是# PRE_TRAINED_MODEL_NAME = "bert-large-uncased"# self.robert = BertModel.from_pretrained(PRE_TRAINED_MODEL_NAME)# 如果是bert_base,此处是PRE_TRAINED_MODEL_NAME = "bert-base-uncased"self.robert = BertModel.from_pretrained(PRE_TRAINED_MODEL_NAME)# 如果是roberta_large,此处是# PRE_TRAINED_MODEL_NAME = 'roberta-large'# self.robert = RobertaModel.from_pretrained(PRE_TRAINED_MODEL_NAME)self.bilstm = nn.LSTM(input_size=self.robert.config.hidden_size,hidden_size=self.robert.config.hidden_size, batch_first=True, bidirectional=True)self.drop = nn.Dropout(p=0.3)self.out = nn.Linear(self.robert.config.hidden_size * 2, n_classes)def forward(self, input_ids, attention_mask):last_hidden_out, pooled_output = self.robert(  # 只要了句子级表示?    _:[10, 300, 768]    [16, 768]input_ids=input_ids,attention_mask=attention_mask)  # [16, 300]300是句子长度last_hidden_out = self.drop(last_hidden_out)output_hidden, _ = self.bilstm(last_hidden_out)  # [10, 300, 768]output = self.drop(output_hidden)  # dropoutoutput = output.mean(dim=1)return self.out(output)

(3)读取数据

def data_process():train = pd.read_csv('data/train_clean_data.csv', sep='\t')test = pd.read_csv('data/test_clean_data.csv', sep='\t')label_path = "data/label_id2cate.pkl"# label编码所需要的字典if os.path.exists(label_path):with open(label_path, 'rb') as f:label_id2cate = pickle.load(f)return train, test, label_id2cate

(4)封装数据集

class PaperDataset(Dataset):def __init__(self, texts, labels, tokenizer, max_len):self.texts = textsself.labels = labelsself.tokenizer = tokenizerself.max_len = max_lendef __len__(self):return len(self.texts)def __getitem__(self, item):"""item 为数据索引,迭代取第item条数据"""text = str(self.texts[item])label = self.labels[item]encoding = self.tokenizer.encode_plus(  # 等价于tokenizer.tokenize() + tokenizer.convert_tokens_to_ids()text,add_special_tokens=True,max_length=self.max_len,truncation=True,return_token_type_ids=True,pad_to_max_length=True,return_attention_mask=True,return_tensors='pt',)return {'texts': text,'input_ids': encoding['input_ids'].flatten(),'attention_mask': encoding['attention_mask'].flatten(),'labels': torch.tensor(label, dtype=torch.long)}
def create_data_loader(df, tokenizer, max_len, batch_size,sampler):ds = PaperDataset(  # datasettexts=df['text'].values,labels=df['label'].values,tokenizer=tokenizer,max_len=max_len)return DataLoader(ds,batch_size=batch_size,sampler = sampler,num_workers=4,  # 多线程pin_memory=True  # 页锁定内存)
def create_test_loader(df, tokenizer, max_len, batch_size):ds = PaperDataset(  # datasettexts=df['text'].values,labels=df['label'].values,tokenizer=tokenizer,max_len=max_len)return DataLoader(ds,batch_size=batch_size,num_workers=4,#多线程pin_memory=True  # 页锁定内存)

(5)定义1个epoch训练

def train_epoch(model, data_loader, loss_fn, optimizer, device, scheduler):print("start training!")model = model.train()losses = []pred_ls = []label_ls = []accumulate_step = 10i = 0for d in tqdm(data_loader):input_ids = d["input_ids"].to(device)attention_mask = d["attention_mask"].to(device)targets = d["labels"].to(device)outputs = model(input_ids=input_ids,attention_mask=attention_mask)_, preds = torch.max(outputs, dim=1)loss = loss_fn(outputs, targets)losses.append(loss.item())loss = loss/accumulate_steploss.backward()nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)if (i+1)%accumulate_step ==0:optimizer.step()scheduler.step()optimizer.zero_grad()i+=1label_ls.extend(d["labels"])pred_ls.extend(preds.tolist())correct_predictions = accuracy_score(label_ls, pred_ls)return correct_predictions, np.mean(losses)# 验证
def eval_model(model, data_loader, loss_fn, device):model = model.eval()  # 验证预测模式losses = []pred_ls = []label_ls = []with torch.no_grad():for d in data_loader:input_ids = d["input_ids"].to(device)attention_mask = d["attention_mask"].to(device)targets = d["labels"].to(device)outputs = model(input_ids=input_ids,attention_mask=attention_mask)_, preds = torch.max(outputs, dim=1)loss = loss_fn(outputs, targets)y_pred_arr = outputs.data.cpu().numpy()losses.append(loss.item())pred_ls.extend(preds.tolist())label_ls.extend(d["labels"])         correct_predictions = accuracy_score(label_ls, pred_ls)return correct_predictions, np.mean(losses)

(6)预测结果

def model_predictions(model, data_loader, device):model = model.eval()result = []with torch.no_grad():for d in data_loader:input_ids = d["input_ids"].to(device)attention_mask = d["attention_mask"].to(device)outputs = model(input_ids=input_ids,attention_mask=attention_mask)y_pred = outputs.data.cpu().numpy()result.extend(y_pred)return result

(7)K折划分数据

# K折数据划分
def load_data_kfold(dataset,BATCH_SIZE,MAX_LEN, k, n):print("Cross validation第{}折正在划分数据集".format(n+1))l = len(dataset)print(l)shuffle_dataset = Truerandom_seed = 42  # fixed random seedindices = list(range(l))if shuffle_dataset:np.random.seed(random_seed)np.random.shuffle(indices)  # shuffle# Collect indexes of samples for validation set.val_indices = indices[int(l / k) * n:int(l / k) * (n + 1)]train_indices = list(set(indices).difference(set(val_indices)))train_sampler = data.SubsetRandomSampler(train_indices)  # build Samplervalid_sampler = data.SubsetRandomSampler(val_indices)tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')train_data_loader = create_data_loader(dataset, tokenizer, MAX_LEN, BATCH_SIZE,train_sampler)val_data_loader = create_data_loader(dataset, tokenizer, MAX_LEN, BATCH_SIZE,valid_sampler)print("划分完成")return train_data_loader, val_data_loader

(8)模型层间差分学习率

# 差分学习率的设置
def get_parameters(model, model_init_lr, multiplier, classifier_lr):parameters = []lr = model_init_lrfor layer in range(12, -1, -1):  # 遍历模型的每一层,bert_large和robert_large参数选择24,bert_base选择12layer_params = {'params': [p for n, p in model.named_parameters() if f'encoder.layer.{layer}.' in n],'lr': lr}parameters.append(layer_params)lr *= multiplier  # 每一层的学习率*0.95的衰减因子classifier_params = {'params': [p for n, p in model.named_parameters() if 'layer_norm' in n or 'linear' in nor 'pooling' in n],'lr': classifier_lr  # 单独针对全连接层}parameters.append(classifier_params)return parameters

注意:因为bert_large和robert_large是24层网络结构,参数选择24,bert_base是12层网络结构选择12

(9)训练过程

#训练模型
def train_start(EPOCHS,MAX_LEN,BATCH_SIZE,train, test_data_loader, label_id2cate):#模型定义model = PaperClassifier()model = model.to(device)#普通学习率k_fold = 5predict_all = np.zeros([10000,39])#存储测试集的 预测结果for n in range(k_fold):train_data_loader, val_data_loader = load_data_kfold(train, BATCH_SIZE,MAX_LEN, k_fold, n)#使用差分学习率parameters = get_parameters(model, 2e-5, 0.95, 1e-4)optimizer = AdamW(parameters)total_steps = len(train_data_loader) * EPOCHSscheduler = get_linear_schedule_with_warmup(optimizer,num_warmup_steps=0,num_training_steps=total_steps)loss_fn = nn.CrossEntropyLoss().to(device)best_accuracy = 0for epoch in range(EPOCHS):print(f'Epoch {epoch + 1}/{EPOCHS}')print('-' * 10)train_acc, train_loss = train_epoch(model,train_data_loader,loss_fn,optimizer,device,scheduler)print(f'Train loss {train_loss} accuracy {train_acc}')val_acc, val_loss = eval_model(model, val_data_loader, loss_fn, device)val_x.extend(val_x_epoch)val_y.extend(val_y_epoch)print(f'Val loss {val_loss} accuracy {val_acc}')if val_acc > best_accuracy:torch.save(model.state_dict(), 'model/best_model_state_large_ensemble.bin')best_accuracy = val_acc#进行预测y_pred = model_predictions(model, test_data_loader, device)predict_all += np.array(y_pred)# 预测矩阵取平均predictions = predict_all/k_fold# 存储预测矩阵np.save("submit_arr.npy", predictions)pred = np.argmax(predictions, axis=1)print("计算完成")model_name = "Bert_large_cross"sub = pd.read_csv('data/sample_submit.csv')# 生成提交文件sub['categories'] = list(pred)sub['categories'] = sub['categories'].map(label_id2cate)sub.to_csv('submit/submit_{}.csv'.format(model_name), index=False)

(9)主函数

# 加载数据集
train, test, label_id2cate = data_process()
EPOCHS = 2
MAX_LEN = 300
BATCH_SIZE = 10
# bert_base和bert_large,对应各自的分词器
# PRE_TRAINED_MODEL_NAME = "bert-large-uncased"
PRE_TRAINED_MODEL_NAME = "bert-base-uncased"
tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME)
# roberta_large 选择以下分词器
# PRE_TRAINED_MODEL_NAME = 'roberta-large/'
# tokenizer = RobertaTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME)
# 封装测试集。不封装训练集,因为要先K折划分后再实现封装
test_data_loader = create_test_loader(test, tokenizer, MAX_LEN, BATCH_SIZE)
# 开始训练
train_start(EPOCHS,MAX_LEN,BATCH_SIZE,train, test_data_loader, label_id2cate)

4 提分点技巧讲解

  • 数据增强

NLP英文文本数据增强

  • 伪标签

    【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–6 提分方案

  • 模型融合

    【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–6 提分方案

5 未来展望

  • ITPT

继续预训练自己的数据集,在任务内的训练方式,理论上是可以提升模型的精度,但是我们尝试过训练。设置60epoch,训练5W的数据,训练了20多个小时,只有0.70+的精度,并没有带来提升,没有时间进一步分析就放弃了该方案,费时不讨好。

import warnings
import pandas as pd
from transformers import (AutoModelForMaskedLM,AutoTokenizer, LineByLineTextDataset,DataCollatorForLanguageModeling,Trainer, TrainingArguments)
warnings.filterwarnings('ignore')
train_data = pd.read_csv('data/train/train.csv', sep='\t')
test_data = pd.read_csv('data/test/test.csv', sep='\t')
train_data['text'] = train_data['title'] + '.' + train_data['abstract']
test_data['text'] = test_data['title'] + '.' + test_data['abstract']
data = pd.concat([train_data, test_data])
data['text'] = data['text'].apply(lambda x: x.replace('\n', ''))
text = '\n'.join(data.text.tolist())with open('text.txt', 'w') as f:f.write(text)model_name = 'roberta-base'
model = AutoModelForMaskedLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.save_pretrained('./paper_roberta_base')train_dataset = LineByLineTextDataset(tokenizer=tokenizer,file_path="text.txt",  # mention train text file hereblock_size=256)valid_dataset = LineByLineTextDataset(tokenizer=tokenizer,file_path="text.txt",  # mention valid text file hereblock_size=256)data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=True, mlm_probability=0.15)training_args = TrainingArguments(output_dir="./paper_roberta_base_chk",  # select model path for checkpointoverwrite_output_dir=True,num_train_epochs=5,# 轮数不要设置的太大per_device_train_batch_size=16,per_device_eval_batch_size=16,gradient_accumulation_steps=2,evaluation_strategy='steps',save_total_limit=2,eval_steps=200,metric_for_best_model='eval_loss',greater_is_better=False,load_best_model_at_end=True,prediction_loss_only=True,report_to="none")trainer = Trainer(model=model,args=training_args,data_collator=data_collator,train_dataset=train_dataset,eval_dataset=valid_dataset)trainer.train()
trainer.save_model(f'./paper_roberta_base')
  • 梯度累计优化

通过梯度缓存和累积的方式,用时间来换取模型精度,最终训练效果等效于更大的batch size。因此,只要你跑得起batch_size=1,只要你愿意花n倍的时间,就可以跑出n倍的batch size。

def train_epoch(model, data_loader, loss_fn, optimizer, device, scheduler, n_examples):print("start training!")model = model.train()losses = []correct_predictions = 0step = 0pred_ls = []label_ls = []# 累计次数accumulation_steps = 4i= 0for d in tqdm(data_loader):input_ids = d["input_ids"].to(device)attention_mask = d["attention_mask"].to(device)targets = d["labels"].to(device)outputs = model(input_ids=input_ids,attention_mask=attention_mask)_, preds = torch.max(outputs, dim=1)loss = loss_fn(outputs, targets)loss = loss / accumulation_steps # 梯度累积losses.append(loss.item())loss.backward()if (i+1) % accumulation_steps == 0: # Wait for several backward steps optimizer.step() # Now we can do an optimizer step nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)scheduler.step()model.zero_grad() # Reset gradients tensors label_ls.extend(d["labels"])pred_ls.extend(preds.tolist())i+=1correct_predictions = accuracy_score(label_ls, pred_ls)return correct_predictions, np.mean(losses)
  • 新的方案

BERT推出这一年来,除了XLNet,其他的改进都没带来太多惊喜,无非是越堆越大的模型和数据,以及动辄1024块TPU,让工程师们不知道如何落地。今天要介绍的ELECTRA是我在ICLR盲审中淘到的宝贝(9月25日已截稿),也是BERT推出以来我见过最赞的改进,通过类似GAN的结构和新的预训练任务,在更少的参数量和数据下,不仅吊打BERT,而且仅用1/4的算力就达到了当时SOTA模型RoBERTa的效果。

资料来源:ELECTRA: 超越BERT, 19年最佳NLP预训练模型

【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–5 Bert 方案相关推荐

  1. 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案--1 赛后总结与分析

    目录 1 相关信息 2 总结 2.1 TextCNN.Fasttext等DL方案 2.2 机器学习LGB方案 2.3 Bert方案 3 继续提分点 1 相关信息 [NLP]讯飞英文学术论文分类挑战赛T ...

  2. 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案–4 机器学习LGB 方案

    1 相关信息 [NLP]讯飞英文学术论文分类挑战赛Top10开源多方案–1 赛后总结与分析 [NLP]讯飞英文学术论文分类挑战赛Top10开源多方案–2 数据分析 [NLP]讯飞英文学术论文分类挑战赛 ...

  3. 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案--6 提分方案

    目录 1 相关信息 2 引言 3 提分技巧及实现 3.1 数据增强 3.2 投票融合 3.2 伪标签 4 加快训练 4.1 混合精度训练 4.2 加速训练的其他技巧 4.2.1 有用到的加速策略 4. ...

  4. 【NLP】讯飞英文学术论文分类挑战赛Top10开源多方案--2 数据分析

    目录 相关信息 1 赛题 2 数据分析 2.1 加载数据 2.2 查看缺失值 2.3 标签分布 2.4 文本长度 2.5 标题摘要合并后字符长度 3 总结 相关信息 [NLP]讯飞英文学术论文分类挑战 ...

  5. 有哪些可助力英文学术论文写作的在线网站、工具或软件?

    说到英文学术论文写作,相信小伙伴们都有同样的困惑:不是难以下手就是好不容易憋出了万字长文,回过头来一看语法漏洞百出,真的很让人头疼!即使是科研大神也会有这样的烦恼.读了万卷文献,依旧Chinglish ...

  6. 英文学术论文写作——模式识别方向(笔记)

    文章目录 文章结构 英文写作tips Latex小技巧 英文学术论文写作经验几乎为0,在老师和师兄们的帮助下,学习到了如何撰写文章.仅限于模式识别方向的. 文章结构 文章除去abstract,ackn ...

  7. 讯飞-糖尿病遗传风险检测挑战赛

    讯飞-糖尿病遗传风险检测挑战赛 前言 相关库 一.比赛报名 1.1 赛事任务 1.2 读取数据 训练数据集 测试数据集 1.3 数据集基本信息 数据集维度 数据表基本信息 二.比赛数据分析 2.1 缺 ...

  8. 给出广义随机petri网在可靠性方面应用的英文学术论文

    在可靠性方面应用广义随机Petri网的英文学术论文有很多.您可以在Google Scholar或者IEEE Xplore等学术搜索引擎上搜索关于"generalized Stochastic ...

  9. 英文学术论文review的回复

    因为之前投稿的文章有了review,所以记录一下回复review的细节. 英文学术论文投稿后,期刊编辑人员会对文章进行审核(论文格式,论文领域等),再将文章送至领域专家进行专业性审核.审核结束后,期刊 ...

最新文章

  1. 住房要注意用电安全-记录一下失火
  2. python 求直线交点坐标
  3. 雅虎因性别歧视成被告 不过这次遭歧视的是男性
  4. 算法小记 · 字符串翻转
  5. 什么是数据中心,它们是如何变化的?
  6. Visual Studio 2010 and .NET Framework 4 Beta 1
  7. linux系统中/etc/syslog.conf文件解读
  8. matlab 神经网络设计多层隐含层_数据预测之BP神经网络具体应用以及matlab代码
  9. codeup 1128: 出租车费 贪心|找规律
  10. java面试常考_JAVA面试常考系列十
  11. 查询存储过程,数据库对象的创建历史
  12. paip.regf文件读取与编辑
  13. 机器学习中最重要的公式——贝叶斯公式
  14. 自定义iTerm2主题配置(iTerm2-Color-Schemes)
  15. 猫眼CEO郑志昊:为什么说产品思维已“死”?
  16. 为什么说买腾讯云服务器通过代理商购买更划算
  17. 顺丰下单后处理接收到的xml
  18. 高防服务器单机防御是什么意思?服务器防御100G是什么意思?
  19. [LnOI2019]东京夏日相会
  20. 基于javaweb+springboot的水果商城在线商城(java+Springboot+ssm+mysql+jsp+maven)

热门文章

  1. java.lang.IllegalArgumentException: interface UserMapper is not visible from class loader
  2. python:文献引文网络构建——基于web of science
  3. 单片机毕设选题 - 便携式空气质量检测系统(物联网 嵌入式)
  4. 结识51CTO学院后【51CTO学院三周年】
  5. HP EVA4400简介
  6. 看宗萨蒋扬清者仁波切写的《正见:佛陀的证悟》的书评
  7. java实现 腾讯人机验证 + 前端
  8. jzoj2742. 【PKU1625】Censored!
  9. xmind下载安装电脑版教程
  10. 【转】ACM比赛经验