Должна ли Роберта быть намного лучше для классификации текста, чем BERT?
У меня проблема с двоичным TC, около 10 тыс. Коротких сэмплов и сбалансированное соотношение классов. Я использую предварительно обученные BERT и Роберту для классификации. С Roberta я получаю на 20% лучшие результаты, чем BERT, почти идеальную точность 0,99 с тем же набором данных, гиперпараметрами и начальным числом. Мне это кажется странным. Я уверен, что у меня правильный разделение на поезд / разработку / тест, ни один из образцов не дублируется в разделах.
Делает ли RoBERTa то, чего не делает BERT, например, определение пороговых значений для окончательных прогнозов, или это просто намного лучшая модель? Может быть, это техническая проблема, например, какой-то кеш, из-за которого данные разработки / обучения попадают в процесс обучения Роберты?
MAX_LENGTH = 128
#MODEL_NAME = 'fav-kky/FERNET-C5'
MODEL_NAME = 'ufal/robeczech-base'
TARGET_NAMES = ['0', '1']
(train_texts, dev_texts, test_texts, train_labels, dev_labels, test_labels) = ...
set_seed(SEED)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=False) # buggy fast tokenizer in Roberta
train_encodings = tokenizer(train_texts, truncation=True, padding=True, max_length=MAX_LENGTH)
dev_encodings = tokenizer(dev_texts, truncation=True, padding=True, max_length=MAX_LENGTH)
train_dataset = Dataset(train_encodings, train_labels)
dev_dataset = Dataset(dev_encodings, dev_labels)
if MODEL_NAME == 'ufal/robeczech-base':
model = RobertaForSequenceClassification.from_pretrained(MODEL_NAME, num_labels=len(TARGET_NAMES)).to("cuda")
else:
model = BertForSequenceClassification.from_pretrained(MODEL_NAME, num_labels=len(TARGET_NAMES)).to("cuda")
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=10,
per_device_train_batch_size=64,
per_device_eval_batch_size=64,
warmup_steps=100,
logging_dir='./logs',
load_best_model_at_end=True,
logging_steps=25,
evaluation_strategy="steps",
learning_rate=1e-5,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=dev_dataset,
compute_metrics=compute_metrics,
)
trainer.train()
trainer.evaluate()
def get_probs(text):
inputs = tokenizer(text, padding=True, truncation=True, max_length=MAX_LENGTH, return_tensors="pt").to("cuda")
outputs = model(**inputs)
return outputs[0].softmax(1)
predictions = np.array([get_probs(test_texts[i]).cpu().detach().numpy()[0] for i in range(len(test_texts))])
print(f1_score(test_labels, np.argmax(predictions, -1), average='weighted'))
print(confusion_matrix(test_labels, np.argmax(predictions, -1)))