Catat tanggalnya! Google I / O mengembalikan 18-20 Mei Daftar sekarang
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Memuat gambar

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Tutorial ini menunjukkan cara memuat dan memproses sebelumnya kumpulan data gambar dengan tiga cara. Pertama, Anda akan menggunakan utilitas dan lapisan praproses Keras tingkat tinggi untuk membaca direktori gambar pada disk. Selanjutnya, Anda akan menulis pipeline input Anda sendiri dari awal menggunakan tf.data . Terakhir, Anda akan mendownload kumpulan data dari katalog besar yang tersedia di Set Data TensorFlow .

Mendirikan

import numpy as np
import os
import PIL
import PIL.Image
import tensorflow as tf
import tensorflow_datasets as tfds
print(tf.__version__)
2.4.1

Unduh kumpulan data bunga

Tutorial ini menggunakan kumpulan data beberapa ribu foto bunga. Kumpulan data bunga berisi 5 sub-direktori, satu per kelas:

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)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
228818944/228813984 [==============================] - 5s 0us/step

Setelah mengunduh (218MB), Anda sekarang memiliki salinan foto bunga yang tersedia. Ada total 3670 gambar:

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

Setiap direktori berisi gambar dari jenis bunga tersebut. Berikut beberapa mawar:

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

Muat dengan menggunakan keras.preprocessing

Mari kita muat gambar ini dari disk menggunakan image_dataset_from_directory .

Buat set data

Tentukan beberapa parameter untuk loader:

batch_size = 32
img_height = 180
img_width = 180

Praktik yang baik untuk menggunakan pemisahan validasi saat mengembangkan model Anda. Kami akan menggunakan 80% gambar untuk pelatihan, dan 20% untuk validasi.

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.

Anda dapat menemukan nama kelas dalam atribut class_names pada class_names data ini.

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

Visualisasikan datanya

Berikut adalah 9 gambar pertama dari set data pelatihan.

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

Anda dapat melatih model menggunakan kumpulan data ini dengan meneruskannya ke model.fit (ditampilkan nanti dalam tutorial ini). Jika mau, Anda juga dapat melakukan iterasi secara manual atas kumpulan data dan mengambil kumpulan gambar:

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

image_batch adalah tensor bentuk (32, 180, 180, 3) . Ini adalah kumpulan 32 gambar dengan bentuk 180x180x3 (dimensi terakhir mengacu pada saluran warna RGB). label_batch adalah tensor bentuk (32,) , ini adalah label yang sesuai dengan 32 gambar.

Standarisasi data

Nilai saluran RGB berada dalam kisaran [0, 255] . Ini tidak ideal untuk jaringan saraf; secara umum Anda harus berusaha untuk membuat nilai masukan Anda kecil. Di sini, kami akan membakukan nilai menjadi [0, 1] dengan menggunakan lapisan Rescaling.

from tensorflow.keras import layers

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

Ada dua cara untuk menggunakan lapisan ini. Anda dapat menerapkannya ke dataset dengan memanggil 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

Atau, Anda dapat menyertakan lapisan di dalam definisi model Anda untuk menyederhanakan penerapan. Kami akan menggunakan pendekatan kedua di sini.

Konfigurasi set data untuk kinerja

Mari pastikan untuk menggunakan buffered prefetching sehingga kita dapat menghasilkan data dari disk tanpa I / O menjadi pemblokiran. Ini adalah dua metode penting yang harus Anda gunakan saat memuat data.

.cache() menyimpan gambar dalam memori setelah dimuat dari disk selama periode pertama. Ini akan memastikan kumpulan data tidak menjadi hambatan saat melatih model Anda. Jika kumpulan data Anda terlalu besar untuk dimasukkan ke dalam memori, Anda juga dapat menggunakan metode ini untuk membuat cache pada disk yang berkinerja baik.

.prefetch() tumpang tindih dengan .prefetch() data dan eksekusi model saat pelatihan.

Pembaca yang tertarik dapat mempelajari lebih lanjut tentang kedua metode tersebut, serta cara menyimpan data ke dalam cache ke disk di panduan kinerja data .

AUTOTUNE = tf.data.AUTOTUNE

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

Latih model

Untuk kelengkapannya, kami akan menunjukkan bagaimana melatih model sederhana menggunakan dataset yang baru kami siapkan. Model ini belum disetel dengan cara apa pun - tujuannya adalah untuk menunjukkan kepada Anda mekanisme menggunakan kumpulan data yang baru saja Anda buat. Untuk mempelajari lebih lanjut tentang klasifikasi gambar, kunjungi tutorial ini.

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 [==============================] - 9s 75ms/step - loss: 1.4194 - accuracy: 0.4075 - val_loss: 1.0631 - val_accuracy: 0.5899
Epoch 2/3
92/92 [==============================] - 1s 12ms/step - loss: 1.0337 - accuracy: 0.5607 - val_loss: 0.9730 - val_accuracy: 0.6322
Epoch 3/3
92/92 [==============================] - 1s 12ms/step - loss: 0.8870 - accuracy: 0.6537 - val_loss: 0.9257 - val_accuracy: 0.6485
<tensorflow.python.keras.callbacks.History at 0x7f9c35c6d1d0>

Anda mungkin melihat keakuratan validasi rendah dibandingkan dengan keakuratan pelatihan, yang menunjukkan model kita overfitting. Anda dapat mempelajari lebih lanjut tentang overfitting dan cara menguranginya dalam tutorial ini.

Menggunakan tf.data untuk kontrol yang lebih baik

Utilitas keras.preprocessing di atas adalah cara mudah untuk membuattf.data.Dataset dari direktori gambar. Untuk kontrol grain yang lebih baik, Anda dapat menulis pipeline input Anda sendiri menggunakan tf.data . Bagian ini menunjukkan bagaimana melakukan hal itu, dimulai dengan jalur file dari zip yang kita unduh sebelumnya.

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/dandelion/10779476016_9130714dc0.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/daisy/144076848_57e1d662e3_m.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/tulips/13513616525_2ee0f049e1.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/tulips/574373182_2776669a79_n.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/daisy/515112668_a49c69455a.jpg'

Struktur pohon file dapat digunakan untuk mengompilasi daftar 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']

Pisahkan kumpulan data menjadi train dan validasi:

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

Anda dapat melihat panjang setiap dataset sebagai berikut:

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

Tulis fungsi singkat yang mengubah jalur file menjadi pasangan (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

Gunakan Dataset.map untuk membuat kumpulan data image, label pasangan 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

Konfigurasi set data untuk kinerja

Untuk melatih model dengan set data ini, Anda memerlukan data:

  • Untuk dikocok dengan baik.
  • Untuk dikumpulkan.
  • Batch akan tersedia secepat mungkin.

Fitur-fitur ini dapat ditambahkan menggunakan API tf.data . Untuk detail selengkapnya, lihat panduan Performa Pipa Masukan .

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)

Visualisasikan datanya

Anda dapat memvisualisasikan kumpulan data ini serupa dengan yang Anda buat sebelumnya.

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

Lanjutkan melatih model

Anda sekarang telah membuattf.data.Dataset serupa secara manual dengan yang dibuat oleh keras.preprocessing atas. Anda dapat terus melatih model dengannya. Seperti sebelumnya, kami akan berlatih hanya dalam beberapa periode agar waktu berjalan tetap singkat.

model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=3
)
Epoch 1/3
92/92 [==============================] - 3s 22ms/step - loss: 0.8030 - accuracy: 0.6918 - val_loss: 0.7237 - val_accuracy: 0.7044
Epoch 2/3
92/92 [==============================] - 1s 13ms/step - loss: 0.6538 - accuracy: 0.7531 - val_loss: 0.7045 - val_accuracy: 0.7248
Epoch 3/3
92/92 [==============================] - 1s 13ms/step - loss: 0.5219 - accuracy: 0.8113 - val_loss: 0.7486 - val_accuracy: 0.6921
<tensorflow.python.keras.callbacks.History at 0x7f9ccdc286a0>

Menggunakan Set Data TensorFlow

Sejauh ini, tutorial ini difokuskan pada pemuatan data dari disk. Anda juga dapat menemukan kumpulan data untuk digunakan dengan menjelajahi katalog besar kumpulan data yang mudah didownload di Set Data TensorFlow . Karena Anda sebelumnya telah memuat kumpulan data Flowers dari disk, mari kita lihat cara mengimpornya dengan Kumpulan Data TensorFlow.

Unduh kumpulan data bunga menggunakan Set Data TensorFlow.

(train_ds, val_ds, test_ds), metadata = tfds.load(
    'tf_flowers',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

Dataset bunga memiliki lima kelas.

num_classes = metadata.features['label'].num_classes
print(num_classes)
5

Ambil gambar dari kumpulan data.

get_label_name = metadata.features['label'].int2str

image, label = next(iter(train_ds))
_ = plt.imshow(image)
_ = plt.title(get_label_name(label))

png

Seperti sebelumnya, ingatlah untuk menumpuk, mengacak, dan mengonfigurasi setiap set data untuk performa.

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

Anda dapat menemukan contoh lengkap cara bekerja dengan kumpulan data bunga dan Set Data TensorFlow dengan mengunjungi tutorial augmentasi data .

Langkah selanjutnya

Tutorial ini menunjukkan dua cara memuat gambar dari disk. Pertama, Anda telah mempelajari cara memuat dan melakukan praproses pada dataset gambar menggunakan lapisan dan utilitas preprocessing Keras. Selanjutnya, Anda mempelajari cara menulis pipeline input dari awal menggunakan tf.data. Terakhir, Anda telah mempelajari cara mendownload set data dari TensorFlow Dataset. Sebagai langkah selanjutnya, Anda dapat mempelajari cara menambahkan augmentasi data dengan mengunjungi tutorial ini. Untuk mempelajari lebih lanjut tentang tf.data, Anda dapat mengunjungi panduan ini.