본문 바로가기
Data Science/Deep Learning

Tensorflow 이미지 로드하는 방법

by Queen2 2022. 11. 14.
728x90
반응형

오늘은 텐서플로우를 통해 이미지 데이터를 로드하는 법을 알아보겠습니다.

 

1. tf.keras.utils.get_file 사용하기

tf.keras.utils.get_file(
    fname=None,
    origin=None,
    untar=False,
    md5_hash=None,
    file_hash=None,
    cache_subdir='datasets',
    hash_algorithm='auto',
    extract=False,
    archive_format='auto',
    cache_dir=None
)

 

어떤 파일 fnameorigin이라는 url 장소에서 가져와라는 기능인데요

 

path_to_downloaded_file = tf.keras.utils.get_file(
    "flower_photos",
    "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz",
    untar=True)

 

이런식으로 파일을 어디서 가져와라고 지정을 하고 나서는 아래처럼 pathlib.Path으로 경로를 호출하도록 연결합니다

 

path_to_downloaded_file = pathlib.Path(path_to_downloaded_file)

#데이터가 들어있는 파일의 이미지 개수를 보고 싶을 때
image_count = len(list(path_to_downloaded_file.glob('*/*.jpg')))

#특정 이름의 파일을 열어서 보고 싶을 때
roses = list(path_to_downloaded_file.glob('roses/*'))
PIL.Image.open(str(roses[0]))

**여기서 glob 모듈은 괄호 내부의 패턴을 일치하는 경로명을 모두 찾아서 반환하는 기능을 가집니다

 


 

2. tf.keras.preprocessing.image_dataset_from_directory 사용하기

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

좀 더 직관적이고 짧게 데이터셋 호출과 전처리를 동시에 처리할 수 있는 기능입니다.

 

사용이 쉽고 간편하지만, 만약에 전처리를 좀 더 섬세하게 하고 싶다면 텐서플로우 홈페이지에서는

tf.data.Dataset을 이용해서 별도의 전처리 함수를 만들어 파이프라인 처리를 할 것을 추천하고 있습니다.

 

공식홈페이지의 예시를 보겠습니다.

 

image_count = len(list(data_dir.glob('*/*.jpg')))

list_ds = tf.data.Dataset.list_files(str(data_dir/'*/*'), shuffle=False)
list_ds = list_ds.shuffle(image_count, reshuffle_each_iteration=False)

 

tf.data.Dataset에서 file 명의 리스트를 얻어서 shuffle을 시킨뒤, 아래처럼 훈련과 검증 데이터로 분리했습니다.

 

val_size = int(image_count * 0.2)
train_ds = list_ds.skip(val_size)
val_ds = list_ds.take(val_size)

 

공식홈페이지에 나온만큼 전처리를 위한 함수들이 깔끔하고 활용도가 높을 것 같아서 가져와봤습니다

 

#파일경로를 리스트화해서 class_names인 레이블을 가져오도록 함
def get_label(file_path):
  parts = tf.strings.split(file_path, os.path.sep)
  one_hot = parts[-2] == class_names
  return tf.argmax(one_hot)
  
#jpeg 이미지를 uint8 텐서로 변환하고 사이즈를 재조정합니다
 def decode_img(img):
  img = tf.io.decode_jpeg(img, channels=3)
  return tf.image.resize(img, [img_height, img_width])
  
 #위 함수들을 활용해서 파일경로(file_paht)에서 (이미지,레이블) 쌍이 반환되도록 합니다
 def process_path(file_path):
  label = get_label(file_path)
  img = tf.io.read_file(file_path)
  img = decode_img(img)
  return img, label

 

이렇게 작성한 함수는 파이썬 map 함수를 통해 적용할 수 있습니다.

 

# Set `num_parallel_calls` so multiple images are loaded/processed in parallel.
train_ds = train_ds.map(process_path, num_parallel_calls=AUTOTUNE)
val_ds = val_ds.map(process_path, num_parallel_calls=AUTOTUNE)

 

 

 

Source:

https://docs.python.org/ko/3/library/glob.html

https://www.tensorflow.org/api_docs/python/tf/keras/utils/get_file

https://www.tensorflow.org/tutorials/load_data/images#%EA%BD%83_%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%84%B8%ED%8A%B8_%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C%ED%95%98%EA%B8%B0

 

728x90
반응형

댓글