Post

[KT Aivle 3기 AI] 8주차 (33~37일차). 미니프로젝트 3차

KT Aivle School 3기 8주차. 미니프로젝트 3차 (1), (2)

👏 미니프로젝트 3차!

이번 주는 통째로 미니프로젝트를 진행했다. 주제는 2개로 월 ~ 수 / 목 ~ 금 각각 다른 주제로 진행되었다. 저번주에 배운 시각지능 딥러닝을 토대로 실제 Task를 해본다는 의미였는데, 직접 구현해보면서 스스로도 많은 정보들을 찾아보고 조원분들과 토의하면서 많은 성장을 할 수 있었던 것 같다!

💡 미니프로젝트 3차 (1) (33일 ~ 35일차)

  • [진행한 코드 !]

  • 강사 : 박상혁 강사님
  • 주제 : 차량 공유 업체의 차량 파손 여부 분류
  • 데이터 : DALL-E로 자체 제작된 데이터

  • 데이터를 통일된 폴더구조로 정리한다.
  • 딥러닝 모델을 직접 설계하고 학습을 진행해본다.
  • Transfer Learning을 진행해본다
  • Data Augmentation을 통해 학습해본다.
🌟 미니프로젝트 3차 (1) TIL --------------------

✅ 데이터 폴더구조

  • 먼저 데이터를 각각 train, validation, test로 나누고 keras의 flow_from_directory를 이용하기 위해서 폴더 구조를 동일하게 생성해야했다.
  • 즉, 각각 폴더 안에 class 명의 폴더가 있고 그 폴더 안에 각 데이터가 있어야 했다.
  • 강사님의 가이드 코드에서는 osshutil등을 이용해서 직접 파일을 옮기고 하는 과정이 있었고, 나는 이것이 익숙해서 바로 진행하였다.
  • 근데, splitfolders라는 좋은 라이브러리가 있어서 쉽게 데이터를 정리할 수 있는 방법이 있었다!!

✅ 모델 설계 및 학습 과정에서 배운 점

  • 현재 우리의 데이터는 양도 적었고, 너무 확실한 데이터였다(구분이 너무나도 잘 되는 데이터).
  • 따라서, 오히려 모델을 깊게 쌓았을 때 보다 얕게 쌓았을 때 더 좋은 성능을 보여주는 현상을 확인할 수 있었다.
  • 그리고 validation accuracy가 0.5에서 변하지 않는 현상이 있었는데, 이는 EarlyStopping의 Patience를 늘려주어 epoch를 많이 돌게하면 학습이 되었다. 그리고 필터 수, 노트 수 등등 모델 구조를 변경해서 파라미터 수를 조절하는 방법으로 해결할 수 있었다.
  • 애초에 데이터 자체가 너무 명확해서 어떠한 모델을 써도 결과가 잘 나올 수 있었지만, 나의 경우는 EfficientNet을 사용했을 때 성능이 가장 좋았다.

✨ BatchNormalization

  • 사실 이번 프로젝트에서 개인적으로 가장 큰 수확 중 하나는 BatchNormalization에 대해서 많이 찾아보고 공부해본 부분이다.
  • 우리 조원분 중 한 분이 Transfer Learning을 할 때, Pretrained Model의 BatchNormalization Layer(이후 BN layer으로 부르겠습니다)를 Trainable 하게 하면 성능이 좋아진다는 글을 보셨고, 직접 해봤을 때도 성능이 좋아졌다는 말을 해주셨다.
  • EfficientNet에 처음에는 끝 단만 학습하도록 했을 때, 학습이 되지 않았었다.
  • 그래서 조원 분의 말을 듣고, BN layer를 Trainable 하게 했더니, 성능이 대폭 향상되어 심지어 Test Data에서 Accuracy 1이 나왔다.(실전 데이터에서는 일어날 수 없는 일임. 아마도 생성된 데이터다보니, train data에 있는 어떤 vector space가 test data에도 거의 비슷하게 존재하는 것으로 보임)
  • 이 부분이 너무 궁금해서 엄청나게 찾아봤는데, 내 생각은 아래와 같다.
Pretrained Model의 BatchNormalization Layer를 학습하는 것에 대하여..

기본적으로 Batch Normalization이 분포를 조절해주는 것인데, BN 을 학습하고 안하고의 차이가 큰 이유는 Imagenet의 분포와 지금 우리가 하고 있는 데이터의 분포의 차이가 커서 그렇지 않을까 하는 생각이 든다.

Tensorflow 공식문서(5번 링크)나 자료들을 찾아보면(여담으로 Chat GPT에서도) Transfer Learning을 할 때는 BN을 학습시키지 않는다는 말이 있다.

Tensorflow 공식 문서에서는 BN은 2개의 Trainable weights(알파, 베타를 의미 하는 것 같다)와 2개의 non Trainable weights(mini batch의 평균, 분산인 것 같다)가 있다고 하는데, 이 때문에 새롭게 학습을 진행하면 기존에 학습했던 것들이 파괴된다고 한다.

Chat GPT에서는 Pretrained Model이 이미 새로운 작업에도 유용할수 있도록 일반적인 Feature를 가지고 있고, BN layer는 이전 layer의 activation을 정규화 하기 위한 것이므로 새 작업을 위해 조정할 필요가 없을 수 있다고 말했다.

근데 내 개인적인 생각으로는 결국 학습시키고자 하는 데이터의 분포를 학습하는게 맞지 않을까 하는 생각인데, 3, 4번 링크에서 보면 BN을 train 하냐 안하냐는 정답은 없는 것 같다.

일단 내 결과에서는 BN을 학습시키는게 좋았다. 그 이유에 대해서 내 개인적인 생각은, Train data의 분포와 Validation, Test Data의 분포가 차이가 많이나서(이걸 Internal Covariate Shift 라고 한다) 그렇지 않을까 생각한다.

++ 관련하여 참고한 링크

  1. https://gaussian37.github.io/dl-concept-batchnorm/
  2. https://velog.io/@dltjrdud37/Batch-Normalization
  3. https://velog.io/@dlskawns/Deep-Learning-전이학습Transfer-Learning의-미세조정Fine-Tuning-방법-및-괴현상-원인분석-feat.-BN-ResNet50
  4. https://stackoverflow.com/questions/63352974/tensorflow-transfer-learning-with-pre-trained-model-that-uses-batch-normalizatio
  5. https://www.tensorflow.org/guide/keras/transfer_learning?hl=ko

✨ EfficientNet

  • 마찬가지로 이번 프로젝트에서 개인적으로 가장 큰 수확 중 하나는 EfficientNet에 대해서 공부해본 부분이다.
  • 이름은 들어봤어도, 따로 공부해보거나 사용해보진 않았었다.
  • EfficientNet이 성능이 좋다고 해서 관련해서 이해하고 사용해보기 위해서 논문리뷰 등 설명하는 자료들을 많이 살펴보았다.

✨ 기타 다른 부분들

  1. Global Average Pooling
    • GAP는 위치정보를 적게 잃어버리고, 파라미터 수를 크게 줄여 과적합을 방지할 수 있다.
    • 이번 모델링에서는 GAP를 쓴 경우가 성능이 더 좋았다.
  2. Validation Data에서 Augmentaion을 하는 것이 성능 향상에 좋을까?
    • 확실하진 않지만, 오히려 Overfitting이 날 수 있다고 함.
  3. Random Seed를 고정하자.
  4. Batch Size와 Learning Rate
    • 관련한 포스팅을 통해 관계를 확인할 수 있었다 :https://inhovation97.tistory.com/32
    • Batch Size에 따른 학습 관계에 대해서도 검색을 통해 알 수 있었는데, Batch Size가 크면 클 수록 train data에 Overfitting이 될 확률이 높고, 작을 수록 Robust한 모델이 학습될 가능성이 높다고 한다.
    • 이유는 Batch Size가 클 수록 weight 값도 작아지고 전체를 반영하는 값으로 학습이 되고, 작을 수록 각각의 데이터에 대한 학습이 이루어지기 때문에 weight도 커지고 다양한 데이터에 대해 학습을 할 수 있다고 한다.

💡 미니프로젝트 3차 (2) (36일 ~ 37일차)

[프로젝트 진행한 코드]

  • 강사 : 권선일 강사님
  • 주제 : 시각장애인 및 저시력자 등 시각의 보조가 필요한 사용자들에게 스마트폰 카메라를 통해 화폐 정보를 알려주는 AI 모델 개발
  • 데이터 : 셀렉스타(오픈 데이터셋)을 통해 원본 데이터 확보
  • 강조사항 : Documentation과 친숙해지자!!

[YOLOV5 Github. Documentation]

🌟 미니프로젝트 3차 (2) TIL --------------------

✅ 데이터 전처리 (YOLO에 맞게 폴더 구조 변경)

우리가 제공받은 데이터는 각 화폐 단위 폴더에 jpg와 json 파일이 존재했다. YOLO에서는 하나의 폴더에 images와 labels가 있고, 각각의 폴더에 train과 validation 폴더가 있다. 그리고 YOLO의 label은 (class, x_center, y_center, width, height)로 구성되어있는 txt파일이다.

먼저 os, shutil, glob 모듈 등을 사용해서 image와 json 파일들을 train, validation 비율에 맞게 복사해주었다. 이때, jpg와 json이 짝으로 존재하므로 jpg의 개수만 가져와서 개수를 정해주었다.

그리고 json 파일에서 label 정보를 추출했는데, 기존 json에는 좌측 아래와 우측 상단의 좌표를 각각 x1, y1, x2, y2 형태로 저장되어있었기 때문에 해당 값을 가져와서 아래와 같이 YOLO label에 맞게 변환해주었다. (YOLO label은 x_center, y_center, widht, height가 모두 0 ~ 1의 값으로 되어있어야 함)

1
2
3
4
x_center = ( (x1 + x2) / 2 ) / width
y_center = ( (y1 + y2) / 2 ) / height
width = (x2 - x1) / width
height = (y2 - y1) / height

마찬가지로 label은 dictionary를 활용해서 파일명에서 label을 parsing 한 값을 dictionary의 값에 맞게끔 하여 생성해주었다.

✅ YOLOV5 학습

YOLOV5에서 모델의 크기별로 5가지가 존재했다(5n, 5n, 5m, 5l, 5x). 우리는 각각 모델 크기별로 학습을 해서 결과를 확인해보았다.

image

그리고 local logging이 되긴 하지만 학습되는 중에는 확인할 수가 없었는데, 공식 Documentation에서 확인할 수 있었던 W&B와 Comet을 활용하여 시각화도 진행해보았다.

그렇게 해서 다양한 모델을 학습시켜보았는데, 학습되는데 너무 많은 시간이 들어서 대부분 20~30 epoch 정도 학습시켰다. 그 중, 5m 모델은 Patience를 많이 주고 epoch도 많이 줘버려서 112 epoch까지 학습을 한 모델이 있었는데, 오히려 Overfitting이 된 것 같은 결과를 확인할 수 있었다.

그래서 각 모델들로 inference를 진행해보았다. 인터넷에 있는 사진들로도 진행해보고, 직접찍은 사진과 동영상으로도 진행해보았다.

image

✅ YOLOV5 Augmentaion

inference 결과 지폐가 돌아가있는 등 정면의 사진이 아닌 경우에는 잘 잡지못하는 것을 확인을 했다. 그래서 Data Augmentaion이 필요하다고 생각해서 진행했다. YOLOV5의 Hyperparameter를 수정하는 yaml 파일에 관련 설정이 있어서 rotation, shear, perspective, flip 등등의 값을 추가해주어 학습을 진행했다. 아래의 사진과 같이 Augmentaion 된 데이터로 학습이 진행되었고, 20 epoch 까지 갔을 때 모델의 성능이 점점 수렴하는 모습을 보였다.

image

image

확실히 Augmentaion을 했을 때, 돌아가있는 지폐를 잘 인식하는 것을 확인할 수 있었다.

✅ Detectron2

우리 조원 중 한 분이 Detectron2라는 모델으로도 학습을 진행해보셨다. Detectron2는 Facebook AI Research에서 만든 최신 감지 및 세분화 알고리즘을 제공하는 의 차세대 라이브러리라고 한다. 근데 label의 format이 yolo와는 달라서 coco format으로 변환을 시켜야 했는데, coco format에서는 이미지의 segmentation 정보까지 아주 정밀하게 label이 되어야 했다. 하지만 우리는 bounding box 정보밖에 없어서 학습결과 성능이 좋지는 않았다.

YOLO Documentation에서도 bounding box는 아주 정밀하게 되어있어야 한다고 했는데, labeling이 얼마나 정밀하게 되어있느냐에 따라 Object Detection의 성능에 차이가 많이 나는 것 같았다.

✅ 결론

YOLOV5의 모델의 크기에 상관없이 어느정도 epoch를 지나면 성능은 비슷한 것을 확인할 수 있었고, Task에 따라 다르겠지만 다양한 각도와 방향에서도 물체를 잘 탐지하고 싶다면 train data에서도 그러한 데이터가 당연히 존재해야한다는 것을 확인할 수 있었다. 그래서 그런 데이터가 없다면 Augmentaion을 하면 원하는 성능을 얻을 수 있었다.

또한, Object Detection에서 labeling은 아주 정확하게 되어야 성능이 잘 나올 수 있다는 것을 확인할 수 있었따.

우리는 다같이 열심히 했고, 팀원 분들이 발표도 하면 좋겠다고 해서 이번에는 발표까지 진행하게 되었다! 정말 많은 성장을 할 수 있는 프로젝트였다.

👏 미니프로젝트 3차 마무리

이번 한 주 동안 좋은 팀원들과 함께 많은 성장을 할 수 있었던 것 같다!

특히 2번째 프로젝트에서는 내가 발표까지 하게 되면서, 열심히 했던 것을 보여줄 수 있어서 좋았다.

확실히 실제로 프로젝트를 진행해보면서 많은 것을 느끼고 스스로도 배우며, 팀원 분들에게도 많은 것을 배울 수 있었다. 앞으로 배울 이론도 열심히 배워서 앞으로의 나에게 좋은 밑거름이 되도록 해야겠다. 그리고 앞으로도 배움의 자세를 잊지 않고 탐구하고 배워나가야겠다!!

This post is licensed under CC BY 4.0 by the author.

[KT Aivle 3기 AI] 7주차 (28~32일차). CNN(Convolutional Neural Network)

[KT Aivle 3기 AI] 9주차. 언어지능 딥러닝