딥러닝 - ImageDataGenerator
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D
from keras.layers import Flatten,Dense
ImageDataGenerator는 이미지 데이터를 전처리하거나 증식할 때 사용하는 도구로서
회전, 이동, 확대, 축소, 뒤집기 등 다양한 변형을 사용하여
훈련 데이터의 다양성을 높여 모델의 일반화 성능을 향상시킬 수 있다
또한 픽셀 값의 스케일링, 정규화, 이미지 크기 조정도 가능하다
flow_from_directory( )와 같은 메소드를 사용하여 디렉토리에서 이미지 데이터를 읽을 수 있다
이는 메모리 효율적인 데이터 로딩을 가능하게 한다
def build_model() :
model = Sequential()
model.add(Conv2D( 32, (3, 3), activation = 'relu',input_shape = ( 150, 150, 3 ) ) )
model.add(MaxPooling2D(2, 2) ) #(2행2열),(2칸씩 점프)
model.add(Conv2D( 64, (3, 3), activation = 'relu' ) )
model.add(MaxPooling2D(2, 2) )
model.add(Conv2D( 128, (3, 3), activation = 'relu' ) )
model.add(MaxPooling2D(2, 2) )
model.add(Conv2D( 128, (3, 3), activation = 'relu' ) )
model.add(MaxPooling2D(2, 2) )
model.add(Flatten())
model.add(Dense( 512,activation = 'relu' ) )
model.add(Dense( 1, activation = 'sigmoid' ) )
model.compile(loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics=['accuracy'] )
return model
model = build_model()
ImageDataGenerator 라이브러리 이용
파일로 존재하는 데이터를 메모리로 준비
ImageDataGenerator( rescale = 1 / 255 )
파일을 Numpy로 바꿔서 피쳐스케일링(정규화(MinMax)) 후 메모리로 만드는 코드
아래는 이미지 증강까지 해서 메모리에 데이터 생성하는 코드다
train_datagen = ImageDataGenerator( rescale = 1 / 255,
rotation_range = 40,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = 'nearest')
위에서 언급했던
rotation_range = 40, 회전
width_shift_range = 0.2, 수평이동
height_shift_range = 0.2, 수직이동
zoom_range = 0.2, 확대/축소 = 숫자를 하나만 쓰게되면 ±퍼센트로 확대과 축소가 되며
( a, b )로 적게 되면 a가 축소 b가 확대로 적용된다
horizontal_flip = True, 좌우반전 / vertical_flip = false 상하반전
fill_mode = 'nearest' 이미지를 변형할 때 경계 밖으로 나가는 픽셀들을 가장 가까운 경계 픽셀의 값으로 채운다
이미지 변형으로 인한 왜곡을 최소화할 수 있다
보편적으로 쓰이는 nearest는 가장 가까운 경계 픽셀의 값을 사용하여 경계 밖을 채우며
경계가 부드럽게 연결되며, 이미지 변형으로 인한 왜곡을 최소화할 수 있기에
다른 모드보다 많이 쓰인다
shear_range = 0.2, 전단 변형 = 대각선 방향으로 늘어나거나 압축되는 효과 (아래 그림 참고)
train_generator = train_datagen.flow_from_directory(train_dir,
target_size = (150, 150),
class_mode = 'binary')
위에서 적었듯이
flow_from_directory( )를 이용하여 이미지파일 = 데이터를 읽을 수 있다
이때 train_dir는 X_train , y_train를 다 가지고 있는데 뒤에 후술하겠다
target_size는 위에서 만든 모델의 input_shape과 일치 해야 한다(행과 열만)
이미지 크기가 서로 다르다면 모델 훈련에 영향을 주기 때문에
로드된 모든 이미지가 150x150 픽셀로 크기 조정될 것을 의미한다
class_mode는 레이블(클래스) 데이터의 형식을 지정하는 옵션
'binary'는 이진 분류 문제(binary classification)에 사용
즉, 해당 문제가 0과 1의 이진 분류 문제라고 지정해주는것
2000개의 이미지와 2개의 클래스를 찾은것을 확인 할 수 있다
train_generator는 X_train , y_train을 다 가지고 있다
훈련용 데이터인 train폴더
그러니까 X_train이 되는 데이터들이
cats 와dogs 안에 존재하기에
y_train이 cats와 dogs로 자연스럽게 들어가게된다
val_datagen = ImageDataGenerator( rescale = 1 / 255 )
val_generator = val_datagen.flow_from_directory(val_dir,
target_size = ( 150, 150 ),
class_mode = 'binary')
validation 데이터들도 똑같이 준비 해준다
early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience = 5)
epoch_history = model.fit(train_generator,
epochs = 20,
validation_data = val_generator,
callbacks = [ early_stop ] )
해당 모델은
딥러닝의 결과를 얻기까지 상당한 시간이 소요되며
아무리 잘 나와도 정답률이 70~80%정도라서
그렇게 좋은 모델이라고 할 수 없겠지만...
이런 과정도 있다는것을 알아두자