Truncation methods 截断法 文章的关键信息位于开头和结尾。 我们可以使用三种不同的截断文本方法来执行 BERT 微调。
head-only: keep the first 510 tokens 头部510个字符,加上两个特殊字符刚好是512 ; tail-only: keep the last 510 tokens;尾部510个字符,同理加上两个特殊字符刚好是512 ; head+tail: empirically select the first 128and the last 382 tokens.:尾部结合
Hierarchical methods 层级法 输入的文本首先被分成k = L/510个片段,喂入 BERT 以获得 k 个文本片段的表示向量。 每个分数的表示是最后一层的 [CLS] 标记的隐藏状态,然后我们使用均值池化、最大池化和自注意力来组合所有分数的表示。
image
我们可以看到:最后一层表征效果最好;最后4层进行max-pooling效果最好
image
这个也深有体会,当预训练模型失效不能够收敛的时候多检查下超参数是否设置有问题。
为不同的BERT设置不同的学习率及衰减因子,BERT的表现如何?
image
η^l代表第几层的学习率
ITPT:继续预训练 Bert是在通用的语料上进行预训练的,如果要在特定领域应用文本分类,数据分布一定是有一些差距的。这时候可以考虑进行深度预训练。
image 我们发现几乎所有进一步的预训练模型在所有七个数据集上的表现都比原始 BERT 基础模型。 一般来说,域内预训练可以带来比任务内预训练更好的性能。 在小句子级 TREC 数据集上,任务内预训练会损害性能,而在使用 Yah 的领域预训练中。Yah. A.语料库可以在TREC上取得更好的结果。 这篇论文与其他模型进行了比较,结果如下表所示:
image
class LastFourModel(nn.Module):
def __init__(self):
super().__init__()
config = AutoConfig.from_pretrained(PRE_TRAINED_MODEL_NAME)
config.update({'output_hidden_states':True})
self.model = AutoModel.from_pretrained(PRE_TRAINED_MODEL_NAME, config=config)
self.linear = nn.Linear(4*HIDDEN_SIZE, n_classes)
def forward(self, input_ids, attention_mask):
outputs = self.model(input_ids, attention_mask)
all_hidden_states = torch.stack(outputs[2])
concatenate_pooling = torch.cat(
(all_hidden_states[-1], all_hidden_states[-2], all_hidden_states[-3], all_hidden_states[-4]), -1
)
concatenate_pooling = concatenate_pooling[:,0]
output = self.linear(concatenate_pooling)
return soutput
def get_parameters(model, model_init_lr, multiplier, classifier_lr):
parameters = []
lr = model_init_lr
for layer in range(12,-1,-1):
layer_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
classifier_params = {
'params': [p for n,p in model.named_parameters() if 'layer_norm' in n or 'linear' in n
or 'pooling' in n],
'lr': classifier_lr
}
parameters.append(classifier_params)
return parameters
parameters=get_parameters(model,2e-5,0.95, 1e-4)
optimizer=AdamW(parameters)
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 here
block_size=256)
valid_dataset = LineByLineTextDataset(
tokenizer=tokenizer,
file_path="text.txt", # mention valid text file here
block_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 checkpoint
overwrite_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')