일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 네부캠
- 스케치데이터셋
- Aimers
- 스케치이미지
- zero-shot classification
- 네이버 부스트캠프
- 머신러닝 사이클
- 학습장
- 회귀모델
- 네이버부스트 캠프
- dp
- 일기장
- object detection
- 타일링2
- 네이버부스트캠프
- 백준
- 다국어 ocr
- 부스트캠프
- 재활용 품목분류
- 11727번
- 객체탐지
- imageclassification
- 9095번
- 쓰레기분류
- pytorch
- 영수증 ocr
- Diffusion
- 모델평가지표
- 1149번
- 이미지분류
- Today
- Total
john8538 님의 블로그
Sketch 데이터셋을 활용한 Image Classfication 본문
본 내용은 네이버 부스트캠프 7기에서 진행한 첫번째 프로젝트 내용에 대해 정리한 내용입니다.
깃허브는 아래 주소를 참고해 주세요.
https://github.com/boostcampaitech7/level1-imageclassification-cv-05?tab=readme-ov-file
1. 소개
디지털 시대에 들어서면서 손으로 그린 스케치나 낙서를 인식하고 분류하는 기술의 중요성이 점점 더 커지고 있습니다. 스케치는 아이디어를 빠르게 표현하는 수단으로, 예술, 디자인, 엔지니어링 등 다양한 분야에서 널리 사용됩니다. 하지만 컴퓨터가 이러한 스케치를 이해하고 분류하는 것은 여전히 challenging한 과제입니다.
프로젝트 배경
본 프로젝트는 컴퓨터 비전(CV) 분야의 핵심 과제인 이미지 분류에 초점을 맞추고 있습니다. 이미지 분류는 주어진 이미지가 어떤 범주에 속하는지 자동으로 판단하는 기술로, 인공지능과 머신러닝의 발전과 함께 급속도로 발전하고 있습니다. 이미지 분류 Task 중 Image-Net에서 제공하는 Sketch 데이터셋을 일부 정재하여 주어진 스케치 이미지에 대해 이미지 분류하는것이 이번 프로젝트의 목표입니다.
프로젝트 목적
우리팀의 목표는 최신 딥러닝 모델들을 활용하여 높은 정확도의 스케치 이미지 분류 시스템을 개발하는 것입니다. 특히, 우리는 다음 두 가지 주요 모델에 초점을 맞췄습니다:
- CNN 아키텍처
- ViT (Vision Transformer) 기반 아키텍처
이 두 모델은 각각 다른 접근 방식을 사용하며, 우리는 이들의 성능을 비교하고 최적화하는 것을 목표로 삼았습니다.
이미지 분류의 중요성
스케치 이미지 분류 기술은 다양한 분야에서 혁신적인 응용을 가능하게 합니다:
- 디자인 및 창의 산업: 빠른 아이디어 스케치를 자동으로 카테고리화하고 관리
- 교육: 학생들의 그림을 자동으로 평가하고 피드백 제공
- UI/UX 디자인: 손으로 그린 와이어프레임을 인식하고 디지털화
- 게임 개발: 사용자가 그린 스케치를 게임 내 오브젝트로 변환
- 보안: 손으로 그린 서명이나 심볼을 인증 수단으로 활용
이러한 응용은 창의성을 높이고, 작업 효율성을 증대시키며, 인간-컴퓨터 상호작용을 더욱 직관적으로 만들 수 있습니다.
프로젝트의 도전과제
스케치 이미지 분류는 다음과 같은 특별한 도전과제를 가지고 있습니다:
- 스케치의 단순성: 스케치는 세부 정보가 부족하여 더 추상적입니다.
- 스타일의 다양성: 각 사람마다 그리는 스타일이 다르기 때문에 일관성이 떨어집니다.
- 노이즈와 불완전성: 손으로 그린 스케치는 종종 불완전하거나 노이즈를 포함합니다.
우리의 프로젝트는 이러한 도전과제를 극복하고, 더 나은 스케치 이미지 분류 모델을 개발하는 것을 목표로 하고 있습니다. 이를 통해 우리는 컴퓨터 비전 기술의 발전에 기여하고, 스케치를 활용한 새로운 응용 분야를 개척하고자 합니다.
2. 협업 구성
프로젝트를 시작하기에 앞서, 각자의 역할을 나누고 주어진 일을 진행하기로 결정하였습니다. 크게 나눈 부분은 Augmentation, github 관리, GPU서버 관리, EDA, 모델 Research 및 실험, 모델 학습코드 수정, wandb 실험 및 관리, 발표, 레포트 작성입니다. 전 이중에 모델 Resarch 및 실험과 전반적인 모델 실험부분, 발표를 담당하였습니다.
어떻게 하면 치우치지 않고 고르게 분배할지 의논하였으며 최종적으로는 이와같이 나누었습니다.
일정관리는 아래와 같이 잡았으며, 매주 2번씩 회의를 통해 진행사항을 공유하였습니다.
3. 데이터셋 구성
전반적인 데이터셋 이미지들은 다음과 같이 나타났습니다.
워터마크, 손글씨, 저작권 표시등 방해요소가 있는그림이 존재하였고, 정교한 그림부터 투박한 그림까지 다양한 분포가 이루어졌습니다. 간혹 컬러이미지가 섞여있는 경우가 있었으며, 대상피사체에 대한 스케치만 있는 것이 아닌 풍경이 포함된 그림도 존재하였습니다. 또한 대상이 여러개 포함된 이미지도 존재했으며, 클래스별로 이미지가 부족한 경우 피사체를 flip한 경우도 보였습니다.
크게 결측치는 나타나지 않았으며 500개의 클래스로 이루어진 Train, Test Sketch 데이터셋입니다.
이미지 가로세로 픽셀 수에 대한 비율이 어떻게 되는지 분포입니다.
이 부분에 대해서도 어떠한 이미지 사이즈를 적용하여 모델을 학습시킬지에 대해서도 의논을 진행하였습니다

4. 모델 선택
가장 초기 모델은 resnet과 ViT를 기반으로 진행하였으며 그 후 각 단일 모델의 성능을 최대로 끌어올려 앙상블을 진행하는 구조로 실험을 하였습니다. 이때의 앙상블은 Soft-Voting을 사용했습니다.
Hard-Voting 보다 Soft-Voting 성능이 잘 나옴을 확인하였으며, 시간이 부족한 관계로 다른 앙상블은 진행하지 못하였습니다.
Why resnet? ViT?
선택하게 된 이유는 다음과 같습니다.
Resnet은 지역적인 특징을 잘 포착하여 세부적인 선과 형태를 인식할 수 있고, Vit는 전체적 특징을 잘 포착하여 전체적인 구조와 배치를 이해할 수 있을 것이란 가설을 세웠기 때문입니다.
전반적인 Optimizer는 AdamW를 사용하였고, lr schedular는 ReduceLROnPlateau를 사용하였습니다.
그 결과는 0.81과 0.83이 나왔으며 이 둘을 앙상블 진행한 결과는 0.8640의 결과가 나왔습니다.
이로써 초기 가설 검증이 완료되었으며, 이를 기반으로 단일 최적모델을 실험하고, 앙상블을 비교하기로 계획하였습니다.
단일 모델을 찾는 과정에는 Image_Classification에 대한 리더보드를 주로 참고했습니다.
첫번째로 Paper with code에 있는 리더보드를 참고해 이를 기반으로 모델을 검색하고, 논문을 찾아보았으며,
두번째는 Hugging Face에 있는 Image_Classification 리더보드를 참고하여 여러 Task에서 성능이 좋은 각각 모델을 Search 하였습니다. Search 한 이후에는 각 모델에 대한 논문 탐색 및 구조 파악으로 어떠한 장점을 지니는지 공부해보는 시간도 가져보았습니다.
이렇게 Search 후 점차 한단계씩 밟아 나가기 시작했습니다.
기초 모델부터 리더보드에서 순위가 높았던 모델을 바탕으로 실험을 한결과,
정확도는 앞에 보이는 것과 같이 CNN아키텍처 를 지닌 convnext 기반 모델, ViT 아키텍쳐는 eva 모델이 높은 성능을 보임을 확인하였습니다. 각 모델에 대한 설명은 생략하도록 하겠습니다. 추후 왜 이러한 좋은 성능을 거둘 수 있었는지 간략하게 정리할 예정입니다.
각기 다른 이미지 크기로 학습된 모델들은 서로 다른 특성을 포착할 가능성이 높아 앙상블을 진행하게 되면 좋은 결과가 있을것이란 생각이 들어 CNN, ViT 각 모델들의 앙상블을 진행해보았습니다.
예상한 결과대로 단일 모델모다 높은 성능을 지님을 확인하였고, ViT에서는 시간이 부족해 가장 높은 단일 모델을 앙상블 하지는 못하였지만, 성능이 증가하는 모습을 확인할 수 있었습니다.
이때 Augmentation은 진행하지 않았으며 가장 기초적인 Baseline 코드에서 모델 코드부분만 일부 수정 후 실험을 진행하였습니다.
최종적으로 저희가 처음세웠던 가설인 CNN와 VIt 모델의 앙상블 결과가 기본 단일모델 모다 높게 나옴을 확인하였고, 가설검증을 완료하였습니다.
5. Augmentation
단순 모델 탐색으로만은 한계가 존재함을 확인하였습니다. 따라서 이미지 특성에 맞게 다양한 Augmentataion을 테스트해보고 실험하기로 결정하였습니다.
먼저 dataset을 분석해보았을때 같은 이미지에 augmentation만 취한듯한 스케치가 다수 존재함을 파악하였습니다.
따라서 실제 우리가 생각하는 것보다 unique한 train data는 적을 수 있을것이라 판단하였고 이와 유사한 특징이 test sketch image에서도 나타난다고 가정했을 때 이러한 특징을 반영하는 augmentation이 도움이 될 수 있다고 생각하였습니다.
또한 중간에 글씨가 들어가 있거나 스케치 자체가 지저분한 경우 등 noisy한 sketch가 다수 존재함을 확인해/Sketch 내에 target뿐만 아니라 다양한 배경과 다른 객체가 존재하는 경우가 있었으며 Sketch에 따라 같은 target에 대해서도 구도, 체형 등이 크게 다른 경우도 존재함을 파악하였습니다.
위에 보이는 사진과 같이 데이터셋에 따라 가설을 세우고 이에 해결책을 Augmentation을 이용해 검증하는 과정을 거치며 테스트해보았습니다. 그러나 Augmentation 만으로는 완벽하게 해결할 수 없다고 판단해, 다른방법도 추가로 조사하고 공부해보았습니다.
먼저 첫번째로 GAN등을 이용해 추가적인 학습데이터를 구축해보고자 하였는데, 이부분은 실패하였습니다.
프롬포팅에서 오류가 존재하였는지
위의 오른쪽 사진과 같이 이상한 형태로 나오는 경우가 많았습니다. 또한 시간이 부족하였기에 더 많은 시도와 다른 Diffusion모델을 사용해보지는 못하였습니다.
저희는 DreamBooth fine-tuning with LoRa 모델을 활용하였으며, 금붕어를 생성하고자 하였습니다.
두번째로 사진내에 존재하는 글씨, 라벨과 같은 내용을 지우고자 시도도 해보았습니다.
위 사진을 보게 되면 이 결과 스케치가 오히려 흐릿해지는 결과를 보이기도 하였습니다.
추후 의논을 거쳐보았을때 글씨가 오히려 스케치 Classification에 도움이 될 수 있을것이라는 가설을 세웠습니다. 이 가설을 시간이 부족해 검증을 실험을 통해 진행하지는 못하였습니다.
모델의 오류를 해결할 수 있는 TTA를 진행해보기도 하였으나, 실험결과 오히려 성능이 낮아지는 모습이 보여 이또한 보류하였습니다.
이후에는 다른 Augmentation인 Mixup & Cutmix를 진행했습니다.
여러 논문을 바탕으로 Mixup보단 Cutmix가 다양한 Task에서 더 좋은 성능을 보임을 확인하였으며 이를 기반으로 파라미터를 조정하여 실험해 보았습니다.
데이터셋의 특징때문인지 하이퍼파라미터 조절에 따라 크게 성능이 향상되는 모습은 보이지 않았습니다. 학습속도가 비교적 빠른 Resnet에서 이를 실험하였는데 본 베이스라인코드 성능보다는 크게 향상되는 모습을 보였습니다.
추후 ViT에서 이를 적용하여 실험을 하였을때는 큰 성능향상을 보이지 못하였는데, 저희는 이를 조금 더 복잡한 모델, 다른 아키텍쳐때문이라고 결론내렸습니다. 따라서 최종적으로는 베이스라인코드로 학습시킨 이후에 추가적으로 모델의 가중치를 불러와 추가학습을 일부 진행하였습니다.
6. Result
최종적용한 Augmnetation은 아래와 같습니다.
SketchRandAugmnet라는 함수를 만들어 최적의 성능을 보이는 Augmentation을 적용하도록하였습니다.
함수의 구성은 아래 코드와 같습니다.
class SketchAutoAugment(A.ImageOnlyTransform):
def __init__(self, always_apply=False, p=1.0):
super(SketchAutoAugment, self).__init__(always_apply, p)
self.policy = self.sketch_policy()
def sketch_policy(self):
return [
[('Rotate', 0.7, 2), ('Posterize', 0.6, 3)],
[('ShearX', 0.8, 4), ('AutoContrast', 0.4, None)],
[('TranslateX', 0.8, 8), ('TranslateY', 0.6, 6)],
[('Invert', 0.3, None), ('Equalize', 0.5, None)]
]
def apply_augment(self, image, op_name, magnitude):
img = Image.fromarray(image)
if op_name == 'Rotate':
return np.array(img.rotate(magnitude * 2.0))
elif op_name == 'Posterize':
return np.array(ImageOps.posterize(img, magnitude))
elif op_name == 'ShearX':
return np.array(img.transform(img.size, Image.AFFINE, (1, magnitude * 0.1, 0, 0, 1, 0)))
elif op_name == 'AutoContrast':
return np.array(ImageOps.autocontrast(img))
elif op_name == 'TranslateX':
return np.array(img.transform(img.size, Image.AFFINE, (1, 0, magnitude, 0, 1, 0)))
elif op_name == 'TranslateY':
return np.array(img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, magnitude)))
elif op_name == 'Invert':
return np.array(ImageOps.invert(img))
elif op_name == 'Equalize':
return np.array(ImageOps.equalize(img))
return image
def apply(self, image, **params):
sub_policy = random.choice(self.policy)
for op_name, prob, magnitude in sub_policy:
if random.random() < prob:
image = self.apply_augment(image, op_name, magnitude)
return image
def get_transform_init_args_names(self):
return ("always_apply", "p")
이를 적용함으로써 데이터셋 다양성증가, 모델의 일반화 능력 향상을 기대했습니다.
이 Augmentation을 적용하면서 추가로 라이브러리를 사용해 또다른 Augmentation도 진행해보았습니다.
이와 같이 앞에서 설명했던 여러 Augmentation을 가설에 맞게 테스트해보며 최적의 성능을 찾아보았습니다.
모델의 성능은 기존보다 상향됨을 보였으며 이를 기반으로 앙상블을 진행하였습니다.
동일한 모델구조를 가지나 서로다른 입력이미지의 크기와 다른 대규모이미지 데이터셋을 학습시킨 두 모델과 앞선 가설에서 증명했던 CNN, ViT모델구조를 앙상블 진행하여 최종적으로는 0.94라는 Public score를 달성할 수 있었습니다.
최종 리더보드 결과는 아래와 같습니다.
Public과 Private의 차이가 좀 존재합니다. 그 원인을 분석해보니 시간이 부족하여 단일모델에 대한 하이퍼파라미터 조정을 못해본것으로 나타났습니다. 거의 모든실험의 Optimizer를 고정하여 실험하였고 lr, batch size는 모델의 사이즈에 따라 조정하였습니다. lr_schedular도 논문이나 다른 Task에 최적의 성능을 내는 부분에 대해 검색 후 추가로 실험을 진행해보았다면 충분히 더 높은 점수를 받을 수 있지 않았을까 하는 아쉬움도 있습니다.
그럼에도 비교적 높은 성능을 받을 수 있었던 결과에 대해 분석해보았습니다.
앙상블 효과:각 모델의 예측을 결합함으로써 개별 모델의 약점을 상호 보완합니다. 예측의 불확실성을 줄이고, 더 안정적이고 정확한 결과를 얻을 수 있습니다.
EVA-02의 강점:대규모 데이터셋에서 사전 학습된 모델로, 풍부한 시각적 지식을 가지고 있습니다. 자기 주의 메커니즘을 통해 스케치의 중요한 부분에 집중할 수 있습니다.
EfficientNet의 강점:효율적인 아키텍처로 계산 비용 대비 높은 성능을 제공합니다. CNN의 특성상 지역적 특징과 질감 정보를 잘 포착합니다.
프로젝트를 진행하며 아쉬웠던 점은 방금 언급했던것과 동일하게 시간이 부족해서 옵티마이저, lr ,bastch size, 스케쥴로와 같은 하이퍼파라미터 튜닝을 하지 못했고, 그래서 성능을 최대한으로 끌어올리지 못했던 점, 또한 협업 과정에서 깔끔하게 코드를 작성하지 못했고 코드를 서로 설명해주는 과정에서 협업이 부드럽지 못하는 아쉬움이 있었습니다.
다음프로젝트에서는 이러한 아쉬움을 줄여 조금더 발전된 모습을 보일 수 있도록 노력할 예정입니다.
7. 코드 구조 및 회고
최종적으로 제가 작성하였던 코드 구조와 회고를 첨부하며 프로젝트 정리를 마무리 하겠습니다. 긴 글 읽어주셔서 감사합니다.
'AI > Naver_Boostcamp AI Tech' 카테고리의 다른 글
다국어 영수증 OCR (0) | 2025.02.11 |
---|---|
재활용 품목 분류를 위한 Object Detection (0) | 2025.02.11 |
회귀 모델 평가 지표 (0) | 2024.08.12 |
머신러닝 라이프사이클: 인공지능 프로젝트의 전체 과정 이해하기 (0) | 2024.08.12 |
텐서 연산 마스터하기: 기본부터 고급까지(2) (# 3일차-2) (0) | 2024.08.07 |