페이지

2022년 8월 1일 월요일

5.2.4 데이터 전처리

 데이터는 네트워크에 주입되기 전에 부동 소수타입의 텐서로 적절하게 전처리 되어 있어야 합니다. 지금은 데이터가 JPEG파일로 되어 있으므로 네트워크에 주입하려면 대략 다음 과정을 따릅니다.

1) 사진 파일을 읽습니다.

2) JPEG콘텐츠를 RGB픽셀 값으로 디코딩합니다.

3) 그다음 부동 소스 타입의 텐서로 변환합니다.

4) 픽셀 값(0에서 255 사이)의 스케일을 [0, 1]사이로 조정합니다(신경망은 작은 입력 값을 선호합니다).

좀 복잡하게 보일 수 있지만 다행히 케라스는 이런 단계를 자동으로 처리하는 유틸리티가 있습니다. 또 케라스에는 keras.preprocessing.image에 이미지 처리를 위한 헬퍼 도구들도 있습니다. 특히 ImageDataGenerator 클래스는 디스크에 있는 이미지 파일을 전처리된 배치 텐서로 바동으로 바꾸어 주는 파이썬 제너레이터(generator)를 만들어 줍니다. 이 캘래스를 사요해 보겠습니다.


from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
              train_dir,
              target_size=(150150),
              batch_size=20,
              class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
          validation_dir,
          target_size=(150150),
          batch_size=20,
          class_mode='binary'
)

파이썬 제너레이터 이해하기
파이썬 제너레이터(generator)는 반복자(iterator)처럼 작동하는 객체로 for ... in 연산자에
사용할 수 있습니다. 제너레이터는 yield 연산자를 사용하여 만듭니다.
다음 정수를 반환하는 제너레이터의 예입니다.

def generator():
    i = 0
    while True:
      i += 1
      yield i

for item in generator():
  print(item)
  if item > 4:
    break



다음과 같이 출력됩니다.
1 2 3 4 5

이 제너레이터의 출력 하나를 살펴보죠. 이 출력은 150 * 150 RGB 이미지의 배치
((20, 150, 150,3) 크기)와 이진 레이블의 배치((20,) 크기)입니다. 각 배치에는 20개의 샘플
(배치 크기)이 있습니다. 제너레이터는 이 배치를 무한정 만들어 냅니다. 타깃 폴더에 있는
이미지를 끝없이 반복합니다. 따라서 반복 루프 안 어디에선가 break문을 사용해야 합니다.

for data_batch, labels_batch in train_generator;
  print('배치 데이터 크리:', data_batch.shape)
  print('배치 레이블 크기:', labels_batch.shape)
  break


배치 데이터 크기: (20, 150, 150, 3)
배치 레이블 크기: (20,)

제너레이터를 사용한 데이터에 모델을 훈련시켜 보겠습니다. fit_generator 메서드는 fit 메서드
와 동일하되 데이터 제너레이터를 사용할 수 있습니다. 이 메서드는 첫 번째 매배변수로 입력과
타깃의 배치를 끝없이 반환하는 파이썬 제너레이터를 기대합니다. 데이터가 끝없이 생성되기
때문에 케라스 모델에 하나의 에포크를 정의하기 위해 제너레이터로부터 얼마나 많은 샘플을 뽑을것인지
알려주어야 합니다. steps_per_epoch 매개변수에서 이를 설정합니다. 제너레이터로부터
steps_per_epoch개의 배치만큼 뽑은 후, 즉 steps_per_epoch횟수만큼 경사 하강법 단곌르 실행
한 후에 훈련 프로세스는 다음 에포크로 넘어갑니다. 여기서는 20개의 샘플이 하나의 배치이므로
2,000개의 샘플을 모두 처리할 때까지 100개의 배치를 뽑을 것입니다.
fit_generator를 사용할 때 fit 메서드와 마찬가지로 validation_Data 매개변수를 전달할 수 있
습니다. 이 매개변수에는 데이터 제너레이터도 가능하지만 넘파이 배열의 튜플도 가능합니다.
validation_data로 제너레이터를 전달하면 검증 데이터의 배치를 끝없이 반환합니다. 따라서 검증
데이터 제너레이터에서 얼마나 많은 배치를 추출하여 평가할지 validation_steps매개변수에
지정해야 합니다.
history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=30,
      validation_data=validation_generator,
      validation_steps=50
)
훈련이 끝나면 항상 모델을 저장하는 것이 좋은 습관입니다.
model.save('cat_and_dogs_smll_1.h5')
훈련 데이터와 검증 데이터에 대한 모델의 손실과 정확도를 그래프로 나타내보겠습니다.

import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1len(acc) +1)

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b' label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

이 그래프는 과대적합의 특성을 보여 줍니다. 훈련 정확도가 시간이 지남에 따라 선형적으로 증가
해서 거의 100%에 도달합니다. 반면에 검증 정확도는 70-72%에서 멈추었습니다. 검증 손실은
다섯 번의 에포크만에 최솟값에 다다른 이후 더 이상 진전되지 않았습니다. 반면에 훈련 손실은
거의 0에 도달할 때까지 선형적으로 계속 감소합니다.
비교적 훈련 샘플의 수(2,000개)가 적기 때문에 과대적합이 가장 중요한 문제입니다. 드롭아웃이나
가중치 감소(L2 규제)처럼 과대적합을 감소시킬 수 있는 여러 가지 기법들을 배웠씁니다. 여기
에서는 검퓨터 비전에 특화되어 있어서 딥러닝으로 이미지를 다룰 때 매우 일반적으로 사용되는
새로운 방법인 데이터 증식을 시도해 보겠습니다.


댓글 없음: