저는 이번 대회에 loss에 대해 적용습니다.
결론은 전처리 조금(entity marker punct + 한글 ner + 특수문자 보정 및 사우디 등의 언어 삭제)에 3 epoch 시, focal loss 사용 했을 경우에 성능 증가!
But! 전처리 기법 3가지 다 적용 & epoch 3 했을 시, focal loss나 label smooth loss 사용하니 안 할 때보다 성능이 조금 떨어졌습니다!
우선, Focal loss와 LabelSmoothing에 대해 코드로 보면서 알아보기 -> Focal loss LabelSmoothing를 Trainer에 적용한 코드 설명 -> Focal loss와 LabelSmoothing loss 적용 시 결과 순서로 말씀드리겠습니다!
0. Focal loss와 Label Smoothing loss 시도는 왜 했니?
Focal loss는 실제 class 분포를 보면 불균형이 심한 것을 알 수 있기에 시도!
label smoothing loss는 유사한 의미를 갖는 class가 많다고 생각하여 경계를 살짝살짝 흐트러 트리기 위해서 사용!
1. Focal loss와 Label Smoothing loss 코드
1-1. Focal loss 코드
Focal loss는 우선 Cross Entropy를 변형한 식으로 class 불균형에 효과를 주고 있습니다.
(1−p_t) ^γ 부분이 쉬운 예시에서는 down scaling을 하여 어려운 예시에 집중합니다. => 잘 분류되는 예시를 down scaling해줍니다.
이 값들로 F.nll_loss로 Cross Entropy 역할을 수행하여 예측값 "((1 - prob) * self.gamma) log_prob", 실제값 target_tensor로 loss값 계산을 수행합니다! (F.nll_loss와 torch.nn.CrossEntropyLoss()의 차이는 예측값을 받을 때 다릅니다!)
CrossEntropyLoss()는 그냥 입력값 가능!
F.nll_loss는 입력값에 log_softmax를 취한 값!
F.nll_loss의 weight와 reduction은 기본이 None과 mean입니다!
1-2. LabelSmoothingLoss 코드
LabelSmoothingLoss는 hard target([0,1,0,0])을 soft target([0.025, 0.925,0.025,0.025])으로 변경하여 mislabeling 된 데이터를 고려하고 모델 정규화에 도움을 줍니다!
ex) label 0과1이 있는데 label 1이 있다고 100% 확신한다면 반드시 그렇지 않다고 생각하게 해줍니다!
labelsmoothing loss 식
labelsmoothing loss는 Cross Entropy 변형 식입니다!
원래 Cross entropy 식!
labelsmoothingloss에는 원래 Cross entropy 식의 y(k) 대신 y(k)' 넣을 예정!
이렇게 위에서 짠 loss들을 아래와 같이 dictionary로 불러오면 class를 가져올 수 있게 했습니다!
criterion = {'label_smoothing': LabelSmoothingLoss, 'focal_loss': FocalLoss}
## 원하는 criterion loss 사용!
def use_criterion(criterion_n, **kwargs):
choose_criterion=criterion[criterion_n]
return choose_criterion(**kwargs)
train.py의 MultilabelTrainer class
HuggingFace 문서를 참고하여 원하는 argument로 받아 criterion loss를 가져올 수 있게 했습니다!
parser.add_argument("--criterion", type=str, default='default', help='criterion type: label_smoothing, focal_loss')
#https://huggingface.co/transformers/main_classes/trainer.html
class MultilabelTrainer(Trainer):
# Trainer상속을 통한 loss 재정의하는 class!
def compute_loss(self, model, inputs, return_outputs=False):
labels = inputs.pop("labels") # "labels" in inputs 기능으로 label 가져오기!
outputs = model(**inputs) # input으로 모델이 예측!
logits = outputs.logits # model 결과값
loss_fn = use_criterion(args.criterion)
loss = loss_fn(logits, labels)
return (loss, outputs) if return_outputs else loss
train.py의 Trainer
loss를 원래 것을 쓰고 싶다면 args.criterion의 default 값으로 --criterion을 선언 안 하여 원래 Trainer를 사용하고 원하는 loss를 사용하고 싶을 때, --criterion에 loss fucntion 이름을 적어 MultilabelTrainer를 사용합니다!
if args.criterion=='default':
trainer = Trainer(
# the instantiated 🤗 Transformers model to be trained
model=model,
args=training_args, # training arguments, defined above
train_dataset=RE_train_dataset, # training dataset
eval_dataset=RE_dev_dataset, # evaluation dataset
compute_metrics=compute_metrics, # define metrics function
#data_collator=dynamic_padding,
tokenizer=tokenizer,
)
else:
trainer = MultilabelTrainer(
# the instantiated 🤗 Transformers model to be trained
model=model,
args=training_args, # training arguments, defined above
train_dataset=RE_train_dataset, # training dataset
eval_dataset=RE_dev_dataset, # evaluation dataset
compute_metrics=compute_metrics, # define metrics function
#data_collator=dynamic_padding,
tokenizer=tokenizer,
)
3. Focal loss와 LabelSmoothing loss 적용 시 결과
적은 전처리와 Focal loss 유무 결과
위의 조건은 entitiy marker (punct) + k_fold 5 + ner(한국어 변형) + 특수문자 보정 및 사우디어, 독일어 삭제는 공통이고 focal loss 유무 결과로 2개 결과 중, 위에 결과가 focal loss 적용한 것으로 조금 더 성능이 올랐습니다!
focal loss 유무 loss 변화를 보면, focal loss가 있을 때, 조금 더 안정적으로 loss가 줄어듭니다!
3가지 전처리와 Focal loss와 LabelSmoothing loss 결과
형광색 칠한 결과 중, 맨 위의 결과가 기본 loss 쓴 결과로 제일 높고 그 다움 형광색 결과는 labelSmoothing, 맨 아래는 focal loss 결과입니다!
micro f1 score 결과로 labelsmoothing loss 결과 > 기본 loss > focal loss 결과 순으로 높습니다!
label smoothin loss가 값이 다른 거에 비해 월등히 높은데 찾아보니 loss값 높은 것은 신경 안 쓰셔도 되고 loss 값이 얼마나 안정적으로 떨어지냐가 중요한 것 같습니다!
그래서 보시면 확실히 기본 loss보다는 2개의 loss가 안정적으로 떨어짐을 알 수 있습니다!
4. 향후 방향
label smoothing과 focal loss 둘 다, 예측하는데 hard를 soft하게 변형시키므로 좀 더 epoch 늘릴 때, 유능할 것 같습니다! (저희 5 epoch 시, overfitting이 일어남을 보아 5 epoch 이상 시, 사용하면 좋을 수 있을 것 같습니다.)
추가로 지금 label smoothing loss에서 smoothing을 0.1이나 0.2로 줄여도 될 것 같습니다!
저는 이번 대회에 loss에 대해 적용습니다. 결론은 전처리 조금(entity marker punct + 한글 ner + 특수문자 보정 및 사우디 등의 언어 삭제)에 3 epoch 시, focal loss 사용 했을 경우에 성능 증가!
But! 전처리 기법 3가지 다 적용 & epoch 3 했을 시, focal loss나 label smooth loss 사용하니 안 할 때보다 성능이 조금 떨어졌습니다!
우선, Focal loss와 LabelSmoothing에 대해 코드로 보면서 알아보기 -> Focal loss LabelSmoothing를 Trainer에 적용한 코드 설명 -> Focal loss와 LabelSmoothing loss 적용 시 결과 순서로 말씀드리겠습니다!
0. Focal loss와 Label Smoothing loss 시도는 왜 했니?
1. Focal loss와 Label Smoothing loss 코드
1-1. Focal loss 코드
Focal loss는 우선 Cross Entropy를 변형한 식으로 class 불균형에 효과를 주고 있습니다. (1−p_t) ^γ 부분이 쉬운 예시에서는 down scaling을 하여 어려운 예시에 집중합니다. => 잘 분류되는 예시를 down scaling해줍니다.
Focal loss 식
Focal loss 코드
F.log_softmax(input_tensor,dim=-1) => log(p_t) torch.exp(log_prob) => p_t
이 값들로 F.nll_loss로 Cross Entropy 역할을 수행하여 예측값 "((1 - prob) * self.gamma) log_prob", 실제값 target_tensor로 loss값 계산을 수행합니다! (F.nll_loss와 torch.nn.CrossEntropyLoss()의 차이는 예측값을 받을 때 다릅니다!)
F.nll_loss의 weight와 reduction은 기본이 None과 mean입니다!
1-2. LabelSmoothingLoss 코드
LabelSmoothingLoss는 hard target([0,1,0,0])을 soft target([0.025, 0.925,0.025,0.025])으로 변경하여 mislabeling 된 데이터를 고려하고 모델 정규화에 도움을 줍니다!
ex) label 0과1이 있는데 label 1이 있다고 100% 확신한다면 반드시 그렇지 않다고 생각하게 해줍니다!
labelsmoothing loss 식
labelsmoothing loss는 Cross Entropy 변형 식입니다!
원래 Cross entropy 식!
labelsmoothingloss에는 원래 Cross entropy 식의 y(k) 대신 y(k)' 넣을 예정!
labelsmoothing loss code
target 부분에 (1-알파)를 넣습니다!
2. Trainer 적용 코드!
이렇게 위에서 짠 loss들을 아래와 같이 dictionary로 불러오면 class를 가져올 수 있게 했습니다!
HuggingFace 문서를 참고하여 원하는 argument로 받아 criterion loss를 가져올 수 있게 했습니다!
loss를 원래 것을 쓰고 싶다면 args.criterion의 default 값으로 --criterion을 선언 안 하여 원래 Trainer를 사용하고 원하는 loss를 사용하고 싶을 때, --criterion에 loss fucntion 이름을 적어 MultilabelTrainer를 사용합니다!
3. Focal loss와 LabelSmoothing loss 적용 시 결과
적은 전처리와 Focal loss 유무 결과
위의 조건은 entitiy marker (punct) + k_fold 5 + ner(한국어 변형) + 특수문자 보정 및 사우디어, 독일어 삭제는 공통이고 focal loss 유무 결과로 2개 결과 중, 위에 결과가 focal loss 적용한 것으로 조금 더 성능이 올랐습니다!
focal loss 유무 loss 변화를 보면, focal loss가 있을 때, 조금 더 안정적으로 loss가 줄어듭니다!
3가지 전처리와 Focal loss와 LabelSmoothing loss 결과
형광색 칠한 결과 중, 맨 위의 결과가 기본 loss 쓴 결과로 제일 높고 그 다움 형광색 결과는 labelSmoothing, 맨 아래는 focal loss 결과입니다!
micro f1 score 결과로 labelsmoothing loss 결과 > 기본 loss > focal loss 결과 순으로 높습니다!
label smoothin loss가 값이 다른 거에 비해 월등히 높은데 찾아보니 loss값 높은 것은 신경 안 쓰셔도 되고 loss 값이 얼마나 안정적으로 떨어지냐가 중요한 것 같습니다!
그래서 보시면 확실히 기본 loss보다는 2개의 loss가 안정적으로 떨어짐을 알 수 있습니다!
4. 향후 방향
label smoothing과 focal loss 둘 다, 예측하는데 hard를 soft하게 변형시키므로 좀 더 epoch 늘릴 때, 유능할 것 같습니다! (저희 5 epoch 시, overfitting이 일어남을 보아 5 epoch 이상 시, 사용하면 좋을 수 있을 것 같습니다.)
추가로 지금 label smoothing loss에서 smoothing을 0.1이나 0.2로 줄여도 될 것 같습니다!
이상입니다! 봐주셔서 감사합니다!