본문 바로가기
Project/Image Classification Pipeline Project

3. (1) 이미지 전처리 - augmentation, normalization(이미지 수집부터 분류 모델까지)

by inhovation97 2021. 6. 17.

이 포스팅은 아래 흐름대로 진행되는 포스팅입니다.

데이터 수집 - 전처리 - 모델링 - 성능 개선 

 

이번 포스팅은 직접 수집한 이미지들에 대해서 전처리를 해줍니다.

이 과정은 모델이 보다 더 잘 학습할 수 있도록 여러 전처리를 진행합니다.

전처리 과정에서 torchvision.transform과 albumentations 라이브러리를 둘 다 사용해봅니다.

 

이번 포스팅은 torchvision.transform을 이용해서 이미지 전처리를 진행합니다.

https://inhovation97.tistory.com/36 << 이전 포스팅 [2. 파이썬 파일 정리하기 (이미지 수집부터 분류 모델까지)]

 

포스팅 순서

<trorchvision 라이브러리를 이용해 쉽게 이미지들을 전처리하기>
1. 이미지 resize하기
2. resize한 이미지 normalize하기
3. torchvision.transforms를 이용해 이미지 augmentation

티스토리 코드 가독성 때문에 먼저 코드 파일을 공유합니다. (주석도 잘 달아놓음)

코랩으로 열기를 권장합니다.

https://github.com/inhovation97/personal_project/blob/main/pytorch/pytorch_project_Image_preprocessing.ipynb

 

inhovation97/personal_project

개인 프로젝트. Contribute to inhovation97/personal_project development by creating an account on GitHub.

github.com

 

 

이번 포스팅은 모델에 집어넣기 직전까지 데이터를 전처리해주는데, 포인트는 학습이 잘 되도록 데이터를 다듬어주는 데에 있습니다.

 

<trorchvision 라이브러리를 이용해 쉽게 이미지들을 전처리하기>

 

1. 이미지 resize

torchvision라이브러리를 이용하면 dataloader를 정의해주기가 굉장히 쉽습니다.

우선 파일들의 상황을 다시 확인해줍니다.

 

train/test 폴더를 만들어준 뒤 각 범주들의 폴더도 만들어 주었습니다.

train/test 데이터를 각 범주마다 8:2 split했습니다.

train : 1049

test : 263

 

제가 가져온 이미지들은 문제가 있습니다. size가 전부 다 다릅니다.

cnn 모델은 featuremap을 뽑기위해 input data의 형태에 맞게 아키텍쳐를 설계하기 때문에 이미지들의 size를 전부 맞춰주어야합니다. 

 

 

 

폴더들을 위 처럼 정리해 두었다면, torchvision의 ImageFolder라는 함수를 이용해 root에 경로만 지정해주면, 알아서 각 범주의 이미지들을 읽어주기 때문에 매우 편리하게 dataset을 정의할 수 있습니다.

 

torchvision의 transforms을 이용해서 모든 이미지들을 128*128로 resize해준 뒤에 tensor형태로 바꿔줍시다. totensor는 numpy형태의 이미지를 torch의 (C,H,W) tensor형태로 바꿔줍니다. 

 

 

 

 

 

 

 

위 transforms를 진행하면, 요로코롬 이미지 데이터가 텐서형태로 변환하면서 픽셀도 전부 255로 나뉘어 range가 (0~1)값으로 스케일링이 됩니다.

 

 

 

 

 

 

 

2. reize한 이미지 normalize하기

 

먼저 이렇게 transform을 해준 이유가 있습니다.

바로 이미지들을 normalize해주기 위함입니다. 

 

범위를 조정함으로써 step해 나가는 landscape를 안정화 시켜서 local optima 문제를 예방하고, 속도 측면에서도 좋아진다고합니다. 

 

저는 앞서 이 글 첫 번째 포스팅에서 resnet50 모델을 transfer leaning을 할 것이라고 말했었는데, 찾아보니  ImageNet에서 쓰인 데이터들의 평균을 이용해서 normalize해주는 경우도 있다고 하더라구요. 일단 저는 제가 크롤링한 데이터들의 mean, std로 normalize를 진행하겠습니다.

 

 

 

하지만 normalize를 진행할 시에 꼭 중요한 점이있습니다.

1. 꼭 resize한 이미지들의 mean과 std로 normalize를 진행할 것

   -> resize한 이미지를 학습할 것이기 때문에 resize한 데이터의 mean과 std를 이용해야 합니다.

 

2. train/test셋을 독립적으로 해야할까? (수정)

   -> 보통의 경우 train셋에는 절대로 test셋의 정보가 들어가면 안됩니다. 두 data를 독립적으로 normalization을 해주지 않으면 의도치 않게 과적합의 위험에 빠져있겠죠...?

 

이미지 데이터에서는 normalization이 크게 작용하지는 않나봅니다. 아래 아래 cs231n에서는 image normalization을 저런 식으로 설명했고, 보통은 imagenet의 mean과 std를 이용하기도 하고, 그냥 mean 0.5, std 0.5로 noramlization을 진행하는 경향도 있다고합니다.

아무래도 지금 제 데이터셋처럼 (해양생물이라 파란색이 굉장히 많죠?) 이미지가 굉장히 독특하다면 직접 구해서 normalizatio해주는 방법도 나쁘지는 않겠습니다. (수정)

 

앞서 말했 듯 제가 공부한 cs231n에서는 그냥 하나의 mean/std로 normalization한다고하며, 채널별로 따로 하는 것도 큰 차이가 없다고 강의 내용에 나옵니다.

하지만 또 여기저기 서칭해보면, 대부분 이미지 데이터를 train/test의 각 채널의 mean과 std로 normalization 진행하는 경우가 많습니다. 

 

https://inhovation97.tistory.com/23
train 셋과 test 셋을 전 처리할 때에는 동일한 mean을 이용하여 zero-mean을 해준다고 합니다.
여기서 mean값을 이미지의 전체 데이터로 할지, 아니면 각각 독립된 채널마다의 mean으로 이용할지 선택할 수 있는데, 이는 큰 차이는 나지 않는다고 합니다.
 
VGGNet은 알렉스 넷보다 후에 나온 것인데, 각각의 채널별로 mean값을 두어 zero-mean을 했다고 합니다.

 

cs231n이 오래된 강의이기도 하고... 이 부분은 이 참에 포스팅하면서 확인해보겠습니다!

엄청 큰 차이는 없을 것 같아요.

 

 

 

 

이렇게 train/test 셋들의 RGB 채널마다 mean과 std를 따로 구하는 함수를 만들어 구해줍니다.

이제 normalization 준비는 끝났습니다.

전부 해양생물 사진이라 그런지 red픽셀값은 낮고 blue 픽셀값은 높네요 ㅋㅋ

 

 

 

 

 

3. torchvision.transforms를 이용해 이미지 augmentation 

 

현재 제 train데이터의 양은 너무 적습니다. 과적합의 위험이 있죠.

이 글들을 포스팅할 때부터 개인적으로 직접 image data를 수집하는 데에는 당연히 한계가 있기에 trainset이 적을 것을 예상했습니다.

 

그래서 제가 생각한 첫 번째는 transfer learning이었고, 두번째가 바로 data augmentation이었습니다. 

이미 학습이 진행된 모델을 가져와 제 데이터들로 fine tuning을 해주고,

data augmentation을 통해서 학습의 epoch의 부담을 줄여주는 것입니다.

 

data augmentation 직역하면 '데이터 증식' 말 그대로인데,

data augmentation 추가해주면, epoch마다 train 이미지들에 변형이 가해져서 모델이 1049장의 이미지들을 조금씩 다른 이미지로 받아들이게 해주는 것입니다. 

보통은 학습 데이터만 augmentation을 해준다고합니다.

 

 

 

 

 

이런식으로 완전 다른 이미지는 아니지만 아마 epoch 수를 높히는 데에 부담이 줄어들 것입니다. 

그래서 위 처럼 이미지를 크롭, 지터링, 회전 등등 augmentation을 가해줍니다.

augmentation을 가한 이미지는 다시 renormalize와 rescaling을 해주어야 이미지가 잘 나오니 참고하세용

 

이제 이렇게 torchvision을 이용해 data loader까지 학습을 위한 데이터의 준비가 끝이 났습니다.

다음 글은 똑같이 data를 준비하지만, 직접 데이터 class를 정의하여 커스터마이징하는 방법을 포스팅합니다.

댓글