tensorflow

데이터 증강

jwjwvison 2022. 6. 27. 16:53
이미지 회전과 같은 무작위 변환을 적용하여 훈련 세트의 다양성을 증가시키는 기술인 데이터 증강의 예에 대해 정리하겠다.
 
 
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds

from tensorflow.keras import layers
from tensorflow.keras.datasets import mnist

 

데이터셋 다운로드
(train_ds,val_ds,test_ds),metadata=tfds.load('tf_flowers',
                                             split=['train[:80%]','train[80%:90%]','train[90%:]'],
                                             with_info=True,
                                             as_supervised=True)​
num_classes=metadata.features['label'].num_classes
print(num_classes)

get_label_name=metadata.features['label'].int2str

image,label=next(iter(train_ds))
_=plt.imshow(image)
_=plt.title(get_label_name(label))

 

 Keras 전처리 레이어 사용하기

 - 크기 빛 배율 조정하기

IMG_SIZE=180

resize_and_rescale=tf.keras.Sequential([
  layers.experimental.preprocessing.Resizing(IMG_SIZE,IMG_SIZE),
  layers.experimental.preprocessing.Rescaling(1./255)
  # 배율 조정 레이어는 픽셀 값을 [0,1]로 표준화한다.
  # [-1,1]을 원할경우, Rescaling(1./127.5, offset=-1)을 사용하면 된다.
])

result=resize_and_rescale(image)
plt.imshow(result)

print("Min and max pixel values:", result.numpy().min(), result.numpy().max())

 

 

 데이터 증강

 데이터 증강에도 전처리 레이어를 사용할 수 있다. 몇개의 전처리 레이어를 만들어 동일한 이미지에 반복적으로 적용해 보겠다.
data_augmentation=tf.keras.Sequential([
      layers.experimental.preprocessing.Rescaling(1./255),                             
      layers.experimental.preprocessing.RandomFlip('horizontal_and_vertical'),
      layers.experimental.preprocessing.RandomRotation(0.2)
])
image=tf.expand_dims(image,0)
# 배치 차원 추가

plt.figure(figsize=(10, 10))
for i in range(9):
  augmented_image = data_augmentation(image[0])
  ax = plt.subplot(3, 3, i + 1)
  plt.imshow(augmented_image)
  plt.axis("off")

layers.RandomContrast,\
layers.RandomCrop,\
layers.RandomZoom 등 데이터 증강에 사용할 수 있는 다양한 전처리 레이어가 있다.

 

전처리 레이어를 사용하는 두 가지 옵션

옵션1: 전처리 레이어를 모델의 일부로 만들기
 
model=tf.keras.Sequential([
    resize_and_rescale,
    data_augmentation,
    layers.Conv2D(16,3,padding='same',activation='relu'),
    layers.MaxPool2D()
])

 

이 경우 유의해야 할 두 가지 중요한 사항이 있다.

1. 데이터 증강은 나머지 레이어와 동기적으로 기기에서 실행되며 GPU 가속을 이용한다.

2. model.save를 사용하여 모델을 내보낼 때 전처리 레이어가 모델의 나머지 부분과 함께 저장된다. 나중에 이 모델을 배포하면 레이어 구성에 따라 이미지가 자동으로 표준화된다. 

참고: 데이터 증강은 테스트할 때 비활성화되므로 입력 이미지는 model.fit(model.evaluate 또는 model.predict가 아님) 호출 중에만 증강된다.

 

옵션 2: 데이터세트에 전처리 적용하기
이 접근 방식에서는 Dataset.map을 사용하여 증강 이미지 배치를 생성하는 데이터세트를 만든다. 

데이터 증강은 CPU에서 비동기적으로 이루어지며 차단되지 않는다. 아래와 같이 Dataset.prefetch를 사용하여 GPU에서 모델 훈련을 데이터 전처리와 중첩할 수 있다.
이 경우, 전처리 레이어는 model.save를 호출할 때 모델과 함께 내보내지지 않는다. 저장하기 전에 이 레이어를 모델에 연결하거나 서버측에서 다시 구현해야 한다. 훈련 후, 내보내기 전에 전처리 레이어를 연결할 수 있다.

 

데이터세트에 전처리 레이어 적용하기

 데이터 증강은 훈련 세트에만 적용해야 한다.
batch_size=32
AUTOTUNE=tf.data.experimental.AUTOTUNE

def prepare(ds,shuffle=False,augment=False):
  # resize and rescale all datasets
  ds=ds.map(lambda x,y: (resize_and_rescale(x),y),
            num_parallel_calls=AUTOTUNE)
  
  if shuffle:
    ds=ds.shuffle(1000)

  ds=ds.batch(batch_size)

  # use data augmentation only on the training set
  if augment:
    ds=ds.map(lambda x,y:(data_augmentation(x,training=True),y),
              num_parallel_calls=AUTOTUNE)
    
  # use buffered prefecting on all datasets
  return ds.prefetch(buffer_size=AUTOTUNE)
train_ds=prepare(train_ds,shuffle=True,augment=True)
val_ds=prepare(val_ds)
test_ds=prepare(test_ds)

 

 모델 훈련하기

model = tf.keras.Sequential([
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(num_classes)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
              
epochs=5
history=model.fit(train_ds,validation_data=val_ds,epochs=epochs)

 

 

참고:https://www.tensorflow.org/tutorials/images/data_augmentation?hl=ko