728x90
Problem Definition
- 카메라로 촬영한 사람 얼굴 이미지의 마스크 착용 여부를 판단
- 입력되는 이미지는 모두 정면을 바라보고 있으며 아시아인 남녀로 구성되고 20대부터 70대까지 연령층이 다양함
- 마스크 착용, 이상하게 착용, 미착용의 분류와 나이(젊은층, 중년층, 노년층), 성별까지 종합한 총 18개의 label를 분류하여 출력
- 이미지 데이터의 특성상 해당 분류 문제는 카메라를 정면을 바라봐야하고 촬영되는 사람도 카메라 화면상 중앙에 위치해야 성립
- 얼굴이 일부 보이는 마스크(투명한 마스크)일 경우와 사람이 얼굴이 프린트된 마스크일 경우와 같은 이미지일 경우 제대로 인식하는가에 대한 문제가 발생
EDA
- 데이터의 불균형 확인을 위해 feature, label별 분포확인
- Normalize의 mean과 std값을 지정해주기위해 이미지의 RGB 통계량을 계산
- opencv의 haar cascasde를 사용하여 이미지상 사람의 얼굴을 인식하는 방법을 적용하였지만 몇몇 이미지들은 인식을 잘 못하는 경우가 발생
- 이미지를 시각화하여 잘못된 label이 있는지 확인
Image Data
- 상황
- 대부분의 이미지에서 얼굴 부분을 제외한 나머지 불필요한 정보가 존재
- opencv의 haar cascasde를 사용하여도 얼굴을 제대로 인식하지 못하는 경우가 발생
- 해결방안
- facenet_pytorch의 MTCNN을 사용하여 face를 detection하였지만 여전히 인식을 못하는 이미지가 생겨 retinaface도 활용하여 face만 crop함
Dataset
- 상황 : train set과 validation set 둘 다 같은 id(사람)를 가지는 이미지가 들어감으로서 overfitting의 위험이 발생
- 가설 : 사람을 기준으로 구분하여 train set과 validation set에 같은 사람이 들어가지 않게함으로서 overfitting의 위험을 줄일 수 있을 것임
- 결과 : 사람을 기준으로 구분한 dataset을사용했을 때 validation score가 이미지를 기준으로 구분한 dataset의 validation score보다 작게 나오고 리더보드 점수는 비슷하게 나오는 결과로 overfitting의 위험이 줄어들었다고 판단
- 정리 : 그저 train set과 validation set을 구분한다는 생각보다 구분되는 데이터들이 어떻게 모델 학습에 영향이 갈지에 대해 조금 더 구체적으로 생각하게 되었음
Data Imbalance
- 상황
- 중년층(30, 40, 50대)이 젊은층(20대 이하)와 노년층(60대)보다 상대적으로 많음
- male보다 female 데이터가 좀 더 많이 분포되어있음
- label에 대한 분포를 확인했을 때 0, 1, 3, 4(마스크를 쓴 젊은층과 중년층)에 집중적으로 분포되어있음
- 마스크 착용 : 이상하게 착용 : 미착용 = 5 : 1 : 1
- 가설 : 상대적으로 많이 분포되어있는 중년층 중에서 55세 이상 60세 미만의 데이터를 가장 적게 분포되어있는 60세로 label을 바꿔줌으로서 데이터 불균형의 문제를 조금 해결할 수 있을 것임
- 결과 : 10% 단위로 50%까지 실험한 결과 비중이 높을수록 validation score가 더 낮아지는 그래프가 그려졌고 50%를 바꾸었을 때의 inference 제출시 리더보드 점수가 상승함
- 정리
- 중년층 중 일부를 노년층으로 바꿔주면서 overfitting의 위험을 줄일 수 있었지만 해당 프로젝트의 목적(다양한 기법들을 사용한 모델 성능 향상 등)과 벗어난다고 판단
- 이처럼 데이터의 일부를 다른 label로 옮기거나 외부 데이터로 데이터 불균형을 보완할 수 있을 것이라는 생각보다 generalization을 통해 성능 향상을 꾀하는 것이 효율적이라고 생각함
Data Augmentation
[#1]
- 상황 : 이미지를 육안으로 확인했을 때 밝기, 인물의 위치, 원근감, 머리카락의 유무, 안경 착용의 유무 등 다양함
- 가설 : RandomBrightness, RandomPerspective, GaussianBlur, Grayscale와 같은 기법들을 사용하여 밝기, 원근감, 마스크 색깔 등을 보완할 수 있을 것임
- 결과 : augmentation을 하지않았을 때와 미미한 차이를 보여줌
- 정리 : 랜덤하게 선택된 이미지들에게 augmentation을 적용했을 때 수가 상대적으로 많은 마스크 착용 이미지들에게도 적용됨 → 데이터 수가 적은 부분에 augmentation을 적용하여 부족한 부분을 채워야하지만 데이터 수가 많은 부분과 데이터 수가 적은 부분 모두에 augmentation을 적용이되어 점수 차이에 영향이 없었던 것이라 생각함
[#2]
- 상황 : 여러 모델을 사용하여 학습을 하였을때 데이터 불균형에 따른 overfitting 문제가 발생
- 가설
- 데이터가 비교적 많이 분포한 중년층 중에서 마스크를 착용한 이미지에 cutmix를 사용하여 generalization이 적용됨으로서 overfitting의 위험을 낮추어줄 것임
- 이미지의 왼쪽 반과 오른쪽 반을 섞는 방식의 cutmix를 사용함으로서 학습시 generalization 적용이 가능해질 것임
- 결과
- resnet50을 사용하고 cutmix를 마스크 쓴 중년층에 30% 적용했을 때 f1 score가 약 0.1이 상승
- efficientnet_b7과 resnet152와 같이 좀 더 레이어가 깊은 모델의 경우 마스크 쓴 중년층과 젊은층 모두에게 적용하여 좀 더 높은 점수를 보여줌
- 정리
- resnet50과 같이 레이어가 깊지않은 모델의 경우에도 generalization을 적용하여 충분히 좋은 결과를 얻을 수 있다고 생각함
- efficientnet_b7과 resnet152는 resnet50보다 레이어가 깊기 때문에 overfitting의 위험 또한 높아지기 때문에 generalization을 적용하는 비중을 높여서 성능 향상에 도움을 주었다고 판단
[#3]
- 상황 : 하나의 모델을 사용하여 augmentation을 적용했을 때 성능 차이를 확인
- 가설 : 고정된 hyperparameter(batch size, lr, epoch, loss, optimizer, weight decay, lr_scheduler, earlystopping-patience)과 고정된 random seed, requires_grad=False를 적용하고 augmentation만을 추가 & 수정한다면 얼마나 성능 차이가 있을지 확인할 수 있을 것임
- 결과 : 성능 차이가 거의 나지 않았음
- 정리
- pre-train된 모델에 backpropagation이 안될때 augmentation을 적용한 데이터에 맞게 학습이 되지않아 실질적으로 성능 차이를 확인할 수 없다고 생각함
- trainsfer learning을 수행할 때 backpropagation의 수행 여부에 따라 성능 차이 확인에 어떠한 영향을 주는가에 대한 판단이 힘들었음
Optimizer & Loss
- 상황 : 학습시 overfitting이 일어나고 제출 점수 기준이 f1 loss임
- 가설
- 기존의 adam보다 generalization 능력이 더 좋은 adamw를 사용하여 overfitting의 위험을 낮출 것임
- 기존의 crossentropy loss를 사용하는 것보다 f1 loss를 사용하여 조금 더 정확한 성능 판단을 할 수 있을 것임
- 결과 & 정리
- adamw의 경우 weight decay를 조절하며 generalization 성능을 끌어올릴 수 있었다고 판단
- f1 loss을 사용하게되면서 리더보드 점수와의 차이를 알 수 있었고 모델의 성능 차이를 확인할 수 있는 지표가 되었다고 판단
Early Stopping
[#1]
- 상황 : 성능 향상이 없음에도 지정한 epoch 만큼 학습이 수행됨
- 해결방안 : Early Stopping 기법을 적용하여 학습시 patience 만큼 성능 향상이 없으면 중단
[#2]
- 상황
- 주어진 patience 이후에도 성능 향상의 여지가 있었음에도 학습이 중단되는 문제 발생
- 1 epoch 차이임에도 제출시 점수 차이가 많이나는 문제 발생
- 해결방안 : 20 epoch를 지정하고 5 epoch 이후부터 각 epoch마다 checkpoint를 저장하고 WandB를 사용하여 그려진 그래프를 통해 최종 inference할 checkpoint를 선택
TTA(Test Time Augmentation)
- Test를 할 때에도 augmentation을 적용시켜 더 다양한 시야와 각도로 본 이미지를 inference함으로서 score 향상에 기여하는 기법
- 여러 개의 augmentation을 적용하여 각 확률 값을 합하거나 평균을 구하는 등의 방법을 통해 최종 예측 값을 도출하는 기법을 사용해보았으며 score 향상에 조금 도움됨
- augmentation을 지나치게 많이 주게되면 오히려 score가 하락하는 문제가 있기때문에 많은 실험과 검증을 통해 최적의 augmentation을 찾는 것이 좋겠지만 성능 차이에 영향이 크지 않아 후반에 사용하는 것이 좋을 것이라 생각함
아쉬웠던 점
- 이번 프로젝트를 진행하면서 코드에 실수가 많았다. 급한 마음에 코드를 꼼꼼히 보지 못하고 진행했던 탓이 컸던 것 같다.
- 대부분의 시간을 augmentation과 cutmix 적용에 사용하여 앙상블과 같은 다양한 기법들을 사용하지 못했던 것이 아쉽다.
- 모델을 실행하는데 시간이 오래걸리는 문제가 발생하여 시간복잡도에 대한 생각과 gpu 사용에 대한 지식이 필요하다고 느꼈다.
- 토론게시판을 이용하려 생각은 하지만 어떤 부분을 공유해야할지에 대한 고민과 불확실성때문에 참여도가 부족했었다. 다름 프로젝트에서는 토론게시판에 참여하려는 노력에 힘써야겠다.
- shell script를 사용하여 계획적으로 모델을 실행하는 시도를 못해본 것이 아쉬웠다. 모델이 실행되고 에러가 발생했을 때 눈치채기 전까지는 그 시간을 버리는 것이기 때문에 shell script를 사용을 꺼렸던 것 같다. 하지만 익숙해지면 좀 더 효율적으로 진행할 수 있을 것이라 생각하기에 사용해봐야겠다.
- 해당 모델이 어떠한 부분을 예측하고 못하는지에 대한 시각화 또는 지표에대한 공부가 더 필요하다는 것을 느꼈다. 모델을 어떠한 방향으로 개선해야할 지에 대한 방향성을 찾는 것이 중요한 것 같다.
새롭게 시도했거나 어려웠던 점
- 데이터 불균형으로 인한 overfitting을 해결하는 것이 가장 어렵다고 느꼈다. overfitting을 판단하는 기준이나 지표조차 정확하게 정할 수 없다는 것이 문제였던 것 같다.
- jupyter notebook에서 수행하던 것을 OOP를 통해 python file 로 대부분의 기능을 클래스와 함수로 구현하였다. 이렇게 여러 python file으로 나누어 구현함으로서 코드의 가용성을 늘리고 유지보수를 줄일 수 있는 효과를 얻게 되었다.
- overfitting의 위험을 낮추기위해 가장 대표적인 cutmix 기법을 사용해보았지만 처음에는 제대로된 적용법을 모르고 실수를 여러번 거치게되었다. 예를 들어 validation set에는 적용하지 않아야하는데 적용했거나 loss 계산을 수정하지 않았던 점 등이 발생하게 되었다. 이 경험을 통해 다음부터는 제대로된 적용법을 숙지하여 불필요한 작업을 최소화할 수 있는 방향으로 진행할 수 있게 노력해야겠다.
- 레이어의 깊이가 적은 모델을 사용했을 때 성능 향상에 도움이 되었던 augmentation이 레이어의 깊이가 깊은 모델에 적용했을 때 성능이 오히려 떨어지는 문제가 있었다. 레이어가 깊을수록 overfitting의 위험이 커지기 때문에 적용되는 augmentation의 비중 또한 높여가며 다시 맞춰가야한다는 것이 어렵다고 느꼈고 이렇게 진행하는 것이 맞는지에 대한 의문도 들었다.
최종 결과
- 모델 : Resnet50
- hyperparameter : learing_rate : 1e-5, train_batch_size : 32, validation_batch_size : 16, epochs : 14, weight_decay : 20
- augmentation : Resize(224, 224), Normalize, ToTensor, Cutmix(마스크 쓴 중년층 30%)
- optimizer & loss : AdamW, F1_loss
- 결과
- public 데이터셋 리더보드 점수 = 0.721, private 데이터셋 리더보드 점수 = 0.728
- 0.721 → 0.728로 소폭 상승
- 최종 점수로는 팀 제출에서 가장 높은 점수를 달성
- 정리 : 레이어가 깊고 parameter의 수가 많은 모델이 아니더라도 충분히 overfitting의 위험을 낮추고 성능을 향상시킬 수 있었다. 이렇게 하나의 모델로 성능 향상에대해 고민하고 적용해보았던 것이 다음 프로젝트에서도 도움이 될 수 있을 것이라 생각한다.
728x90
'Boostcamp AI Tech' 카테고리의 다른 글
[Boostcamp Day-26] Computer Vision - Annotation, Data Efficient Learning (0) | 2021.09.08 |
---|---|
[Boostcamp Day-25] Computer Vision - Image Classification 1 (0) | 2021.09.06 |
[실험 일지 작성_목] Image Classification (0) | 2021.09.02 |
[실험 일지 작성_수] Image Classification (0) | 2021.09.01 |
[실험 일지 작성_화] Image Classification (0) | 2021.09.01 |