본문 바로가기
인공지능 개발하기/Machine Learning

[Tensorflow] 27. ImageDataGenerator 이미지 데이터 전처리(preprocessing)

by 선의공 2024. 1. 27.

 

 

이번 포스팅에서는

ImageDataGenerator() 를 이용해서 

이미지 데이터를 불러와 전처리해보겠습니다.

 

(학습하려고 찾아보니 ImageDataGenerator가 deprecated 되었군요.

찾아보니 2.9 버전 이상부터는

utils.image_dataset_from_directory와

수치화 된 데이터 형은 Dataset 형태를 사용하라고 하네요.

추가적으로 학습 후 포스팅 하겠습니다.)

 

 

 

 

 


 

1. ImageDataGenerator()

 

 

keras의 preprocessing의 image 모듈에 있습니다.

이미지를 변형하고 생성해주는 클래스입니다. 

https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator

 

tf.keras.preprocessing.image.ImageDataGenerator  |  TensorFlow v2.15.0.post1

Generate batches of tensor image data with real-time data augmentation.

www.tensorflow.org

 

파라미터가 엄청 많네요.

천천히 살펴보겠습니다.

featurewise_center 입력평균을 0으로 설정 할지 여부. (전처리 관련 파라미터 같습니다.)
samplewise_center 각 샘플 평균을 0으로 설정할지 여부.
featurewise_std_normalization 입력을 데이터세트의 표준편차로 나눔 여부.
samplewise_std_normalization 각 입력을 각각의 표준편차로 나눔 여부. 
zca_epsilon ZCA 화이트닝을 해주는 앱실론
zca_whitening ZCA 화이트닝을 해줄지 여부.
rotation_range 랜덤 회전 각도 범위.
width_shift_range 사진을 가로로 얼마나 이동할지 설정.
(0~1 이면 너비의 %, 1보다 크면 픽셀의 이동 수를 설정하는 거라고 하네요.)
height_shift_range 사진을 세로로 얼마나 이동할지 설정.
brightness_range 밝기 변화값 설정.
shear_range shear 각도설정. (깊이의 회전을 조정하는 각도인가요?...)
zoom_range 확대 정도.
channel_shift_range RGB 색변화. 
fill_mode "constant", "nearest", "reflect" or "wrap" 로 설정 가능하고 기본값은 "nearest"입니다.
빈 부분을 채우는 방법을 선택해 주라고 하는 것 같네요.
cval fill_mode 가 "constant"일때 사용 가능하다고 합니다.
horizontal_flip 좌우 뒤집기 여부.
vertical_flip 위아래 뒤집기 여부.
rescale 데이터 rescaling 값.
preprocessing_function 콜백 함수 같네요. 이미지의 크기와 확대가 끝나면 함수를 실행 해준다고 합니다.
data_format "channels_first", "chennels_last" 두 가지를 설정할 수 있고, 기본값은 "chennel_last"입니다.
channels_first 모드: (data개수, channels , 이미지 height, 이미지 width, ) 형태로 반환.
channels_last 모드: (data개수, 이미지 height, 이미지 width, channels) 형태로 반환.
validation_split validation data 잘라줄 비율. 
dtype 이미지 수치화시 데이터의 타입 지정.

 

 

 

 

ImageDataGenerator()에 구현된

메서드 살펴보겠습니다.

 

apply_transform()   이미지 변형을 설정하고 적용
(single 이미지에 대해서 적용하나보네요) 
flow()  입력한 x,y 데이터를 ImageDataGenerator에 설정된 값으로 랜덤하게 변형 후 반환
flow_from_dataframe() dataframe 형식 데이터를 ImageDataGenerator에 설정된 값으로 랜덤하게 변형 후 반환
flow_from_directory() 디렉토리 경로에 있는 데이터를 ImageDataGenerator에 설정된 값으로 랜덤하게 변형 후 반환

 

 

 


 

2. 이미지 읽어오고 전처리 하기

 

 

 

이미지는 kaggle에서 다운받은 일부를 사용하였습니다.

https://www.kaggle.com/competitions/cat-and-dog-classification-harper2022/data

 

Cat and Dog Classification | Kaggle

 

www.kaggle.com

 

 

 

고양이와 강아지는 폴더를 나눠 저장되어 있습니다.

 

ImageDataGenerator() 를 사용해서 데이터를 가져오는 경우

각 클래스의 설정이 필요하기 때문입니다.

 

이미지는 x값이 되고,  클래스는 y값이 됩니다. 

(분류에서는 데이터의 종류가 클래스가 됩니다

상단에 있는 것부터 0, 1, ... 의 클래스가 정해집니다.)

 

 

 

 

 

Cat 폴더에는 고양이 사진 5개 

Dog폴더에는 강아지 사진 11개가 들어있습니다.

Dog()폴더에는 11개의 강아지 사진이 담겨있습니다.

 

 

 

 

이제 이미지들의 사이즈를 동일하게 맞추고

0~1 값으로  scaling 하는 전처리와

 

디렉토리 경로에 있는 폴더의 이미지를

수치화된 데이터로 읽어오겠습니다.

 

 

ImageDataGenerator의 

rescale 값을 설정해줘

0~1 사이의 값을 갖는 데이터로 만들어주었습니다.

 

from keras.preprocessing.image import ImageDataGenerator

data_gen = ImageDataGenerator(
    rescale=1./255,
)

 

 

 

 

flow_from_directory() 함수를 사용해

이미지 크기를 설정해주고

이미지 데이터가 담긴 Iterator()를 가져왔습니다.

data_iter = data_gen.flow_from_directory(
    directory = image_path,
    target_size=(300,300),
    class_mode='binary', #이진분류 데이터설정,
    shuffle=True #섞기
)#Found 16 images belonging to 2 classes.

 

(참고)

반환값 Iterator()은 

auguments 

n : 정수형. 데이터 수.

batch_size: 정수형. 배치크기.(model.fit()의 batch_size와 동일한 개념입니다.)

shuffle : 부울형.데이터를 섞을지 여부

seed : 데이터 랜덤 시드

 

method

 next(), on_epoch_end(), reset()..

로 구성되어 있습니다.

 

 

 

 

next() 호출시

배치로 잘린 데이터의 (x,y)의 튜플 값이 반환됩니다.

x는 300x300 크기의 총 16개의

이미지 데이터가 담겼고,

y는 이미지의 종류 데이터가 담겨있습니다.

x = data_iter.next()[0] #(x,y) 튜플의 x값
y = data_iter.next()[1] #(x,y) 튜플의 y값
print(x.shape)#(16, 300, 300, 3)
print(y.shape)#(16, 2)

 

클래스를 확인해줍니다.

import numpy as np
print(np.unique(y))#[0. 1.]

 

 

 

이미지 시각화를 해보면

import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=2, ncols=8, figsize = (8,2))
for i in range(16):
    ax[i//8, i%8].imshow(x[i])
    ax[i//8, i%8].axis('off')
plt.show()

 

이미지 데이터가

잘 들어온 것을 확인할 수 있습니다.

 

 

 

 

 

 

 

다음 포스팅으로는

ImageDataGenerator()의 주목적

이미지 데이터 증강(Augument)

을 다뤄보겠습니다.

 

 

 

틀린점 있으면 지적부탁드립니다!