Как изменить параметры модели Берта для лучшей работы на тестовой выборке? - PullRequest
0 голосов
/ 07 августа 2020

Я работаю над заданием НЛП из конкурса Kaggle, цель которого - предсказать, будет ли твит выражать настоящую катастрофу или нет. Я использую BertForSequenceClassification.

Размер моего тренировочного набора составляет 10000, я разделил его на:

  • 8000 как обучающий набор
  • 2000 как набор проверки
  • Скорость обучения: 2e-5
  • Эпохи: 4
  • Размер партии: 32

Даже если у меня хорошие кривые обучения, производительность на тестовом наборе плохо (0,47 при подаче на Kaagle). Я пробовал много изменений в скорости обучения и эпохах, но у меня все еще есть та же проблема.

Как изменить параметры модели Берта для лучшей производительности на тестовом наборе?

from transformers import BertForSequenceClassification,AdamW,BertConfig
from transformers import BertTokenizer
print("Loading BertTokenizer...")
tokenizer=BertTokenizer.from_pretrained("bert-base-uncased")


model=BertForSequenceClassification.from_pretrained(
    "bert-base-uncased",
    num_labels=2,
    output_attentions=False,
    output_hidden_states=False,
    
)

model.cuda()

optimizer=AdamW(model.parameters(),
                lr=1.5e-5,
                eps=1e-8,
               )

from transformers import get_linear_schedule_with_warmup

epochs=4

total_steps=len(train_dataloader)*epochs

scheduler=get_linear_schedule_with_warmup(optimizer,
                                          num_warmup_steps=0,
                                          num_training_steps=total_steps)


import random 

seed_val=42

random.seed(seed_val)
np.random.seed(seed_val)
torch.manual_seed(seed_val)
torch.cuda.manual_seed_all(seed_val)

##################################################################
#                        TRAINING                                #
##################################################################     

# loss_values=[]

training_stats = []
for epoch_i in range(0,epochs):

  print("****Epoch {:} /{:} ******".format(epoch_i+1,epochs))
  print("Training...")

  t0=time.time()
  total_loss=0

  model.train()


  for step,batch in enumerate(train_dataloader):
    if step%100==0 and not step==0:
      elapsed=format_time(time.time()-t0)
      print(" Batch {:>5,} of {:>5,}. Elapsed: {:}".format(step,len(train_dataloader),elapsed))

    b_input_ids=batch[0].to(device)
    b_input_mask=batch[1].to(device)
    b_labels=batch[2].to(device)
   

    model.zero_grad()
    # outputs=model(b_input_ids,
    #               token_type_ids=None,
    #               # attention_masks=b_input_mask,
    #               labels=b_labels
    #               )
    
    loss, logits = model(b_input_ids,
                                  token_type_ids=None, 
                                  attention_mask=b_input_mask,
                                  labels=b_labels
                           )

  
    total_loss +=loss.item()
    loss.backward()

    torch.nn.utils.clip_grad_norm(model.parameters(),1.0)
    optimizer.step()
    scheduler.step()

  avg_train_loss=total_loss/len(train_dataloader)

  
  print("")
  print(" Average training loss :{0:.2f}".format(avg_train_loss))
  print("Training epoch took {:}".format(format_time(time.time()-t0)))
  training_time = format_time(time.time() - t0)



##################################################################
#                        VALIDATION                                #
##################################################################     

  print("")
  print("Runing Validation ...")

  t0=time.time()
  model.eval()

  total_eval_loss,eval_accuracy=0,0
  nb_eval_steps,nb_eval_examples=0,0

  for batch in validation_dataloader:

    batch=tuple(t.to(device) for t in batch)

    b_input_ids,b_input_mask,b_labels=batch

    with torch.no_grad():
    #   outputs=model(b_input_ids,
    #                 token_type_ids=None,
    #                 # attention_masks=b_input_mask
    #                 )
    # logits=outputs[0]
      loss, logits = model(b_input_ids, 
                                token_type_ids=None, 
                                attention_mask=b_input_mask,
                                labels=b_labels)


      total_eval_loss += loss.item()
    #Move to cpu

    logits=logits.detach().cpu().numpy()
    label_ids=b_labels.to('cpu').numpy()


    # # Accuracy of this batch 
    tmp_eval_accuracy=flat_accuracy(logits,label_ids)
    eval_accuracy+=tmp_eval_accuracy
    nb_eval_steps+=1
    
  print("  Accuracy: {0:.2f}".format(eval_accuracy/nb_eval_steps)) 
  print("  Validation took:{:}".format(format_time(time.time()- t0)))
  avg_val_loss = total_eval_loss / len(validation_dataloader)
  print(" Average validation loss :{0:.2f}".format(avg_val_loss))

  avg_val_accuracy = eval_accuracy / len(validation_dataloader)
  validation_time = format_time(time.time() - t0)
  


  training_stats.append(
      {
          'epoch': epoch_i + 1,
          'Training Loss': avg_train_loss,
          'Valid. Loss': avg_val_loss,
          'Valid. Accur.': avg_val_accuracy,
          'Training Time': training_time,
          'Validation Time': validation_time
      }
  )

  
print("")   
print("Training completed!")

И я поместите результаты в CSV для отправки следующим образом

predictions=predictions[:,1]
predictions[predictions>0]=0
predictions[predictions<0]=1
predictions=predictions.astype(np.int64)

sample_submission=pd.read_csv('sample_submission.csv',sep=',',index_col=0)
sample_submission["target"]=predictions
sample_submission.head()

to_submit=sample_submission.to_csv("submission.csv",index=True)

Кривые обучения

...