0. 개요
첫 주차는 파이프라인을 구성하는 코드 하나하나를 분석하지 않고
전반적인 훈련 흐름을 "관광"하는 것이 목표이다.
이번 주의 핵심은 (1)모델을 고정하고, (2) epoch을 고정하여 동일한 환경에서
(1)데이터 전처리와 (2)optinizer 및 scheduler 를 변형하여 성능 향상을 이뤄낼 수 있다는 것을 경험하는 것이다.
이번 주에는 model은 resnet50을 사용하였고, epoch은 50으로 고정하였지만 scheduler를 관찰하기 위해 scheduler를 사용하는 부분은 100epoch으로 했다.
채팅방을 통해 제공된 tar.gz파일을 압축해제하여 데이터셋과 파일을 볼 수 있다.
cd [폴더] 명령어를 이용해 tar.gz파일 위치로 이동한 다음
tar -zxvf 1_classification.tar.gz 명령어를 통해 classification_1.tar.gz 파일을 압축해제할 수 있다.
파일은 총 7개로,
classification_0_EDA.ipynb
classification_1_base.ipynb
classification_2_skf.ipynb
classification_3_Adam.ipynb
classification_4_aug.ipynb
classification_5_scheduler.ipynb
classification_6_scheduler2.ipynb
이렇게 구성하였다.
이번 페이지에서는
classification_0_EDA.ipynb
classification_1_base.ipynb
classification_1_skf.ipynb
를 다뤄보겠다.
일단 파이프라인이 어떻게 구성되는지 넓은 시야로 정리해보자.

이런 식으로 정리될 수 있을 것 같다. - 그리고 이 순서대로 코드를 작성해주는 것이 여러모로 편할 것이다 !
처음 본다면 고려할 게 너무나도 많은 것은 당연하다.
겉도는 말을 조금 덧붙이자면, 논문스터디 경험이 있다면 9할 이상의 시간을 투가하는 영역이 Model 부분이다.
Model에 따른 성능 변화가 어떻게 이루어지는지를 주로 논문에서 언급한다. 가끔씩 augmentation 기법, 아아아주 가끔씩 Optimizer 기법이나 dataset에 대한 논문을 볼 경험이 있었을 것이다.
실제로 훈련 파이프라인을 작성할 때 model에 대한 이해가 많다고 정확도 높은 파이프라인은 만들 수 있는 건 아닌 것 같고, 파이프라인의 전반적인 이해가 있어야 잘 훈련할 수 있는 것 같았다. 그래서 이 강의를 통해 인공지능 뉴비들이 조금 더 익숙해지길 기대해본다.
1. EDA ( Exploratory Data Analysis )
data룰 무작정 훈련에 input하기보다 데이터의 분포와 형태를 이해하는 것은 매우 중요하다.
당연한 예시를 들자면,
(1) 고양이와 개를 분류해야하는 task에서 높은 확률로 거꾸로된 고양이 이미지를 입력받을 일이 없다. 그러므로 거꾸로된 고양이 이미지는 바로 세우는 수정을 한 뒤 input 해줘야한다.
(2) 폐렴 환자를 구분하는 xray 이미지에서 정상인 xray에 환자 label을 달아놨다. 일반성을 헤치는 data이므로 label을 수정해줘야한다..
(3) 남자 여자를 구분하는 task에서 남자이미지를 50개, 여자 이미지를 5000개 준비했다. 데이터의 분포가 불균일하므로 down sampling을 하든, loss function을 바꿀 고민을 하든,새로운 전략을 세울 필요성을 알아차린다.
EDA 과정을 통해 dataset을 수정할 수도 있고, 훈련 파이프라인을 만드는 전략에 힌트를 얻을 수도 있다.
실제로 대회를 경험하다보면, 정확도 성능이 더이상 오르지 않을 때 EDA 과정으로 돌아가 dataset 가공하는 새로운 방법론을 적용하면 성능 향상이 큰 폭으로 이루어질 때도 많다.
가장 기본적이면서도, 가장 중요한 EDA이지만 자료 만들 시간이 부족하므로 대충 흝고 넘어가자.
https://www.kaggle.com/datasets/datamunge/sign-language-mnist
Sign Language MNIST
Drop-In Replacement for MNIST for Hand Gesture Recognition Tasks
www.kaggle.com
dataset은 수화로 알파벳을 표현한 26개 class 분류 과제다.
import torch
import matplotlib
import pandas as pd
import string
import matplotlib.pyplot as plt
raw_data = pd.read_csv("./data/sign_mnist_train.csv")
raw_data.head()

데이터를 뜯어보면, 이미지로 준 게 아니라 784개 픽셀값을 하나하나 줘놨다.
벌써부터 어질어질하다.
각 행은 이미지 1장, 각 열은 픽셀값, 784 = 28x28 이미지 인 것을 눈치껏 알아차려야한다.
MNIST같은 기본적인 data는 28x28 사이즈로 주로 제공된다.
맨 앞에 label 열을 보면 각 class를 나타내는 것 같다. 이걸 통계로 뽑아보면
label_count = raw_data['label'].value_counts()
labels = label_count.index
counts = label_count.values
plt.figure(figsize=(10, 6))
plt.bar(labels, counts)
plt.xlabel('Label')
plt.xticks(labels)
plt.ylabel('Count')
plt.title('Count of Labels')
plt.tight_layout()
plt.show()

비교적 data가 균일하게 분포해있다는 것을 알 수 있다.
다만 9번, 15번 라벨이 누락된 것 같다.
그리고 각 라벨은 알파벳을 나타낼 건데, 어떤 라벨이 어떤 알파벳을 뜻하는지는 모른다.
이건 스스로 검색해서 알아내야한다.
분류 실컷 해놓고 본인이 뭘 분류한 지 모르는 기이한 상황이 펼쳐지곤 한다..
나는 대충 눈치껏 0은a, 1은b라 생각하고 EDA 했다.
아니라면 나중에 피드백 부탁한다.
이번에는 라벨별 이미지를 출력해보자.
img = raw_data.drop(labels=['label'],axis=1)
img = img.values.reshape(-1,28,28)
label_value = raw_data['label'].values
alphabet = string.ascii_lowercase
num_images=24
num_cols = 6
img_list = []
label_list = []
for i in range(26):
for j in range(200): # 대충 200쯤 보내면 이미지 다 채울 수 있을 것 같아서 줬다.
if label_value[j] == i:
img_list.append(img[j])
label_list.append(i)
break
num_rows = (num_images + num_cols - 1) // num_cols
plt.figure(figsize=(10, 6))
for i in range(num_images):
plt.subplot(num_rows, num_cols, i + 1)
plt.imshow(img_list[i], cmap='gray')
plt.axis('off')
plt.title(f'{label_list[i]} : {alphabet[label_list[i]]}', fontsize=10)
plt.show()

손 모양이 다 다르니깐 출력은 문제없이 잘 된 것 같다.
다만 a, e, m,n, y는 손모양이 같아보이고, p, q 혹은 d, r은 잘 구분할 수 있을지 모르겠다.
이번에는 좀 더 큰 시야로 넘어가보자.
2. 성능 비교
여섯 번의 코드 변형을 통해
(1) 모델을 고정
(2) epoch을 고정
하고 f1 성능이 향상되는 과정을 보자.

성능을 측정할 때는 accuracy보다 f1 score로 보는 것이 공정하다.
f1 score로 비교했을 때 성능이 꾸준히 향상되는 것을 알 수 있다.
이제 각 과정에서 어떤 기교가 사용됐는지 살펴보자.
3. base
base 파이프라인에서는
dataset : x
model - resnet 50
loss function - cross entropy
optimizer - SGD
scheduler - x
f1 : 0.1022
이렇게 구성됐다.
3. skf - Stratify k fold
skf를 이해하려면 코드 분석과 같이 가는 게 좋을 것 같아서 따로 포스팅을 남기는 게 좋을 것 같다.
간단하게 이해하자면, 모든 label의 비율을 반영하여 valid set을 만드는 것이다.
예를 들어 10개의 class, 각각 10개씩의 data가 있는데, 0~7번 class를 train set으로, 8~9번 class를 valid set으로 나눈다면, 훈련도 똑바로 이뤄지지 않을 것이고, test set에서 8~9번 class는 훈련과정에서 경험하지 못했기 때문에 모조리 틀려버릴 것이다.
그래서 모든 class를 골고루 훈련하기위해 구성된 기술이다.
어떤 data를 훈련시킬 것인지만 결정해준 것인데 점수가 0.02점이나 향상됐다.
작은 점수같지만 대회 한번 나가보면 저 점수 진짜 큰 점수인 거 알 수 있다.
f1 : 0.1263
나머지 파일들에 대한 리뷰는 다음 포스팅에서 이어서 해보겠다.
'Ai > One and Zero class' 카테고리의 다른 글
| Week-3 classification 모듈화 & colab에서 run time 끊기지 않게 JavaScript 입력하기 (0) | 2024.05.30 |
|---|---|
| Week-2 Ubuntu ( Linux ) 에 Git 설치하기 (0) | 2024.05.10 |
| Week-1 Ubuntu(Linux)에서 miniconda 설치, 가상환경 생성 (1) | 2024.03.30 |
| Week-1 : VScode와 Colab 연동 (0) | 2024.03.30 |
| Week-1 : Window에 Linux 설치 (0) | 2024.03.29 |
댓글