이미지 로드 및 전처리하기
고급 Keras 전처리 유틸리티 및 레이어를 사용한다. 다음으로 tf.data를 사용하여 처음부터 자체 입력 파이프라인을 작성한다.
설정
import numpy as np
import os
import PIL
import PIL.Image
import tensorflow as tf
import tensorflow_datasets as tfds
print(tf.__version__)
꽃 데이터세트 다운로드하기
수천 장의 꽃 사진 데이터세트를 사용한다. 꽃 데이터세트에는 클래스당 하나씩 5개의 하위 디렉토리가 있다.
flowers_photos/
daisy/
dandelion/
roses/
sunflowers/
tulips/
(참고: 모든 이미지에는 CC-BY 라이선스가 있으며 크리에이터는 LICENSE.txt 파일에 나열된다.)
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)
다운로드한 후, 꽃 사진의 사본을 사용할 수 있다. 총 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]))
roses = list(data_dir.glob('roses/*'))
PIL.Image.open(str(roses[1]))
tf.keras.preprocessing을 사용하여 로드하기
tf.keras.preprocessing.image_dataset_from_directory를 사용하여 이러한 이미지를 디스크에서 로드한다.
(참고: 이 섹션에 소개된 Keras Preprocesing 유틸리티 및 레이어는 현재 실험 중이며 변경될 수 있다.)
데이터세트 만들기
로더를 위해 일부 매개변수를 정의한다.
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")
이러한 데이터세트를 사용하는 모델을 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개 이미지에 해당하는 레이블이다.
(참고: 이들 텐서 중 하나에서 .numpy()를 호출하여 numpy.ndarray로 변환할 수 있다.)
데이터 표준화하기
RGB 채널 값은 [0, 255] 범위에 있다. 이것은 신경망에 이상적이지 않다. 일반적으로 입력 값을 작게 만들어야 한다. 여기서는 tf.keras.layers.experimental.preprocessing.Rescaling 레이어를 사용하여 [0, 1] 범위에 있도록 값을 표준화한다.
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
또는 모델 정의 내에 레이어를 포함하여 배포를 단순화할 수 있다. 여기서는 두 번째 접근법을 사용할 것이다.
(참고: 픽셀 값을 [-1,1]으로 조정하려면 대신 Rescaling(1./127.5, offset=-1)를 작성할 수 있다.)
(참고: 이전에 tf.keras.preprocessing.image_dataset_from_directory의 image_size 인수를 사용하여 이미지 크기를 조정했다. 모델에 크기 조정 논리를 포함하려면 tf.keras.layers.experimental.preprocessing.Resizing 레이어를 대신 사용할 수 있다.)
성능을 위한 데이터세트 구성하기
버퍼링된 프리페치를 사용하여 I/O를 차단하지 않고 디스크에서 데이터를 생성한다. 데이터를 로드할 때 다음 두 가지 중요한 메서드를 사용해야 한다.
.cache()는 첫 번째 epoch 동안 디스크에서 이미지를 로드한 후 이미지를 메모리에 유지한다. 이렇게 하면 모델을 훈련하는 동안 데이터세트가 병목 상태가 되지 않는다. 데이터세트가 너무 커서 메모리에 맞지 않는 경우, 이 메서드를 사용하여 성능이 높은 온디스크 캐시를 생성할 수도 있다.
.prefetch()는 훈련 중에 데이터 전처리 및 모델 실행과 겹친다.
데이터 성능 가이드에서 두 가지 메서드와 디스크에 데이터를 캐시하는 방법에 대해 자세히 알아볼 수 있다.
AUTOTUNE = tf.data.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([
tf.keras.layers.experimental.preprocessing.Rescaling(1./255),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(num_classes)
])
model.compile(
optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
(참고: 몇 개의 epoch에 대해서만 훈련하므로 이 튜토리얼은 빠르게 진행된다.)
model.fit(
train_ds,
validation_data=val_ds,
epochs=3
)
Epoch 1/3
92/92 [==============================] - 4s 21ms/step - loss: 1.2970 - accuracy: 0.4404 - val_loss: 1.1139 - val_accuracy: 0.5586
Epoch 2/3
92/92 [==============================] - 1s 11ms/step - loss: 1.0270 - accuracy: 0.5886 - val_loss: 0.9677 - val_accuracy: 0.6185
Epoch 3/3
92/92 [==============================] - 1s 11ms/step - loss: 0.8740 - accuracy: 0.6649 - val_loss: 0.9886 - val_accuracy: 0.5967
<keras.callbacks.History at 0x7f14800d14d0>
(참고: model.fit을 사용하는 대신 사용자 정의 훈련 루프를 작성할 수도 있다. 자세한 내용은 이 튜토리얼을 참조하면 된다.)
검증 정확도가 훈련 정확도에 비해 낮으므로 모델이 과대적합되었음을 알 수 있다. 이 튜토리얼에서 과대적합 및 이를 줄이는 방법에 대해 자세히 알아볼 수 있다.
https://www.tensorflow.org/tutorials/load_data/images?hl=ko
'DNN with Keras > TensorFlow' 카테고리의 다른 글
[TensorFlow] CSV 전처리 (1) (0) | 2022.06.16 |
---|---|
[TensorFlow] 이미지 전처리 (2) (0) | 2022.06.16 |
[TensorFlow] Keras Tuner (0) | 2022.06.15 |
[TensorFlow] 모델 저장 / 복원 (2) (0) | 2022.06.15 |
[TensorFlow] 모델 저장 / 복원 (1) (0) | 2022.06.15 |