Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python과 TensorFlow tf.data로 커스텀 입력 파이프라인 구축하기 – 더 세밀한 데이터 제어 방법

tf.data는 데이터셋 내의 데이터를 섞어(shuffle) 모든 유형의 데이터가 최대한 고르게 분포되도록 함으로써, 모델 구축 파이프라인을 세밀하게 커스터마이징할 수 있도록 도와주는 강력한 API입니다.

tf.data를 사용해야 하는 이유

keras.preprocessing 유틸리티는 이미지 디렉터리만으로 간편하게 tf.data.Dataset을 생성할 수 있는 좋은 출발점입니다. 하지만 데이터 로딩 순서, 셔플 방식, 학습·검증 세트 분할 비율 등을 직접 제어하고 싶다면 tf.data를 활용해 커스텀 입력 파이프라인을 직접 작성하는 것이 훨씬 유연합니다.

실습 환경 및 데이터셋 소개

이 튜토리얼에서는 수천 장의 꽃 이미지를 포함하는 꽃(flowers) 데이터셋을 사용합니다. 이 데이터셋은 5개의 하위 디렉터리로 구성되어 있으며, 각 하위 디렉터리는 하나의 클래스(꽃 종류)에 해당합니다.

코드는 Google Colaboratory(Colab)에서 실행됩니다. Colab은 브라우저에서 별도 설정 없이 Python 코드를 실행할 수 있게 해주며, GPU에 무료로 접근할 수 있다는 장점이 있습니다. Colaboratory는 Jupyter Notebook을 기반으로 구축되었습니다.

커스텀 입력 파이프라인 작성하기

아래 코드는 파일 경로 목록을 생성하고, 데이터를 섞은 뒤, 학습 세트와 검증 세트로 분할하는 과정을 보여줍니다.

print("Defining customized input pipeline")
list_ds = tf.data.Dataset.list_files(str(data_dir/'*/*'), shuffle=False)
list_ds = list_ds.shuffle(image_count, reshuffle_each_iteration=False)

for f in list_ds.take(5):
    print(f.numpy())

class_names = np.array(sorted([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"]))
print(class_names)

print("The dataset is split into training and validation set")
val_size = int(image_count * 0.2)
train_ds = list_ds.skip(val_size)
val_ds = list_ds.take(val_size)
print("Length of each subset is displayed below")
print(tf.data.experimental.cardinality(train_ds).numpy())
print(tf.data.experimental.cardinality(val_ds).numpy())

코드 출처: https://www.tensorflow.org/tutorials/load_data/images

실행 결과

Defining customized input pipeline
b'/root/.keras/datasets/flower_photos/dandelion/14306875733_61d71c64c0_n.jpg'
b'/root/.keras/datasets/flower_photos/dandelion/8935477500_89f22cca03_n.jpg'
b'/root/.keras/datasets/flower_photos/sunflowers/3001531316_efae24d37d_n.jpg'
b'/root/.keras/datasets/flower_photos/daisy/7133935763_82b17c8e1b_n.jpg'
b'/root/.keras/datasets/flower_photos/tulips/17844723633_da85357fe3.jpg'
['daisy' 'dandelion' 'roses' 'sunflowers' 'tulips']
The dataset is split into training and validation set
Length of each subset is displayed below
2936
734

코드 상세 설명

  • list_files(): 지정된 디렉터리 패턴(*/*)에 일치하는 모든 이미지 파일 경로를 tf.data.Dataset 형태로 불러옵니다.
  • shuffle(): 전체 이미지 개수(image_count)를 버퍼 크기로 지정해 데이터를 완전히 섞고, reshuffle_each_iteration=False 옵션으로 매 에포크마다 재셔플되지 않도록 합니다. 이를 통해 클래스별 데이터가 학습 과정에서 고르게 분포됩니다.
  • class_names 생성: 파일 시스템의 디렉터리 트리 구조를 활용해 LICENSE.txt를 제외한 폴더 이름들로 클래스 이름 목록을 자동으로 작성합니다.
  • skip()과 take()를 통한 분할: 전체 데이터의 20%를 검증 세트로, 나머지 80%를 학습 세트로 분할합니다. skip(val_size)는 앞부분을 건너뛰고, take(val_size)는 앞부분만 가져오는 방식입니다.
  • cardinality(): tf.data.experimental.cardinality()를 사용해 각 서브셋에 포함된 요소 개수를 확인할 수 있습니다. 실행 결과 학습 세트 2,936개, 검증 세트 734개로 분할되었음을 알 수 있습니다.

정리

이처럼 tf.data를 활용하면 keras.preprocessing보다 훨씬 세밀하게 데이터 파이프라인을 제어할 수 있습니다. 파일 경로 로드부터 셔플, 클래스 이름 추출, 학습·검증 세트 분할까지 모든 단계를 명시적으로 관리할 수 있어, 복잡한 데이터 전처리 요구사항이 있는 프로젝트에서 특히 유용합니다.