UNI-DTHON 2021 대회에서 시도하지 못한 것들에 아쉬움이 남아 추가적으로 공부하였다. AWS(Amazon Web Service)와 GCP(Google Cloud Platform) 모두 무료 크레딧을 제공하여 어느 서비스를 사용할지 고민하였는데 UI가 깔끔해 보이고 더 많은 크레딧을 제공하는 GCP를 선택하였다. GCP는 Vertex AI Workbench 사용자 관리 노트북 인스턴스를 제공하는데 이를 이용하면 빠르게 Jupyterlab으로 사전 패키징 된 VM 인스턴스를 만들 수 있다. 또한 노트북에 딥러닝 패키지 모음(Tensorflow 및 Pytorch 프레임워크 등)이 사전 설치되어 있어 개발 환경설정에 용이하다. GCP에서 공부를 하고 싶다면 노트북 인스턴스를 이용하는 것을 추천한다!
인스턴스 사양은 다음과 같다
CPU : 4 vCPUs
RAM :15GB
GPU : NVIDIA Tesla K80 x1
메모리 사용량 증가 이슈 해결
Colab으로 대회를 진행했을 때 모델을 학습하는 동안 계속해서 RAM 사용량이 증가하였다. 다행히 데이터의 크기가 작아(7500개) 메모리 초과로 학습이 멈추는 일은 발생하지 않았었다. 하지만 모델 학습 중에 계속해서 메모리 사용량이 증가하는 것은 문제가 있는 것으로 이번에는 이 문제를 해결해야 했다. 원래 모델 학습 중 메모리 사용량은 batch size x (1 training data size) 정도로 일정하게 유지되어야 한다. 계속해서 메모리 사용량이 증가하는 것은 학습 데이터가 메모리에 저장되고 있다는 뜻이다. 다음은 이미지와 라벨 데이터를 불러오는 Custom Dataset 클래스 코드이다. 어느 코드가 메모리 사용량에 영향을 주고 있을까?
class FoodDataset(Dataset):
def __getitem__(self, idx):
if not idx in self.samples.keys():
img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
img_path = img_path.replace('\\', '/')
# image 불러오기
image = Image.open(img_path).convert('RGB')
# label 불러오기
label = self.img_labels.iloc[idx, 1]
self.samples[idx] = (image, label)
return self.samples[idx]
바로 self.samples[ idx ] = (image, label) 이다. 각각의 인덱스에 해당하는 image와 label을 모두 저장하고 있으니 메모리 사용량이 계속해서 증가하는 것이었다. 이를 수정하여 메모리 문제를 해결할 수 있었다.
모델 학습 속도 높이기
학습 데이터 로드 시간, 순전파 + 역전파에 걸리는 시간을 측정한 결과 모델 학습을 하는데 학습 데이터 로드에 상당한 시간이 걸린다는 것을 알 수 있었다. DataLoader가 더 빠르게 작동하기 위해서는 1) 이미지를 더 빠르게 로드하고, 2) 이미지 어그멘테이션을 더 빠르게 해야 하며, 3) 더 많은 CPU가 데이터 로드에 참여해야 한다. 이를 위해 다음과 같은 방법을 사용하였다.
- Image.open → cv2.imread
- transforms library → Albumentation library
- num_workers = 1 → num_workers = 4
이 중 num_workers의 개수를 변경한 것이 학습 속도에 영향을 주었다. 각 배치마다의 학습 속도가 대략 30초 정도 감소하였다! 다만 OpenCV와 Albumentation 라이브러리는 학습 속도 향상에 별다른 영향이 없었다. 주의해야 할 것은 num_workers의 개수를 올릴수록 계속해서 학습 속도가 향상된다는 것은 아니라는 것이다!
모델 정확도 높이기
모델의 정확도를 높이기 위해 시도한 방법은 다음과 같다.
1. Training Data Size
대회에서는 학습 데이터의 사이즈가 크지 않았음에도 모델 학습 시간이 너무 오래 걸려서 150개의 각 label당 50개의 이미지 데이터를 뽑아 총 7500개의 데이터로밖에 학습을 진행하지 못했다. 이번에는 150 x 50, 150 x 70, 150 x 100, 150 x 200, 150 x 500개의 데이터로 사이즈를 늘려가면서 모델을 학습하였는데, 뒤에 서술할 어떠한 방법보다 모델 정확도 향상에 많은 영향을 끼친 것을 알 수 있었다.
2. Backbone Model 변경
이미지 분류에서 매우 좋은 성능을 보이는 EfficientNet을 pretrained model로 사용하였다. 대회에서는 학습 시간을 고려하여 EfficientNet-b0 모델을 사용하였는데 이번 프로젝트에서 EfficientNet-b1 모델로 변경 후 모델의 정확도가 0.03 높아진 것을 확인하였다. 대회와 이번 프로젝트 둘다 모델 전체를 학습하는 fine-tuning을 진행하였는데 대회에서는 학습 데이터의 사이즈가 작아 FC layer만 학습시켰으면 어땠을까라는 생각이 들었다.
3. Data Augmentation
Albumentation 라이브러리의 CenterCrop, RandomRotation, HorizontalFlip, Cutout, GaussianBlur 등 다양한 어그멘테이션 함수를 사용하였다. 결과적으로 데이터 어그멘테이션으로 인한 정확도 향상 효과를 보지 못했다. 데이터 어그멘테이션 기법 중 이미지 분류에서 좋은 성능을 보여주는 Cutmix를 썼으면 정확도가 높아졌을까 궁금해졌다.
4. Batch Size
batch size를 16, 32, 64로 설정하고 모델의 정확도를 측정하였다. 그 결과 batch size가 64, 32, 16순으로 정확도가 높았고 16과 비교했을 때 각각 0.01, 0.02씩 정확도가 상승하였다. 또한 모델 학습 속도 향상에도 영향을 미친다는 것을 확인하였다. 확실히 batch size는 실제 모델 학습시 중요한 하이퍼 파라미터 중 하나이다!
추론 정확도 높이기
Model Ensemble을 통해 추론 정확도를 0.04 높였다. EfficientNet-b0, b1을 기반으로 모델을 각각 학습하여 추론할 때 두 개의 모델을 로드하였다. 그리고 각 label별로 모델들이 예측한 확률을 합산하여 가장 확률이 높은 label을 선택하는 soft voting을 적용한 결과이다. 또한 TTA(Test Time Augmentation) 기법을 통해 추론 정확도를 높일 수 있었다. 1개의 이미지를 transform을 통해 8개의 이미지로 늘려서 추론을 진행하고 가장 많이 나온 클래스가 예측값으로 결정되는 메커니즘이다. 정확도를 높이기 위해서는 tta 기법을 적용하는 것이 좋다고 생각한다.
대회 때와 비교해보면 추론 시간은 동일하지만 정확도가 0.838에서 0.908로 증가하였다! 대회 때의 정확도보다 조금만 높여보자며 프로젝트를 진행하였는데 생각했던 것보다 더 높인 것 같아 만족스럽다.
느낀 점
딥러닝과 관련된 기법을 많이 알게 되었다. Transfer Learning, Data Augmentation, Grid Search, Model Ensemble, TTA 등 다양한 기법을 배우고 적용하였다. 2020 AI RUSH에서 모델 앙상블도 몰라서 헤매던 때를 생각해보면 성장한 것 같다. 아직도 많이 부족하지만..! 그때부터 거의 2년이 지났는데 이 정도밖에 성장하지 못했다는 것에 더 반성하게 되었다. 군대에서 공부 열심히 하려고 했는데.. 지금이라도 전역 전까지 불태워야겠다!!
요즘은 데이터 사이언티스트의 역량에 대해 공부하고 있는데 물론 머신러닝, 딥러닝 스킬도 중요하지만 비즈니스, 데이터 분석 역량이 매우 중요하다는 사실을 깨달았다. 또한 SOTA 모델과 같은 복잡한 모델들은 실무에서 사용하기 힘들다는 이야기를 듣고 지금 중요한 것은 딥러닝이 아니라는 사실을 알았다. 그래서 비즈니스, 데이터 분석 역량을 높일 수 있는 공부를 시작하려고 한다. 그리고 머신러닝, 딥러닝의 기초가 부족하다고 생각하여 기초부터 다시 공부할 생각이다. 서두르지 말고 기초부터 천천히 쌓아올리도록 노력해야겠다!
'머신러닝 · 딥러닝' 카테고리의 다른 글
[UNI-DTHON 2021] 후기 (0) | 2021.12.09 |
---|
댓글