C.W.K.
Stream
Lesson 06 of 06 · published

실전 이미지 로딩 + 안티패턴

~13 min · image-loading, antipatterns, debugging

Level 0Level 0
0 XP0/78 lessons0/17 achievements
0/100 XP to next level100 XP to go0% complete

실전에서 진짜 짜게 될 pipeline

대부분 실전 이미지 프로젝트는 클래스별로 정리된 JPEG/PNG 디렉토리가 있어. 두 경로: 빠른 실험엔 high-level keras.utils.image_dataset_from_directory, 제어 필요하면 tf.io.read_file로 수동 pipeline.

피해야 할 4가지 안티패턴:

  1. Batch 후 shuffle — element 아니라 batch만 셔플됨.
  2. Prefetch 없음 — batch 사이 GPU 정지.
  3. Augment된 데이터 cache — 매 epoch 같은 augmentation.
  4. Num_parallel_calls hardcodeAUTOTUNE이 적응하는데 굳이.

느릴 땐 TensorBoard Input Pipeline Analyzer (Profile 탭) 열어서 "Input Bound: 80%" 찾아 — 데이터 로딩이 model 계산이 아니라 병목이라는 표준 신호.

Code

Option A: image_dataset_from_directory·python
import tensorflow as tf
from tensorflow import keras

# Directory layout:
# data/train/cats/*.jpg
# data/train/dogs/*.jpg

IMG_SIZE = (224, 224)
BATCH_SIZE = 32
AUTOTUNE = tf.data.AUTOTUNE

train_ds = keras.utils.image_dataset_from_directory(
    "data/train",
    image_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    label_mode='int',           # or 'categorical' for one-hot
    shuffle=True,
    seed=42,
    validation_split=0.2,
    subset='training',
)
class_names = train_ds.class_names

normalization = keras.layers.Rescaling(1./255)

def augment_image(image, label):
    image = tf.image.random_flip_left_right(image)
    image = tf.image.random_brightness(image, 0.1)
    image = tf.image.random_contrast(image, 0.9, 1.1)
    return image, label

train_ds = (train_ds
    .map(lambda x, y: (normalization(x), y), num_parallel_calls=AUTOTUNE)
    .cache()
    .map(augment_image, num_parallel_calls=AUTOTUNE)
    .prefetch(AUTOTUNE))
Option B: manual pipeline (more control)·python
import tensorflow as tf
import pathlib

data_dir = pathlib.Path("data/train")
image_paths = list(data_dir.glob("*/*.jpg"))
class_names = sorted([p.name for p in data_dir.iterdir() if p.is_dir()])
class_to_idx = {n: i for i, n in enumerate(class_names)}
labels = [class_to_idx[p.parent.name] for p in image_paths]

def load_and_preprocess(path, label):
    raw = tf.io.read_file(path)
    image = tf.io.decode_image(raw, channels=3, expand_animations=False)
    image = tf.image.resize(image, [224, 224])
    image = tf.cast(image, tf.float32) / 255.0
    return image, label

ds = (tf.data.Dataset.from_tensor_slices(
        ([str(p) for p in image_paths], labels))
    .shuffle(len(image_paths), seed=42)
    .map(load_and_preprocess, num_parallel_calls=tf.data.AUTOTUNE)
    .cache()
    .batch(32, drop_remainder=True)
    .prefetch(tf.data.AUTOTUNE))

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.