텐서플로우

[tf.data] TensorFlow Input Pipelines

망나 2021. 4. 20. 15:12

딥러닝 기법을 사용할 때, 가장 중요하다고 생각되는 부분은 단연 데이터입니다. 데이터를 수집하고 전처리하는 등의 데이터 준비 과정이 최종 모델의 정확도에 가장 큰 부분을 차지한다고 생각합니다. 공들여 준비한 데이터를 모델 훈련에 사용할 때 다양한 데이터 입력 방법들이 존재합니다.

 

이번 포스트에서는 준비된 이미지 데이터를 사용하기 위한 입력 파이프라인 방법에 대해서 정리해보도록 하겠습니다.

 

 

tf.data.Dataset

 

classes = os.listdir(path)
filenames = glob(path + '/*/*')
random.shuffle(filenames)
labels = [classes.index(name.split('/')[-2]) for name in filenames]

 

위 4줄짜리 코드로 모델 훈련에 사용할 데이터의 filename과 label을 저장하고 모델의 성능 향상을 위해 random.shuffle을 활용했습니다.

 

def parse_image(filename):
    image = tf.io.read_file(filename) # 이미지 파일 읽기
    image = tf.image.decode_jpeg(image, channels=3) # JPEG-encoded -> uint8 tensor (RGB format)
    image = tf.image.resize(image, [IMG_SIZE, IMG_SIZE]) # 이미지 사이즈 변경
    return image

filenames_ds = tf.data.Dataset.from_tensor_slices(filenames)
images_ds = filenames_ds.map(parse_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)
labels_ds = tf.data.Dataset.from_tensor_slices(labels)

ds = tf.data.Dataset.zip((images_ds, labels_ds)) # 이미지, 라벨 병합

 

이후 tf.data.Dataset.from_tensors(), tf.data.Dataset.from_tensor_slices(), 또는 tf,data.TFRecordDataset()을 사용하여 데이터를 생성할 수 있습니다. 이때, num_parallel_calls를 세팅해 병렬 처리로 속도를 최적화 할 수 있습니다.

 

def configure_for_performance(ds):
    ds = ds.shuffle(buffer_size=1000)
    ds = ds.batch(batch_size)
    ds = ds.repeat()
    ds = ds.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
    return ds
    
    
ds = configure_for_performance(ds)

 

마지막으로 configure_for_performance 함수를 통해 데이터를 반복해서 모델을 학습합니다.

 

 

 

전체 함수 (데이터 입력 파이프라인)

def make_dataset(path, batch_size):

  def parse_image(filename):
    image = tf.io.read_file(filename)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, [IMG_SIZE, IMG_SIZE])
    return image

  def configure_for_performance(ds):
    ds = ds.shuffle(buffer_size=1000)
    ds = ds.batch(batch_size)
    ds = ds.repeat()
    ds = ds.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
    return ds

  classes = os.listdir(path)
  filenames = glob(path + '/*/*')
  random.shuffle(filenames)
  labels = [classes.index(name.split('/')[-2]) for name in filenames]

  filenames_ds = tf.data.Dataset.from_tensor_slices(filenames)
  images_ds = filenames_ds.map(parse_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)
  labels_ds = tf.data.Dataset.from_tensor_slices(labels)
  ds = tf.data.Dataset.zip((images_ds, labels_ds))
  ds = configure_for_performance(ds)

  return ds

 

위 입력 파이프라인 함수를 활용해서 다음과 같이 모델 훈련이 가능합니다.

from glob import glob
import math

def use_tf_data(path):
  dataset = make_dataset(path, 32)

  num_classes = len(os.listdir(path))
  num_images = len(glob(path + '/*/*'))
  model = build_model(num_classes)

  model.fit(dataset, batch_size=32, epochs=5, steps_per_epoch=math.ceil(num_images/32))

 

 

 

데이터 증강 (tf.image)

  • 이미지 뒤집기 - tf.image.flip_left_right(image)
  • 이미지 회색조 - tf.image.rgb_to_grayscale(image)
  • 이미지 채도 수정 - tf.image.adjust_saturation(image, 3)
  • 이미지 밝기 수정 - tf.image.adjust_brightness(image, 0.4)
  • 이미지 자르기 - tf.image.central_crop(image, central_fraction=0.5)
  • 이미지 회전 - tf.imagerot90(image)

 

 

참고

What is the Best Input Pipeline to Train Image Classification Models with tf.keras?

'텐서플로우' 카테고리의 다른 글

Tensorflow 2.0 Install  (0) 2020.05.18