דף זה תורגם על ידי 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.processing

בואו נטען תמונות אלה מהדיסק באמצעות 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) . זהו אצווה של 32 תמונות בעלות צורה 180x180x3 (הממד האחרון 180x180x3 לערוצי צבע RGB). label_batch היא טנזור של הצורה (32,) , אלה תוויות תואמות ל 32 התמונות.

תקנן את הנתונים

ערכי ערוץ RGB נמצאים בטווח [0, 255] . זה לא אידיאלי עבור רשת עצבית; באופן כללי עליך לנסות להפוך את ערכי הקלט שלך קטנים. כאן, נקבע ערכים להיות ב- [0, 1] ידי שימוש בשכבת שינוי גודל.

 from tensorflow.keras import layers

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

ישנן שתי דרכים להשתמש בשכבה זו. אתה יכול להחיל אותו על מערך הנתונים על ידי מפת שיחות:

 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() שומר את התמונות בזיכרון לאחר שהן נטענות מהדיסק במהלך התקופה הראשונה. זה יבטיח כי מערך הנתונים לא יהפוך לצוואר בקבוק בזמן אימון המודל שלך. אם מערך הנתונים שלך גדול מכדי שייכנס לזיכרון, באפשרותך גם להשתמש בשיטה זו כדי ליצור מטמון בדיסק.

.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>

יתכן שתבחין בכך שדיוק האימות הוא נמוך בהשוואה לדיוק האימונים, מה שמעיד שהמודל שלנו מתאים מדי. אתה יכול ללמוד עוד על overfitting וכיצד להפחית אותו זה הדרכה .

באמצעות tf.data לבקרה עדינה יותר

כלי העזר לעיבוד keras. לעיל הם דרך נוחה ליצור tf.data.Dataset מתוך ספריית תמונות. לבקרת תבואה עדינה יותר, אתה יכול לכתוב צינור קלט משלך באמצעות 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 .

 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 של 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

הגדר מערך נתונים לביצועים

כדי לאמן דגם עם מערך נתונים זה תרצו את הנתונים:

  • להיות דשדוש היטב.
  • להיות אצווה.
  • קבוצות יהיו זמינות בהקדם האפשרי.

ניתן להוסיף תכונות אלה באמצעות ממשק ה- API tf.data . לפרטים נוספים, עיין במדריך ביצועי צינור הקלט .

 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

המשך לאמן את הדגם

בניתם ידנית tf.data.Dataset באופן ידני לזה שנוצר על ידי ה- keras.preprocessing לעיל. אתה יכול להמשיך לאמן את הדגם איתו. כמו קודם, נתאמן למספר תקופות ספורות בכדי להקצר את זמן הריצה.

 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 תוכלו לבקר במדריך זה.