CastleJo의 개발일지

Image Classification - 학습정리

|

EDA

Exploratory Data Analysis

탐색적 데이터 분석

  • 실제로 어떻게 생겨먹었는가?
  • 데이터들의 분포가 어떻게 되어있는가?
  • 특정 변수들 사이에 연관성이 있는가?
  • 기타 등등…

모델을 만들기 전 해야 할 일이다.

정답은 없다. 하지만 괜찮은 가이드라인이 있다.

Input X에 대한 분석

  • 이미지의 사이즈
    이미지의 사이즈가 상이하면 모델이 학습을 잘 못 할수도 있다.
    아래의 객체의 위치에서 추가로 적어야겠다
  • 객체의 위치
    이미지가 존재한다는 Bounding Box를 추출하여, 그 부분만 학습시킨다면 더 효과적일것이다. 특정한 모델로 이를 구하는 전처리방법을 거치고있다.
  • RGB채널의 값
    마스크가 없는 사진과 있는 사진에는 RGB값의 차이가 꽤 눈에 띄었다.
    마스크를 구분하는 모델에서 쓸 수 있을수도?

Target Y에 대한 분석

  • y값의 독립적인 분포 확인
    모든 훈련세트에서 동일한 정보는 빼내도 될 것 같다.
    클래스를 분류할 때 One-Hot 벡터를 이용해야 할 것이다.
  • y값의 복합적인 분포 확인
    성별값과 같은 2개밖에 없는 클래스와 다른 y값들을 같이 보니 꽤나 유용한 정보들이 있었던 것 같다.

X와 y의 관계에 대한 분석

  • 이미지 사이즈와 y값의 관계
    이건 잘 모르겠다.
  • RGB 통계값과 y값의 관계
    확실히 마스크를 끼지 않은 쪽과 낀 쪽에서 RGB값이 좀 달랐다.
  • 데이터의 노이즈 확인
    이거 일부러 넣어두신거에요?? ㅜㅜㅜ

Pre-processing

주어진 바닐라데이터를 모델에 적합한 데이터로 바꾸는 과정이다.

Bounding box

이미지의 경우 생각 이상으로 많은 정보를 가지고있을때가 있다.
예를들어, 사람이 찍힌 사진인데, 뒤에 고양이가 같이 찍힐수도 있다.
모델은 이럴 경우 사람만을 학습하지 않고 고양이까지 학습할수도 있다.

이럴 경우 모델에 간섭이 생길수도 있어, 사람만을 추출해주는 전처리과정을 거치는것이 좋다.

Resize

모델은 특정한 사이즈의 사진을 Input으로 요구한다.
이를 위해 맞춰주는 과정이 필요하다.

이 외에도 상황에 따라 상당히 많은 변수들이 존재한다.

Generalization

일반화

Bias & Variance

학습이 너무 안됐거나, 학습이 너무 됐거나 하는 경우이다.
적당한 epoch값을 주어 해결할수도 있고, Cut-Mix와 같은 방법으로도 해결할 수도 있고, 여러가지 시도들이 필요하다.

Train / Validation

훈련 세트 중 일부를 때어내어 검증 세트로 이용하는 것이다.
교차검증을 통한 방법들이 많이 있다.

Data Augmentation

한 사진에 여러가지 필터를 적용하여 과적합을 방지하고 여러가지 노이즈가 있어도 인식할 수 있게 한다. 상당히 중요하다.
이미지를 자르던, 뒤집던, 섞던 여러가지 방법이 있다.
하지만 정말 Input으로는 들어오지 않을 상황에 대해서는, 넣을지 말지 고민을 해봐야될것이다.

  • Albumentations
    기존의 torchvision.transforms보다 더 빠르고 더 다양한 방법들을 제공하여 꽤나 유용한 라이브러리이며, 자주 사용해야겠다.

Data Generation

학습을 할 땐, 모델의 성능과 Data Generator의 처리속도에 맞춰 조정을 잘 해주는것이 병목현상을 막는것에 중요하다.

Pytorch의 DatasetDataLoader에 의해 조정되며, 이에 대하여는 저번주에 많이 정리를 했다.

Model

Pytorch는 상당히 Low-Level로 되어있다.
그리고 핵심 클래스인 nn.Module은 많은 클래스 내에서 구성되어있다.
이들의 특징은 forward()함수를 갖는다는 것 인데, 가장 상위 모듈에서 forward 함수를 실행하면 아래의 모든 클래스에서 다 같이 forward함수를 사용한다.
해당 함수를 실행할 시 내부의 Parameter클래스들을 업데이트해주는 방식으로 학습이 일어난다.

Pre-Trained Model

세상엔 잘 만들어진 모델들이 매우 많다.
이를 사용하지 않고 모델을 처음부터 만드는 것은 매우 힘들것이다.

다만, 주의해야할 점은, 미리 학습된 모델이 내가 적용하려는 모델이 학습한 데이터와 비슷한지를 알아야한다. 비슷하다면 feature-extension만 하면 되고, 비슷하지 않다면 fine=tuning을 한다.
다만 학습 데이터가 충분하지 않을시, 비슷하지 않은 모델을 훈련시키기엔 큰 무리가 있다.

Loss

Loss 또한 nn.Module을 상속한다.
학습을 하면서 loss.backward()를 할 때 파라미터의 grad값이 업데이트된다.

  • Focal Loss
    Class마다 Imbalance 문제가 있을 경우 맞출 확률이 높은 Class에는 많은 Loss를 주는 방식
  • Label Smooting Loss
    Class Label을 One-hot방식으로 표현하는것이 아닌, 좀 더 Soft하게 표현하여 일반화 성능을 높이는 방법이다.

Optimizer

Loss를 보며 어느 방향으로, 얼마나 하강할 지 결정하는 클래스이다.

매 epoch마다 optimizer.zero_grad()를 해주는 것이 권장된다.

훈련 과정

model.train()

Dropout, BatchNorm과 같은 부분에서 영향을 줄 수 있어 무조건 훈련을 할 땐 해당 함수를 실행시켜주는것이 좋다.

기본적인 순서는

  • optimizer.zero_grad()
  • loss = loss_fn(output, labels)
  • loss.backward()
  • optimizer.step()

이 반복된다.

model.eval()

검증 과정에서도 forward()함수가 호출된다.
이 때 grad를 업데이트하면 안되기에 grad를 고정시키기 위해 해당 함수를 사용한다.

또는 with torch.no_grad()를 사용할 수도 있다.