이 페이지는 Cloud Translation API를 통해 번역되었습니다.
Switch to English

이미지로드

TensorFlow.org에서보기 Google Colab에서 실행 GitHub에서 소스보기 노트북 다운로드

이 학습서는 두 가지 방법으로 이미지 데이터 세트를로드하고 전처리하는 방법을 보여줍니다. 먼저, 고급 Keras 전처리 유틸리티레이어를 사용 합니다. 다음으로 tf.data를 사용하여 처음부터 자체 입력 파이프 라인을 작성합니다.

설정

 import numpy as np
import os
import PIL
import PIL.Image
import tensorflow as tf
 
 print(tf.__version__)
 
2.3.0

꽃 데이터 세트 다운로드

이 튜토리얼에서는 수천 장의 꽃 사진 데이터 세트를 사용합니다. 꽃 데이터 세트에는 클래스 당 하나씩 5 개의 하위 디렉토리가 있습니다.

 flowers_photos/
  daisy/
  dandelion/
  roses/
  sunflowers/
  tulips/
 
 import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file(origin=dataset_url, 
                                   fname='flower_photos', 
                                   untar=True)
data_dir = pathlib.Path(data_dir)
 

다운로드 한 후 (218MB) 이제 꽃 사진 사본을 사용할 수 있습니다. 총 3670 개의 이미지가 있습니다 :

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

각 디렉토리에는 해당 유형의 꽃 이미지가 포함되어 있습니다. 다음은 장미입니다.

 roses = list(data_dir.glob('roses/*'))
PIL.Image.open(str(roses[0]))
 

png

 roses = list(data_dir.glob('roses/*'))
PIL.Image.open(str(roses[1]))
 

png

keras.preprocessing을 사용하여로드

image_dataset_from_directory를 사용하여 이러한 이미지를 디스크에서로드 하십시오 .

데이터 세트 만들기

로더에 대한 일부 매개 변수를 정의하십시오.

 batch_size = 32
img_height = 180
img_width = 180
 

모델을 개발할 때 유효성 검사 분할을 사용하는 것이 좋습니다. 교육에 이미지의 80 %를 사용하고 유효성 검사에 20 %를 사용합니다.

 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)
 
Found 3670 files belonging to 5 classes.
Using 2936 files for training.

 val_ds = tf.keras.preprocessing.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="validation",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)
 
Found 3670 files belonging to 5 classes.
Using 734 files for validation.

이러한 데이터 세트의 class_names 속성에서 클래스 이름을 찾을 수 있습니다.

 class_names = train_ds.class_names
print(class_names)
 
['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']

데이터 시각화

교육 데이터 세트의 처음 9 개 이미지는 다음과 같습니다.

 import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):
  for i in range(9):
    ax = plt.subplot(3, 3, i + 1)
    plt.imshow(images[i].numpy().astype("uint8"))
    plt.title(class_names[labels[i]])
    plt.axis("off")
 

png

이러한 데이터 세트를 사용하여 모델을 model.fit (이 자습서의 뒷부분에 표시)에 전달하여 모델을 학습 할 수 있습니다. 원하는 경우 데이터 세트를 수동으로 반복하고 이미지 배치를 검색 할 수도 있습니다.

 for image_batch, labels_batch in train_ds:
  print(image_batch.shape)
  print(labels_batch.shape)
  break
 
(32, 180, 180, 3)
(32,)

image_batch(32, 180, 180, 3) 모양의 텐서입니다. 이것은 180x180x3 모양의 32 개 이미지 묶음입니다 (마지막 치수는 색상 채널 RGB를 나타냄). label_batch 는 모양 (32,) 의 텐서이며 32 이미지에 해당하는 레이블입니다.

데이터 표준화

RGB 채널 값은 [0, 255] 범위에 있습니다. 신경망에는 이상적이지 않습니다. 일반적으로 입력 값을 작게 만들어야합니다. 여기서는 Rescaling 레이어를 사용하여 [0, 1] 에있는 값을 표준화합니다.

 from tensorflow.keras import layers

normalization_layer = tf.keras.layers.experimental.preprocessing.Rescaling(1./255)
 

이 레이어를 사용하는 방법에는 두 가지가 있습니다. map을 호출하여 데이터 세트에 적용 할 수 있습니다.

 normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]
# Notice the pixels values are now in `[0,1]`.
print(np.min(first_image), np.max(first_image)) 
 
0.0 0.96902645

또는 모델 정의 내에 계층을 포함시켜 배포를 단순화 할 수 있습니다. 우리는 여기서 두 번째 접근법을 사용할 것입니다.

성능을위한 데이터 세트 구성

I / O를 차단하지 않고 디스크에서 데이터를 생성 할 수 있도록 버퍼링 된 프리 페치를 사용해야합니다. 데이터를로드 할 때 사용해야하는 두 가지 중요한 방법입니다.

.cache() 는 첫 번째 에포크 (epoch) 동안 디스크에서 이미지를로드 한 후 이미지를 메모리에 유지합니다. 이렇게하면 모델을 훈련하는 동안 데이터 세트가 병목 현상이되지 않습니다. 데이터 세트가 너무 커서 메모리에 맞지 않는 경우이 방법을 사용하여 수행 가능한 온 디스크 캐시를 작성할 수도 있습니다.

.prefetch() 훈련하는 동안 데이터 전처리 및 모델 실행과 겹칩니다.

관심있는 독자는 두 가지 방법과 데이터 성능 안내서데이터 를 디스크에 캐시하는 방법에 대해 자세히 알아볼 수 있습니다.

 AUTOTUNE = tf.data.experimental.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
 

모델 훈련

완전성을 위해 방금 준비한 데이터 세트를 사용하여 간단한 모델을 학습하는 방법을 보여줍니다. 이 모델은 어떤 식 으로든 조정되지 않았습니다. 목표는 방금 만든 데이터 세트를 사용하여 역학을 보여주는 것입니다. 이미지 분류에 대한 자세한 내용은이 자습서를 방문하십시오.

 num_classes = 5

model = tf.keras.Sequential([
  layers.experimental.preprocessing.Rescaling(1./255),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(num_classes)
])
 
 model.compile(
  optimizer='adam',
  loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
  metrics=['accuracy'])
 
 model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=3
)
 
Epoch 1/3
92/92 [==============================] - 6s 66ms/step - loss: 1.3282 - accuracy: 0.4240 - val_loss: 1.1035 - val_accuracy: 0.5804
Epoch 2/3
92/92 [==============================] - 1s 11ms/step - loss: 1.0304 - accuracy: 0.5913 - val_loss: 0.9515 - val_accuracy: 0.6267
Epoch 3/3
92/92 [==============================] - 1s 11ms/step - loss: 0.8712 - accuracy: 0.6689 - val_loss: 0.9268 - val_accuracy: 0.6471

<tensorflow.python.keras.callbacks.History at 0x7f86d80ad128>

모델이 과적 합되었음을 나타내는 검증 정확도가 훈련 정확도와 비교하여 낮음을 알 수 있습니다. 이 자습서 에서 과적 합 및 과잉 축소 방법에 대해 자세히 알아볼 수 있습니다.

더 세밀한 제어를 위해 tf.data 사용

위의 keras.preprocessing 유틸리티는 이미지 디렉토리에서 tf.data.Dataset 을 작성하는 편리한 방법입니다. 보다 세밀한 제어를 위해 tf.data 사용하여 자체 입력 파이프 라인을 tf.data 있습니다. 이 섹션에서는 이전에 다운로드 한 zip 파일 경로부터 시작하여이를 수행하는 방법을 보여줍니다.

 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())
 
b'/home/kbuilder/.keras/datasets/flower_photos/roses/1445228333_59a07e0801.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/dandelion/14128835667_b6a916222c.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/roses/7551637034_55ae047756_n.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/dandelion/4574736702_b15ecf97d0_m.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/roses/6867597533_d65d1c39fb_n.jpg'

파일의 트리 구조를 사용하여 class_names 목록을 컴파일 할 수 있습니다.

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

데이터 세트를 학습 및 검증으로 분할하십시오.

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

다음과 같이 각 데이터 세트의 길이를 볼 수 있습니다.

 print(tf.data.experimental.cardinality(train_ds).numpy())
print(tf.data.experimental.cardinality(val_ds).numpy())
 
2936
734

파일 경로를 (img, label) 쌍으로 변환하는 간단한 함수를 작성하십시오.

 def get_label(file_path):
  # convert the path to a list of path components
  parts = tf.strings.split(file_path, os.path.sep)
  # The second to last is the class-directory
  one_hot = parts[-2] == class_names
  # Integer encode the label
  return tf.argmax(one_hot)
 
 def decode_img(img):
  # convert the compressed string to a 3D uint8 tensor
  img = tf.image.decode_jpeg(img, channels=3)
  # resize the image to the desired size
  return tf.image.resize(img, [img_height, img_width])
 
 def process_path(file_path):
  label = get_label(file_path)
  # load the raw data from the file as a string
  img = tf.io.read_file(file_path)
  img = decode_img(img)
  return img, label
 

Dataset.map 을 사용하여 image, label 쌍의 데이터 세트를 작성하십시오.

 # 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)
 
 for image, label in train_ds.take(1):
  print("Image shape: ", image.numpy().shape)
  print("Label: ", label.numpy())
 
Image shape:  (180, 180, 3)
Label:  2

성능을위한 데이터 세트 구성

이 데이터 세트로 모델을 학습 시키려면 데이터가 필요합니다.

  • 잘 섞는다.
  • 일괄 처리됩니다.
  • 가능한 빨리 배치를 사용할 수 있습니다.

이러한 기능은 tf.data API를 사용하여 추가 할 수 있습니다. 자세한 내용은 입력 파이프 라인 성능 안내서를 참조하십시오.

 def configure_for_performance(ds):
  ds = ds.cache()
  ds = ds.shuffle(buffer_size=1000)
  ds = ds.batch(batch_size)
  ds = ds.prefetch(buffer_size=AUTOTUNE)
  return ds

train_ds = configure_for_performance(train_ds)
val_ds = configure_for_performance(val_ds)
 

데이터 시각화

이 데이터 세트를 이전에 작성한 데이터 세트와 유사하게 시각화 할 수 있습니다.

 image_batch, label_batch = next(iter(train_ds))

plt.figure(figsize=(10, 10))
for i in range(9):
  ax = plt.subplot(3, 3, i + 1)
  plt.imshow(image_batch[i].numpy().astype("uint8"))
  label = label_batch[i]
  plt.title(class_names[label])
  plt.axis("off")
 

png

모델 교육 계속

위의 keras.preprocessing 의해 작성된 것과 유사한 tf.data.Dataset 을 수동으로 빌드했습니다. 모델 학습을 계속할 수 있습니다. 이전과 마찬가지로 실행 시간을 짧게 유지하기 위해 몇 가지 에포크 (epoch)를 훈련시킵니다.

 model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=3
)
 
Epoch 1/3
92/92 [==============================] - 2s 19ms/step - loss: 0.7267 - accuracy: 0.7272 - val_loss: 0.7963 - val_accuracy: 0.7098
Epoch 2/3
92/92 [==============================] - 1s 11ms/step - loss: 0.5384 - accuracy: 0.7987 - val_loss: 0.8067 - val_accuracy: 0.6894
Epoch 3/3
92/92 [==============================] - 1s 11ms/step - loss: 0.3382 - accuracy: 0.8770 - val_loss: 1.0317 - val_accuracy: 0.6662

<tensorflow.python.keras.callbacks.History at 0x7f87cd496320>

다음 단계

이 튜토리얼에서는 디스크에서 이미지를로드하는 두 가지 방법을 보여주었습니다. 먼저 Keras 전처리 레이어 및 유틸리티를 사용하여 이미지 데이터 세트를로드하고 전처리하는 방법을 배웠습니다. 다음으로, tf.data를 사용하여 처음부터 입력 파이프 라인을 작성하는 방법을 배웠습니다. 다음 단계로이 학습서 를 방문하여 데이터 기능 보강을 추가하는 방법을 학습 할 수 있습니다. tf.data에 대한 자세한 내용은이 안내서를 방문하십시오.